summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--CONTRIBUTING.markdown25
-rw-r--r--ansible.html.markdown470
-rw-r--r--ar-ar/python3-ar.html.markdown1019
-rw-r--r--asymptotic-notation.html.markdown2
-rw-r--r--awk.html.markdown11
-rw-r--r--bash.html.markdown80
-rw-r--r--bc.html.markdown98
-rw-r--r--c++.html.markdown263
-rw-r--r--chapel.html.markdown2
-rw-r--r--cmake.html.markdown3
-rw-r--r--crystal.html.markdown24
-rw-r--r--cs-cz/python3.html.markdown2
-rw-r--r--csharp.html.markdown2
-rw-r--r--cypher.html.markdown2
-rw-r--r--dart.html.markdown112
-rw-r--r--de-de/asciidoc-de.html.markdown6
-rw-r--r--de-de/c++-de.html.markdown1157
-rw-r--r--de-de/git-de.html.markdown2
-rw-r--r--de-de/hq9+-de.html.markdown2
-rw-r--r--de-de/make-de.html.markdown3
-rw-r--r--de-de/markdown-de.html.markdown2
-rw-r--r--de-de/opencv-de.html.markdown2
-rw-r--r--de-de/paren-de.html.markdown2
-rw-r--r--de-de/python-de.html.markdown359
-rw-r--r--de-de/python3-de.html.markdown4
-rw-r--r--de-de/rst-de.html.markdown2
-rw-r--r--de-de/shutit-de.html.markdown2
-rw-r--r--de-de/yaml-de.html.markdown4
-rw-r--r--dhall.html.markdown362
-rw-r--r--dynamic-programming.html.markdown2
-rw-r--r--el-gr/bash-gr.html.markdown528
-rw-r--r--el-gr/html-gr.html.markdown193
-rw-r--r--el-gr/json-gr.html.markdown60
-rw-r--r--elisp.html.markdown6
-rw-r--r--elixir.html.markdown2
-rw-r--r--emacs.html.markdown320
-rw-r--r--es-es/awk-es.html.markdown3
-rw-r--r--es-es/common-lisp-es.html.markdown692
-rw-r--r--es-es/dart-es.html.markdown529
-rw-r--r--es-es/kotlin-es.html.markdown68
-rw-r--r--es-es/python-es.html.markdown2
-rw-r--r--es-es/pythonstatcomp-es.html.markdown3
-rw-r--r--es-es/scala-es.html.markdown741
-rw-r--r--es-es/visualbasic-es.html.markdown2
-rw-r--r--fr-fr/awk-fr.html.markdown377
-rw-r--r--fr-fr/erlang-fr.html.markdown4
-rw-r--r--fr-fr/make-fr.html.markdown3
-rw-r--r--fr-fr/markdown-fr.html.markdown2
-rw-r--r--fr-fr/python-fr.html.markdown2
-rw-r--r--fsharp.html.markdown2
-rw-r--r--haxe.html.markdown407
-rw-r--r--html.html.markdown3
-rw-r--r--hu-hu/python-hu.html.markdown2
-rw-r--r--it-it/javascript-it.html.markdown617
-rw-r--r--it-it/logtalk-it.html.markdown5
-rw-r--r--it-it/pyqt-it.html.markdown2
-rw-r--r--it-it/python-it.html.markdown2
-rw-r--r--it-it/qt-it.html.markdown2
-rw-r--r--it-it/rust-it.html.markdown4
-rw-r--r--ja-jp/asciidoc.html.markdown135
-rw-r--r--ja-jp/python3-jp.html.markdown240
-rw-r--r--javascript.html.markdown1
-rw-r--r--json.html.markdown2
-rw-r--r--julia.html.markdown24
-rw-r--r--ko-kr/python-kr.html.markdown2
-rw-r--r--kotlin.html.markdown130
-rw-r--r--lambda-calculus.html.markdown9
-rw-r--r--latex.html.markdown2
-rw-r--r--linker.html.markdown9
-rw-r--r--logtalk.html.markdown7
-rw-r--r--lua.html.markdown169
-rw-r--r--m.html.markdown370
-rw-r--r--make.html.markdown3
-rw-r--r--mercurial.html.markdown4
-rw-r--r--ocaml.html.markdown2
-rw-r--r--opengl.html.markdown765
-rw-r--r--p5.html.markdown53
-rw-r--r--pascal.html.markdown2
-rw-r--r--perl.html.markdown2
-rw-r--r--perl6-pod.html.markdown622
-rw-r--r--perl6.html.markdown2070
-rw-r--r--pl-pl/java-pl.html.markdown1026
-rw-r--r--pl-pl/python-pl.html.markdown2
-rw-r--r--powershell.html.markdown3
-rw-r--r--processing.html.markdown216
-rw-r--r--prolog.html.markdown2
-rw-r--r--protocol-buffer-3.html.markdown247
-rw-r--r--pt-br/asymptotic-notation-pt.html.markdown24
-rw-r--r--pt-br/awk-pt.html.markdown3
-rw-r--r--pt-br/clojure-pt.html.markdown2
-rw-r--r--pt-br/cmake-pt.html.markdown5
-rw-r--r--pt-br/coffeescript-pt.html.markdown46
-rw-r--r--pt-br/cypher-pt.html.markdown2
-rw-r--r--pt-br/factor-pt.html.markdown2
-rw-r--r--pt-br/html-pt.html.markdown2
-rw-r--r--pt-br/less-pt.html.markdown2
-rw-r--r--pt-br/make-pt.html.markdown3
-rw-r--r--pt-br/pascal-pt.html.markdown253
-rw-r--r--pt-br/python-pt.html.markdown2
-rw-r--r--pt-br/python3-pt.html.markdown2
-rwxr-xr-xpt-br/stylus-pt.html.markdown228
-rw-r--r--pug.html.markdown204
-rw-r--r--python.html.markdown5
-rw-r--r--python3.html.markdown57
-rw-r--r--r.html.markdown2
-rw-r--r--racket.html.markdown18
-rw-r--r--reason.html.markdown544
-rw-r--r--red.html.markdown10
-rw-r--r--ro-ro/python-ro.html.markdown2
-rw-r--r--rst.html.markdown16
-rw-r--r--ru-ru/asymptotic-notation-ru.html.markdown450
-rw-r--r--ru-ru/bash-ru.html.markdown346
-rw-r--r--ru-ru/learnvisualbasic-ru.html.markdown284
-rw-r--r--ru-ru/linker-ru.html.markdown203
-rw-r--r--ru-ru/php-composer-ru.html.markdown197
-rw-r--r--ru-ru/python-ru.html.markdown2
-rw-r--r--ru-ru/yaml-ru.html.markdown189
-rw-r--r--scala.html.markdown2
-rw-r--r--sl-si/asciidoc-sl.html.markdown136
-rw-r--r--smalltalk.html.markdown1141
-rw-r--r--solidity.html.markdown16
-rw-r--r--standard-ml.html.markdown3
-rw-r--r--stylus.html.markdown228
-rw-r--r--swift.html.markdown991
-rw-r--r--tcsh.html.markdown3
-rw-r--r--th-th/pascal.th.html.markdown55
-rw-r--r--tmux.html.markdown2
-rwxr-xr-xtoml.html.markdown14
-rw-r--r--tr-tr/clojure-tr.html.markdown490
-rw-r--r--tr-tr/html-tr.html.markdown157
-rw-r--r--tr-tr/python-tr.html.markdown2
-rw-r--r--typescript.html.markdown41
-rw-r--r--uk-ua/python-ua.html.markdown2
-rw-r--r--vim.html.markdown14
-rw-r--r--visualbasic.html.markdown2
-rw-r--r--vyper.html.markdown872
-rw-r--r--wasm.html.markdown227
-rw-r--r--wolfram.html.markdown4
-rw-r--r--yaml.html.markdown4
-rw-r--r--zfs.html.markdown11
-rw-r--r--zh-cn/awk-cn.html.markdown3
-rw-r--r--zh-cn/dart-cn.html.markdown44
-rw-r--r--zh-cn/git-cn.html.markdown2
-rw-r--r--zh-cn/lambda-calculus-cn.html.markdown223
-rw-r--r--zh-cn/make-cn.html.markdown13
-rw-r--r--zh-cn/markdown-cn.html.markdown58
-rw-r--r--zh-cn/python-cn.html.markdown2
-rw-r--r--zh-cn/ruby-cn.html.markdown160
-rw-r--r--zh-cn/solidity-cn.html.markdown825
-rw-r--r--zh-cn/sql.html.markdown105
-rw-r--r--zh-tw/python-tw.html.markdown2
151 files changed, 20262 insertions, 3425 deletions
diff --git a/CONTRIBUTING.markdown b/CONTRIBUTING.markdown
index 455c3256..18a5a5d7 100644
--- a/CONTRIBUTING.markdown
+++ b/CONTRIBUTING.markdown
@@ -52,6 +52,8 @@ languages:
Other fields:
+- **category**: The category of the article. So far, can be one of *language*,
+ *tool* or *Algorithms & Data Structures*. Defaults to *language* if omitted.
- **filename**: The filename for this article's code. It will be fetched, mashed
together, and made downloadable.
+ For non-English articles, *filename* should have a language-specific
@@ -78,3 +80,26 @@ If you want to add yourself to contributors, keep in mind that contributors get
equal billing, and the first contributor usually wrote the whole article. Please
use your judgement when deciding if your contribution constitutes a substantial
addition or not.
+
+## Building the site locally
+
+You can buid the site locally to test your changes. Follow the steps below.
+
+* Install Ruby language runtime and RubyGems. See [here](https://middlemanapp.com/basics/install/) for more details.
+* Clone or zip download the [learnxinyminutes-site](https://github.com/adambard/learnxinyminutes-site) repo.
+ * `git clone https://github.com/adambard/learnxinyminutes-site`
+* Install Middleman and other required dependencies using Bundler.
+ * `cd learnxinyminutes-site/`
+ * `bundle install`
+* Get the source in place
+ * Copy the contents of your clone of the fork of learnxinyminutes-docs repo
+ into the `source/docs` folder. There shouldn't be a `learnxinyminutes-docs`
+ folder inside the `docs` folder, it should just contain all the repo
+ contents.
+ * Checkout your fork of the learnxinyminutes-docs repo as `source/docs`.
+ * `cd source/docs/`
+ * `git clone https://github.com/YOUR-USERNAME/learnxinyminutes-docs ./source/docs/`
+* Build the site or run a development server to test your changes (NOTE: run
+these commands at `learnxinyminutes-site/`).
+ * Build - `bundle exec middleman build`
+ * Dev server - `bundle exec middleman --force-polling --verbose`
diff --git a/ansible.html.markdown b/ansible.html.markdown
index cb365e0f..41a8c9b5 100644
--- a/ansible.html.markdown
+++ b/ansible.html.markdown
@@ -3,17 +3,74 @@ category: tool
tool: ansible
contributors:
- ["Jakub Muszynski" , "http://github.com/sirkubax"]
+ - ["Pat Myron" , "https://github.com/patmyron"]
+ - ["Divay Prakash", "https://github.com/divayprakash"]
filename: LearnAnsible.txt
---
+## Introduction
+
```yaml
---
"{{ Ansible }}" is an orchestration tool written in Python.
-
+...
```
+Ansible is (one of many) orchestration tools. It allows you to control your
+environment (infrastructure and code) and automate the manual tasks.
+
+Ansible has great integration with multiple operating systems (even Windows)
+and some hardware (switches, Firewalls, etc). It has multiple tools that
+integrate with the cloud providers. Almost every noteworthy cloud provider is
+present in the ecosystem (AWS, Azure, Google, DigitalOcean, OVH, etc...).
+
+But ansible is way more! It provides execution plans, an API, library, and callbacks.
+
+### Main pros and cons
+
+#### Pros
+
+* It is an agent-less tools In most scenarios, it use ssh as a transport layer.
+In some way you can use it as 'bash on steroids'.
+* It is very easy to start. If you are familiar with ssh concept - you already
+know Ansible (ALMOST).
+* It executes 'as is' - other tools (salt, puppet, chef - might execute in
+different scenario than you would expect)
+* Documentation is at the world-class standard!
+* Writing your own modules and extensions is fairly easy.
+* Ansible AWX is the open source version of Ansible Tower we have been waiting
+for, which provides an excellent UI.
+
+#### Cons
+
+* It is an agent-less tool - every agent consumes up to 16MB ram - in some
+environments, it may be noticable amount.
+* It is agent-less - you have to verify your environment consistency
+'on-demand' - there is no built-in mechanism that would warn you about some
+change automatically (this can be achieved with reasonable effort)
+* Official GUI - Ansible Tower - is great but expensive.
+* There is no 'small enterprise' payment plan, however Ansible AWX is the free
+open source version we were all waiting for.
+
+#### Neutral
+
+Migration - Ansible <-> Salt is fairly easy - so if you would need an
+event-driven agent environment - it would be a good choice to start quick with
+Ansible, and convert to Salt when needed.
+
+#### Some concepts
+
+Ansible uses ssh or paramiko as a transport layer. In a way you can imagine
+that you are using a ssh with API to perform your action. The simplest way is
+to execute remote command in more controlled way (still using ssh).
+On the other hand - in advanced scope - you can wrap Ansible (use python Ansible
+code as a library) with your own Python scripts! It would act a
+bit like Fabric then.
+
## Example
+
An example playbook to install apache and configure log level
+
```yaml
---
- hosts: apache
@@ -23,39 +80,39 @@ An example playbook to install apache and configure log level
handlers:
- name: restart apache
- service:
+ service:
name: apache2
state: restarted
enabled: True
- notify:
+ notify:
- Wait for instances to listen on port 80
become: True
- name: reload apache
- service:
+ service:
name: apache2
state: reloaded
- notify:
+ notify:
- Wait for instances to listen on port 80
become: True
- name: Wait for instances to listen on port 80
- wait_for:
- state: started
- host: localhost
- port: 80
- timeout: 15
+ wait_for:
+ state: started
+ host: localhost
+ port: 80
+ timeout: 15
delay: 5
tasks:
- - name: Update cache
- apt:
- update_cache: yes
+ - name: Update cache
+ apt:
+ update_cache: yes
cache_valid_time: 7200
become: True
- name: Install packages
- apt:
+ apt:
name={{ item }}
with_items:
- apache2
@@ -65,127 +122,136 @@ An example playbook to install apache and configure log level
become: True
- name: Configure apache2 log level
- lineinfile:
+ lineinfile:
dest: /etc/apache2/apache2.conf
line: "LogLevel {{ apache2_log_level }}"
regexp: "^LogLevel"
notify:
- reload apache
become: True
-
+...
```
## Installation
+
```bash
# Universal way
$ pip install ansible
# Debian, Ubuntu
$ apt-get install ansible
-
```
+
* [Appendix A - How do I install ansible](#infrastructure-as-a-code)
* [Additional Reading.](http://docs.ansible.com/ansible/latest/intro_installation.html)
### Your first ansible command (shell execution)
+
```bash
-# This command ping the localhost (defined in default inventory: /etc/ansible/hosts)
+# Command pings localhost (defined in default inventory: /etc/ansible/hosts)
$ ansible -m ping localhost
-# you should see this output
+# You should see this output
localhost | SUCCESS => {
- "changed": false,
+ "changed": false,
"ping": "pong"
}
-
```
+
### Shell Commands
+
There are few commands you should know about
* `ansible` (to run modules in CLI)
* `ansible-playbook` (to run playbooks)
* `ansible-vault` (to manage secrets)
* `ansible-galaxy` (to install roles from github/galaxy)
-* and other!
### Module
-_program (usally python) that execute, do some work and return proper JSON output_
-This *program* perform specialized task/action (like manage instances in the cloud, execute shell command).
-
-The simplest module is called `ping` - it just returns a JSON with `pong` message.
+A program (usually python) that executes, does some work and returns proper
+JSON output. This program performs specialized task/action (like manage
+instances in the cloud, execute shell command). The simplest module is called
+`ping` - it just returns a JSON with `pong` message.
Example of modules:
-* Module: `ping` - the simplest module that is usefull to verify host connectivity
+
+* Module: `ping` - the simplest module that is useful to verify host connectivity
* Module: `shell` - a module that executes shell command on a specified host(s).
-Example of execution - `ping`, `shell`
```bash
$ ansible -m ping all
$ ansible -m shell -a 'date; whoami' localhost #hostname_or_a_group_name
```
-* Module: `command` - executes a single command that will not be processed through the shell, so variables like $HOME or operands like `|` `;` will not work. The command module is more secure, because it will not be affected by the user’s environment. For more complex command - use shell module.
-
+* Module: `command` - executes a single command that will not be processed
+through the shell, so variables like `$HOME` or operands like ``|` `;`` will not
+work. The command module is more secure, because it will not be affected by the
+user’s environment. For more complex commands - use shell module.
```bash
$ ansible -m command -a 'date; whoami' # FAILURE
-
$ ansible -m command -a 'date' all
$ ansible -m command -a 'whoami' all
```
-* Module: `file` - performs file operations (stat, link, dir, ...)
-* Module: `raw` - executes a low-down and dirty SSH command, not going through the module subsystem (usefull to install python2.7)
+* Module: `file` - performs file operations (stat, link, dir, ...)
+* Module: `raw` - executes a low-down and dirty SSH command, not going through
+the module subsystem (useful to install python2.7)
### Task
- Execution of a single Ansible **module** is called a **task**
- The simplest module is called `ping` as you could see above
-
- Another example of the module that allow you to execute command remotly on multiple resources is called `shell`. See above how you were using them already.
+Execution of a single Ansible **module** is called a **task**. The simplest
+module is called `ping` as you could see above.
+Another example of the module that allow you to execute command remotly on
+multiple resources is called `shell`. See above how you were using them already.
### Playbook
+
**Execution plan** written in a form of script file(s) is called **playbook**.
-Playbook consist of multiple elements
+Playbook consist of multiple elements -
* a list (or group) of hosts that 'the play' is executed against
* `task(s)` or `role(s)` that are going to be executed
* multiple optional settings (like default variables, and way more)
-Playbook script language is YAML.
+Playbook script language is YAML. You can think that playbook is very advanced
+CLI script that you are executing.
-You can think that playbook is very advanced CLI script that you are executing.
+#### Example of the playbook
-
-#### Example of the playbook:
-This example-playbook would execute (on all hosts defined in the inventory) two tasks:
+This example-playbook would execute (on all hosts defined in inventory) two tasks:
* `ping` that would return message *pong*
* `shell` that execute three commands and return the output to our terminal
```yaml
- hosts: all
-
+
tasks:
- name: "ping all"
ping:
-
+
- name: "execute a shell command"
shell: "date; whoami; df -h;"
```
Run the playbook with the command:
+
```bash
$ ansible-playbook path/name_of_the_playbook.yml
```
-_Note: Example playbook is explained in the next chapter: 'Roles'
+
+Note: Example playbook is explained in the next chapter: 'Roles'
+
### More on ansible concept
### Inventory
-Inventory is a set of an objects or hosts, against which we are executing our playbooks or single tasks via shell commands
-For this few minutes, lets asume that we are using default ansible inventory (which in Debian based system is placed in /etc/ansible/hosts)
-`/etc/ansible/hosts`
+Inventory is a set of objects or hosts, against which we are executing our
+playbooks or single tasks via shell commands. For these few minutes, let's
+assume that we are using the default ansible inventory (which in Debian based
+system is placed in `/etc/ansible/hosts`).
+
```
localhost
@@ -197,18 +263,23 @@ hostB.localdomain
[a_group_of_a_groups:children]
some_group
some_other_group
-
```
+
* [Additional Reading.](http://docs.ansible.com/ansible/latest/intro_inventory.html)
+
### ansible-roles (a 'template-playbooks' with right structure)
- You already know that the tasks (modules) can be run via CLI. You also know the playbooks - the execution plans of multiple tasks (with variables and logic).
+You already know that the tasks (modules) can be run via CLI. You also know the
+playbooks - the execution plans of multiple tasks (with variables and logic).
-A concept called `role` was introduced for parts of the code (playbooks) that should be reusable.
+A concept called `role` was introduced for parts of the code (playbooks) that
+should be reusable.
-**Role** is a structured way to manage your set of tasks, variables, handlers, default settings, and way more (meta, files, templates).
-Role allows to reuse the same parts of code in multiple plybooks (you can parametrize the role 'further' during it's execution).
-It is a great way to introduce `object oriented` management for your applications.
+**Role** is a structured way to manage your set of tasks, variables, handlers,
+default settings, and way more (meta, files, templates). Roles allow reusing
+the same parts of code in multiple playbooks (you can parametrize the role
+'further' during its execution). Its a great way to introduce `object oriented`
+management for your applications.
Role can be included in your playbook (executed via your playbook).
@@ -221,40 +292,43 @@ Role can be included in your playbook (executed via your playbook).
ping:
- name: "execute a shell command"
shell: "date; whoami; df -h;"
-
- roles:
+
+ roles:
- some_role
- { role: another_role, some_variable: 'learnxiny', tags: ['my_tag'] }
-
+
pre_tasks:
- name: some pre-task
shell: echo 'this task is the last, but would be executed before roles, and before tasks'
```
#### For remaining examples we would use additional repository
-This example install ansible in `virtualenv` so it is independend from a system. You need to initialize it into your shell-context with `source environment.sh` command.
+This example install ansible in `virtualenv` so it is independend from a system.
+You need to initialize it into your shell-context with `source environment.sh`
+command.
-We are going to use repository with examples: https://github.com/sirkubax/ansible-for-learnXinYminutes
+We are going to use this repository with examples: [https://github.com/sirkubax/ansible-for-learnXinYminutes]()
```bash
-$ # The folowing example contains a shell-prompt to indicate the venv and relative path
+$ # The following example contains a shell-prompt to indicate the venv and relative path
$ git clone git@github.com:sirkubax/ansible-for-learnXinYminutes.git
user@host:~/$ cd ansible-for-learnXinYminutes
user@host:~/ansible-for-learnXinYminutes$ source environment.sh
$
$ # First lets execute the simple_playbook.yml
(venv) user@host:~/ansible-for-learnXinYminutes$ ansible-playbook playbooks/simple_playbook.yml
-
```
Run the playbook with roles example
+
```bash
$ source environment.sh
$ # Now we would run the above playbook with roles
(venv) user@host:~/ansible-for-learnXinYminutes$ ansible-playbook playbooks/simple_role.yml
```
-#### Role directory structure:
+#### Role directory structure
+
```
roles/
some_role/
@@ -268,10 +342,13 @@ roles/
```
#### Role Handlers
-Handlers are a tasks that can be triggered (notified) during execution of a playbook, but they itself execute at the very end of a playbook.
-It is a best way to restart a service, check if application port is active (successfull deployment criteria), etc.
+Handlers are tasks that can be triggered (notified) during execution of a
+playbook, but they execute at the very end of a playbook. It is the best way to
+restart a service, check if the application port is active (successful
+deployment criteria), etc.
+
+Get familiar with how you can use roles in the simple_apache_role example
-Please get familiar how you can use role in simple_apache_role example
```
playbooks/roles/simple_apache_role/
├── tasks
@@ -282,18 +359,14 @@ playbooks/roles/simple_apache_role/
### ansible - variables
-Ansible is flexible - it has 21 levels of variable precedence
-
+Ansible is flexible - it has 21 levels of variable precedence.
[read more](http://docs.ansible.com/ansible/latest/playbooks_variables.html#variable-precedence-where-should-i-put-a-variable)
-
For now you should know that CLI variables have the top priority.
-
You should also know, that a nice way to pool some data is a **lookup**
### Lookups
-Awesome tool to query data from various sources!!! Awesome!
+Awesome tool to query data from various sources!!! Awesome!
query from:
-
* pipe (load shell command output into variable!)
* file
* stream
@@ -308,6 +381,7 @@ query from:
```
You can use them in CLI too
+
```yaml
ansible -m shell -a 'echo "{{ my_variable }}"' -e 'my_variable="{{ lookup("pipe", "date") }}"' localhost
ansible -m shell -a 'echo "{{ my_variable }}"' -e 'my_variable="{{ lookup("pipe", "hostname") }}"' all
@@ -315,15 +389,16 @@ ansible -m shell -a 'echo "{{ my_variable }}"' -e 'my_variable="{{ lookup("pipe"
# Or use in playbook
(venv) user@host:~/ansible-for-learnXinYminutes$ ansible-playbook playbooks/lookup.yml
-
```
-### Register and Conditional
+### Register and Conditional
#### Register
-Another way to dynamicaly generate the variable content is a `register` command.
-`Register` is also useful to store an output of a task, and use it's value as a logic
-for execution further tasks.
+
+Another way to dynamically generate the variable content is the `register` command.
+`Register` is also useful to store an output of a task and use its value
+for executing further tasks.
+
```
(venv) user@host:~/ansible-for-learnXinYminutes$ ansible-playbook playbooks/register_and_when.yml
```
@@ -339,22 +414,25 @@ for execution further tasks.
- name: debug root_size
debug:
msg: "{{ root_size }}"
-
+
- name: debug root_size return code
debug:
msg: "{{ root_size.rc }}"
-# when: example
+# when: example
- name: Print this message when return code of 'check the system capacity' was ok
debug:
msg: "{{ root_size.rc }}"
when: root_size.rc == 0
-
+...
```
+
#### Conditionals - when:
-You can define complex logic with Ansible and Jinja functions. Most common is usage of `when:`, with some variable (often dynamicly generated in previous playbook steps with `register` or `lookup`)
+You can define complex logic with Ansible and Jinja functions. Most common is
+usage of `when:`, with some variable (often dynamically generated in previous
+playbook steps with `register` or `lookup`)
```yaml
---
@@ -365,53 +443,63 @@ You can define complex logic with Ansible and Jinja functions. Most common is us
when: some_variable in 'a string'
roles:
- { role: mid_nagios_probe, when: allow_nagios_probes }
+...
```
-
### ansible - tags, limit
You should know about a way to increase efficiency by this simple functionality
#### TAGS
-You can tag a task, role (and its tasks), include, etc, and then run only the tagged resources
- ansible-playbook playbooks/simple_playbook.yml --tags=tagA,tag_other
- ansible-playbook playbooks/simple_playbook.yml -t tagA,tag_other
+You can tag a task, role (and its tasks), include, etc, and then run only the
+tagged resources
- There are special tags:
- always
-
- --skip-tags can be used to exclude a block of code
- --list-tags to list available tags
+```
+ansible-playbook playbooks/simple_playbook.yml --tags=tagA,tag_other
+ansible-playbook playbooks/simple_playbook.yml -t tagA,tag_other
+
+There are special tags:
+ always
+
+--skip-tags can be used to exclude a block of code
+--list-tags to list available tags
+```
[Read more](http://docs.ansible.com/ansible/latest/playbooks_tags.html)
#### LIMIT
-You can limit an execution of your tasks to defined hosts
- ansible-playbook playbooks/simple_playbook.yml --limmit localhost
+You can limit an execution of your tasks to defined hosts
- --limit my_hostname
- --limit groupname
- --limit some_prefix*
- --limit hostname:group #JM
+```
+ansible-playbook playbooks/simple_playbook.yml --limit localhost
+
+--limit my_hostname
+--limit groupname
+--limit some_prefix*
+--limit hostname:group #JM
+```
### Templates
-Template is a powerfull way to deliver some (partially) dynamic content. Ansible uses **Jinja2** langueage to describe the template.
+Templates are a powerful way to deliver some (partially) dynamic content.
+Ansible uses **Jinja2** language to describe the template.
-```jinja2
+```
Some static content
{{ a_variable }}
-{% for item in loop_items %}
+{% for item in loop_items %}
this line item is {{ item }}
{% endfor %}
```
-Jinja may have some limitations, but it is a powerfull tool that you might like.
-Please examine this simple example that install apache2 and generate index.html from the template
+Jinja may have some limitations, but it is a powerful tool that you might like.
+
+Please examine this simple example that installs apache2 and generates
+index.html from the template
"playbooks/roles/simple_apache_role/templates/index.html"
```bash
@@ -420,15 +508,18 @@ $ # Now we would run the above playbook with roles
(venv) user@host:~/ansible-for-learnXinYminutes$ ansible-playbook playbooks/simple_role.yml --tags apache2
```
-
#### Jinja2 CLI
+
You can use the jinja in the CLI too
+
```bash
ansible -m shell -a 'echo {{ my_variable }}` -e 'my_variable=something, playbook_parameter=twentytwo" localhost
```
+
In fact - jinja is used to template parts of the playbooks too
+
```yaml
-#check part of this playbook: playbooks/roles/sys_debug/tasks/debug_time.yml
+# check part of this playbook: playbooks/roles/sys_debug/tasks/debug_time.yml
- local_action: shell date +'%F %T'
register: ts
become: False
@@ -438,24 +529,29 @@ In fact - jinja is used to template parts of the playbooks too
debug: msg="{{ ts.stdout }}"
when: ts is defined and ts.stdout is defined
become: False
-
```
#### Jinja2 filters
-Junja is powerfull. It has built-in many usefull functions.
-```jinja
+
+Jinja is powerful. It has many built-in useful functions.
+
+```
# get first item of the list
{{ some_list | first() }}
# if variable is undefined - use default value
{{ some_variable | default('default_value') }}
```
+
[Read More](http://docs.ansible.com/ansible/latest/playbooks_filters.html)
### ansible-vault
-To maintain **ifrastructure as a code** you need to store secrets.
- Ansible provides a way to encrypt the confidential files so you can store it in the repository, yet the files are decrypted in-fly during ansible execution.
-The best way to use the **ansible-vault** is to store the secret in some secure location, and configure ansible to use during runtime.
+To maintain **infrastructure as code** you need to store secrets. Ansible
+provides a way to encrypt confidential files so you can store them in the
+repository, yet the files are decrypted on-the-fly during ansible execution.
+
+The best way to use it is to store the secret in some secure location, and
+configure ansible to use during runtime.
```bash
# Try (this would fail)
@@ -486,36 +582,41 @@ $ ansible-vault decrypt path/somefile
```
### dynamic inventory
-You might like to know, that you can build your inventory dynamically.
-(For Ansible) inventory is just a JSON with proper structure - if you can deliver that to ansible - anything is possible.
+You might like to know, that you can build your inventory dynamically.
+(For Ansible) inventory is just JSON with proper structure - if you can
+deliver that to ansible - anything is possible.
-You do not need to invent the wheel - there are plenty ready to use inventory script for most popular Cloud provicers and a lot of in-house popular usecaseses.
+You do not need to reinvent the wheel - there are plenty of ready to use
+inventory scripts for most popular Cloud providers and a lot of in-house
+popular usecases.
[AWS example](http://docs.ansible.com/ansible/latest/intro_dynamic_inventory.html#example-aws-ec2-external-inventory-script)
```bash
-$ etc/inv/ec2.py --refresh
-
+$ etc/inv/ec2.py --refresh
$ ansible -m ping all -i etc/inv/ec2.py
```
[Read more](http://docs.ansible.com/ansible/latest/intro_dynamic_inventory.html)
### ansible profiling - callback
-Playbook execution takes some time. It is OK. First make it run, then you may like to speed things up
-Since ansible 2.x there is built-in callback for task execution profiling
+Playbook execution takes some time. It is OK. First make it run, then you may
+like to speed things up. Since ansible 2.x there is built-in callback for task
+execution profiling.
```
-vi ansible.cfg
-#set this to:
+vi ansible.cfg
+# set this to:
callback_whitelist = profile_tasks
```
### facts-cache and ansible-cmdb
-You can pool some infrmations of you environment from another hosts.
-If the informations does not change - you may consider using a facts_cache to speed things up.
+
+You can pull some information about your environment from another hosts.
+If the information does not change - you may consider using a facts_cache
+to speed things up.
```
vi ansible.cfg
@@ -531,41 +632,55 @@ fact_caching_timeout = 86400
```
I like to use `jsonfile` as my backend. It allows to use another project
-`ansible-cmdb` [(project on github)](https://github.com/fboender/ansible-cmdb) that generates a HTML page of your inventory resources. A nice 'free' addition!
+`ansible-cmdb` [(project on github)](https://github.com/fboender/ansible-cmdb) that generates a HTML page of your inventory
+resources. A nice 'free' addition!
+
+### Debugging ansible [chapter in progress]
-### debugging ansible [chapter in progres]
When your job fails - it is good to be effective with debugging.
-1. Increase verbosiy by using multiple -v **[ -vvvvv]**
-2. If variable is undefined
- - grep -R path_of_your_inventory -e missing_variable
-3. If variable (dictionary or a list) is undefined
- - grep -R path_of_your_inventory -e missing_variable
-4. Jinja template debug
+1. Increase verbosity by using multiple -v **[ -vvvvv]**
+2. If variable is undefined -
+`grep -R path_of_your_inventory -e missing_variable`
+3. If variable (dictionary or a list) is undefined -
+`grep -R path_of_your_inventory -e missing_variable`
+4. Jinja template debug
5. Strange behaviour - try to run the code 'at the destination'
-### Infrastructure as a code
-You already know, that ansible-vault allow you to store your confidential data along with your code (in repository). You can go further - and define your ansible installation and configuration as-a-code.
-See `environment.sh` to learn how to install the ansible itself inside a `virtualenv` that is not attached to your operating system (can be changed by non-privilages user), and as additional benefit - upgrading version of ansible is as easy as installing new version in new virtualenv. What is more, you can have multiple versions of Ansible present in the same time. This is very helpfull!
+### Infrastructure as code
+
+You already know, that ansible-vault allows you to store your confidential data
+along with your code. You can go further - and define your
+ansible installation and configuration as code.
+See `environment.sh` to learn how to install the ansible itself inside a
+`virtualenv` that is not attached to your operating system (can be changed by
+non-privileged user), and as additional benefit - upgrading version of ansible
+is as easy as installing new version in new virtualenv. What is more, you can
+have multiple versions of Ansible present at the same time.
```bash
- # recreate ansible 2.x venv
+# recreate ansible 2.x venv
$ rm -rf venv2
$ source environment2.sh
- # execute playbook
+
+# execute playbook
(venv2)$ ansible-playbook playbooks/ansible1.9_playbook.yml # would fail - deprecated syntax
- # now lets install ansible 1.9.x next to ansible 2.x
+# now lets install ansible 1.9.x next to ansible 2.x
(venv2)$ deactivate
$ source environment.1.9.sh
- # execute playbook
+
+# execute playbook
(venv1.9)$ ansible-playbook playbooks/ansible1.9_playbook.yml # works!
- # please note that you have both venv1.9 and venv2 present - you need to (de)activate one - that is all
+# please note that you have both venv1.9 and venv2 present - you need to (de)activate one - that is all
```
#### become-user, become
-In Ansible - to become `sudo` - use the `become` parameter. Use `become_user` to specify the username.
+
+In Ansible - to become `sudo` - use the `become` parameter. Use `become_user`
+to specify the username.
+
```
- name: Ensure the httpd service is running
service:
@@ -573,97 +688,68 @@ In Ansible - to become `sudo` - use the `become` parameter. Use `become_user` to
state: started
become: true
```
-Note: You may like to execute Ansible with `--ask-sudo-pass` or add the user to sudoers file in order to allow non-supervised execution if you require 'admin' privilages.
+
+Note: You may like to execute Ansible with `--ask-sudo-pass` or add the user to
+sudoers file in order to allow non-supervised execution if you require 'admin'
+privilages.
[Read more](http://docs.ansible.com/ansible/latest/become.html)
## Tips and tricks
#### --check -C
-Always make sure that your playbook can executes in 'dry run' mode (--check), and it's execution is not declaring 'Changed' objects.
+
+Always make sure that your playbook can execute in 'dry run' mode (--check),
+and its execution is not declaring 'Changed' objects.
#### --diff -D
-Diff is usefull to see nice detail of the files changed
-It compare 'in memory' the files like `diff -BbruN fileA fileB`
+Diff is useful to see nice detail of the files changed.
+It compare 'in memory' the files like `diff -BbruN fileA fileB`.
#### Execute hosts with 'regex'
+
```bash
ansible -m ping web*
```
-####
-Host groups can be joined, negated, etc
+#### Host groups can be joined, negated, etc
```bash
ansible -m ping web*:!backend:monitoring:&allow_change
```
#### Tagging
-You should tag some (not all) objects - a task in a playbook, all tasks included form a role, etc.
-It allows you to execute the choosen parts of the playbook.
+
+You should tag some (not all) objects - a task in a playbook, all tasks
+included form a role, etc. It allows you to execute the chosen parts of the
+playbook.
#### no_logs: True
-You may see, that some roles print a lot of output in verbose mode. There is also a debug module.
-This is the place where credentials may leak. Use `no_log` to hide the output.
+
+You may see, that some roles print a lot of output in verbose mode. There is
+also a debug module. This is the place where credentials may leak. Use `no_log`
+to hide the output.
#### Debug module
+
allows to print a value to the screen - use it!
#### Register the output of a task
-You can register the output (stdout), rc (return code), stderr of a task with the `register` command.
-
-#### Conditionals: when:
-
-#### Loop: with, with_items, with_dict, with_together
-
-[Read more](http://docs.ansible.com/ansible/latest/playbooks_conditionals.html)
-
-## Introduction
-Ansible is (one of the many) orchestration tools. It allows you to controll your environment (infrastructure and a code) and automate the manual tasks.
-'You can think as simple as writing in bash with python API
-Of course the rabit hole is way deeper.'
-
-Ansible have great integration with multiple operating systems (even Windows) and some hardware (switches, Firewalls, etc). It has multiple tools that integrate with the could providers. Almost every worth-notice cloud provider is present in the ecosystem (AWS, Azure, Google, DigitalOcean, OVH, etc...)
-
-
-But ansible is way more! It provides an execution plans, an API, library, callbacks, not forget to mention - COMMUNITY! and great support by developers!
+You can register the output (stdout), rc (return code), stderr of a task with
+the `register` command.
+#### Conditionals: when:
-### Main cons and pros
+#### Loop: with, with\_items, with\_dict, with\_together
-#### Cons
-
-It is an agent-less tool - every agent consumes up to 16MB ram - in some environments, it may be noticable amount.
-It is agent-less - you have to verify your environment consistency 'on-demand' - there is no built-in mechanism that would warn you about some change automatically (this can be achieved with reasonable effort)
-Official GUI Tool (web inferface) - Ansible Tower - is great, but it is expensive. There is no 'small enterprice' payment plan, however Ansible AWX is the free open source version we were all waiting for.
-
-#### Pros
-
-It is an agent-less tools In most scenarios, it use ssh as a transport layer.
-In some way you can use it as 'bash on steroids'.
-It is very-very-very easy to start. If you are familiar with ssh concept - you already know Ansible (ALMOST). My personal record is: 'I did show "how to install and use ansible" (for simple raspberry pi cluster management) - it took me 30 seconds to deliver a complete working example !!!)'
-I do provide a training services - I'm able to teach a production-ready person - in 8 hours (1 training day)! It covers all needed to work aspects! No other tool can match this ease of use!
-It executes 'as is' - other tools (salt, puppet, chef - might execute in different scenario than you would expect)
-Documentation is at the world-class standard!
-The comunity (github, stackOverflow) would help you very fast.
-Writing own modules and extension is fairly easy.
-Ansible AWX is the open source version of Ansible Tower we have been waiting for, which provides an excellent UI.
-
-#### Neutral
-Migration Ansible<->Salt is failrly easy - so if you would need an event-driven agent environment - it would be a good choice to start quick with Ansible, and convert to salt when needed.
-
-#### Some concepts
-
-Ansible uses ssh or paramiko as a transport layer. In a way you can imagine that you are using a ssh with API to perform your action.
-The simplest way is to execute remote command in more controlled way (still using ssh).
-On the other hand - in advanced scope - you can wrap Ansible (use python Ansible code as a library) with your own Python scrips! This is awesome! It would act a bit like Fabric then.
+[Read more](http://docs.ansible.com/ansible/latest/playbooks_conditionals.html)
## Additional Resources
* [Servers For Hackers: An Ansible Tutorial](https://serversforhackers.com/c/an-ansible-tutorial)
* [A system administrator's guide to getting started with Ansible - FAST!](https://www.redhat.com/en/blog/system-administrators-guide-getting-started-ansible-fast)
* [Ansible Tower](https://www.ansible.com/products/tower) - Ansible Tower provides a web UI, dashboard and rest interface to ansible.
-* [Ansible AWX](https://github.com/ansible/awx) - The Open Sourc version of Ansible Tower. \ No newline at end of file
+* [Ansible AWX](https://github.com/ansible/awx) - The Open Source version of Ansible Tower.
diff --git a/ar-ar/python3-ar.html.markdown b/ar-ar/python3-ar.html.markdown
new file mode 100644
index 00000000..e1a12690
--- /dev/null
+++ b/ar-ar/python3-ar.html.markdown
@@ -0,0 +1,1019 @@
+---
+language: python3
+contributors:
+ - ["Louie Dinh", "http://pythonpracticeprojects.com"]
+ - ["Steven Basart", "http://github.com/xksteven"]
+ - ["Andre Polykanine", "https://github.com/Oire"]
+ - ["Zachary Ferguson", "http://github.com/zfergus2"]
+ - ["evuez", "http://github.com/evuez"]
+ - ["Rommel Martinez", "https://ebzzry.io"]
+ - ["Roberto Fernandez Diaz", "https://github.com/robertofd1995"]
+translators:
+ - ["Ahmad Hegazy", "https://github.com/ahegazy"]
+lang: ar-ar
+filename: learnpython3-ar.py
+---
+
+لقد أُنشئت لغة البايثون بواسطة جايدو ڤان روسم في بداية التسعينات. هي الأن أحد أشهر اللغات الموجودة.
+لقد أحببت لغة البايثون بسبب وضوحها. هي في الأساس عبارة عن سودوكود قابل للتنفيذ.
+
+ردود أفعالكم عن المقال مُقدرة بشدة. يمكنكم التواصل مع الكاتب الاساسي من خلال [@louiedinh](http://twitter.com/louiedinh) أو louiedinh [at] [google's email service]
+
+ملحوظة: هذا المقال يُطبق على بايثون 3 فقط. راجع المقال [هنا](http://learnxinyminutes.com/docs/python/) إذا أردت تعلم لغة البايثون نسخة 2.7 الأقدم
+
+```python
+
+# تعليق من سطر واحد يبدأ برمز الرقم.
+
+""" يمكن كتابة تعليق يتكون من أكثر من سطر
+ باستخدام ثلاثة علامات "
+ ، وعادة يُستخدم في كتابة التوثيقات.
+"""
+
+####################################################
+## 1. أنواع البيانات البدائية والعمليات
+####################################################
+
+# لديك أرقام
+3 # => 3
+
+# العمليات الحسابية هي ما تتوقعه
+1 + 1 # => 2
+8 - 1 # => 7
+10 * 2 # => 20
+35 / 5 # => 7.0
+
+# نتائج قسمة الأرقام الصحيحية تُقرب للأصغر سواءًا كانت الأرقام موجبة أو سالبة.
+5 // 3 # => 1
+5.0 // 3.0 # => 1.0 # يعمل في حالة الكسور أيضا
+-5 // 3 # => -2
+-5.0 // 3.0 # => -2.0
+
+# ناتج القسمة هو دائما كسر
+10.0 / 3 # => 3.3333333333333335
+
+# عملية باقي القسمة
+7 % 3 # => 1
+
+# الأُس (س ** ص، رفع س لقوى ص)
+2**3 # => 8
+
+# أفرض ترتيب العمليات الحسابية بالأقواس
+(1 + 3) * 2 # => 8
+
+# القيم الثنائية هي المعروفة عموما (ﻻحظ: تكبير أول حرف)
+True
+False
+
+# أنفي بـ (not)
+not True # => False
+not False # => True
+
+# العمليات على القيم الثنائية
+# ﻻحظ ﻻيهم حالة الحرف (كبير أو صغير) في "and" و "or"
+True and False # => False
+False or True # => True
+
+# True و False هما في الواقع 1 و 0 لكن بمسميات مختلفة
+True + True # => 2
+True * 8 # => 8
+False - 5 # => -5
+
+# عمليات المقارنة تنظر الي القيمة الرقمية لل True وال False
+0 == False # => True
+1 == True # => True
+2 == True # => False
+-5 != False # => True
+
+# عند استخدام المنطق الثنائي على القيم الصحيحة يتم تحويلهم الي قيم ثنائية لإجرات العمليات عليهم، لكن قيمهم الأصلية تعود
+# ﻻ تخلط بين bool(قيمة صحيحة) و العمليات المنطقية الثناية and/or (&,|)
+bool(0) # => False
+bool(4) # => True
+bool(-6) # => True
+0 and 2 # => 0
+-5 or 0 # => -5
+
+# مقارنة التساوي ب ==
+1 == 1 # => True
+2 == 1 # => False
+
+# مقارنة الاختلاف ب !=
+1 != 1 # => False
+2 != 1 # => True
+
+# مقارنات أخرى
+1 < 10 # => True
+1 > 10 # => False
+2 <= 2 # => True
+2 >= 2 # => True
+
+# لمعرفة هل القيمة في نطاق معين
+1 < 2 and 2 < 3 # => True
+2 < 3 and 3 < 2 # => False
+
+# التسلسل يجعلها تبدو أجمل
+1 < 2 < 3 # => True
+2 < 3 < 2 # => False
+
+# (is مقابل ==) is تتحق من أن المتغيرين يشيران إلي نفس العنصر,
+# لكن == تتحقق من أن العنصرين المُشار اليهما بالمتغيرين لهما نفس القيمة.
+a = [1, 2, 3, 4] # اجعل a تشير إلي قائمة جديدة, [1, 2, 3, 4]
+b = a # اجعل a تُشير الي ما تُشير إليه b
+b is a # => True, a و b يُشيران إلي نفس العنصر
+b == a # => True, قيمة عنصر a و b متساوية
+b = [1, 2, 3, 4] # اجعل b تشير الي قائمة جديدة , [1, 2, 3, 4]
+b is a # => False, a و b do ﻻ يشيران إلي نفس العنصر
+b == a # => True, قيمة عنصر a و b متساوية
+
+# يمكنك إنشاء الكلمات (تسلسلات الحروف) عن طريق " أو '
+"This is a string."
+'This is also a string.'
+
+# يمكنك جمع هذا النوع أيضا! لكن حاول ألا تفعل هذا.
+"Hello " + "world!" # => "Hello world!"
+# يمكنك الربط بين الكلمات بدون استخدام '+' (لكن ليس المتغيرات)
+"Hello " "world!" # => "Hello world!"
+
+# يمكنك معاملة الكلمات كقائمة من الحروف
+"This is a string"[0] # => 'T'
+
+# يمكنك معرفة طول الكلمة
+len("This is a string") # => 16
+
+# .format يمكنك استخدامها لبناء الجمل بشكل معين, مثل هذا:
+"{} can be {}".format("Strings", "interpolated") # => "Strings can be interpolated"
+
+# يمكنك تكرار معاملات بناء الجملة لتقليل الكتابة.
+"{0} be nimble, {0} be quick, {0} jump over the {1}".format("Jack", "candle stick")
+# => "Jack be nimble, Jack be quick, Jack jump over the candle stick"
+
+# يمكنك استخدام الكلمات المفتاحية إذا لم تُرد العد.
+"{name} wants to eat {food}".format(name="Bob", food="lasagna") # => "Bob wants to eat lasagna"
+
+# إذا كان كود بايثون 3 الخاص بك يحتاج لبايثون 2.5 أو نسخة أقدم
+# يمكنك استخدام أسلوب بناء الجمل القديم:
+"%s can be %s the %s way" % ("Strings", "interpolated", "old") # => "Strings can be interpolated the old way"
+
+# يمكنك أبضا بناء الجمل باستخدام f-strings أو حروف بناء الجمل (في بايثون 3.6 فما فوق)
+name = "Reiko"
+f"She said her name is {name}." # => "She said her name is Reiko"
+# يمكنك ببساطة وضع أي كود بايثون داخل أقواس وستقوم بإخراج الجملة.
+f"{name} is {len(name)} characters long."
+
+
+# None عبارة عن كائن
+None # => None
+
+# ﻻ تستخدم رمز المساواة "==" لمقارنة العناصر ب None
+# استخدم is بدلا منه. يقوم بالتحقق من مساواة هوية العنصر
+"etc" is None # => False
+None is None # => True
+
+# None, 0, قوائم/جمل/قواميس/صفوف فارغة كلها تُترجم إلي False.
+# كل القيم الأخرى True.
+bool(0) # => False
+bool("") # => False
+bool([]) # => False
+bool({}) # => False
+bool(()) # => False
+
+####################################################
+## 2. المتغيرات والمجموعات
+####################################################
+
+# بايثون لديها دالة عرض "print"
+print("I'm Python. Nice to meet you!") # => I'm Python. Nice to meet you!
+
+# الافتراضي دالة print تطبع سطر جديد في النهاية.
+# استخدم المعامل end لتغيير أخر الجملة المعروضة.
+print("Hello, World", end="!") # => Hello, World!
+
+# طريقة بسيطة لطلب مدخل من الطرفية
+input_string_var = input("Enter some data: ") # يقوم بإعادة البيانات ك "string"
+# لاحظ: في النسخ القديمة من بايثون، دالة input() كان اسمها raw_input()
+
+# ﻻ يوجد تعريفات للمتغيرات، يتم تعيين قيمة المتغير مباشرة.
+# العٌرف تسمية المتغيرات حروف_صغيرة_مع_خطوط_سُفلية
+some_var = 5
+some_var # => 5
+
+# محاولة استخدام متغير غير مُعين يعتبر خطأ
+# إقرأ جزء 3.مسار التحكم لمعرفة المزيد عن التحكم في الأخطاء
+some_unknown_var # يعرض خطأ NameError
+
+# يمكن استخدام if كتعبير واحد
+# مساوِ للتعبير الأتي في لغة السي '?:' عملية ثلاثية
+"yahoo!" if 3 > 2 else 2 # => "yahoo!"
+
+# القوائم تحفظ المتسلسلات
+li = []
+# يمكنك البدأ بقائمة مليئة
+other_li = [4, 5, 6]
+
+# إضافة بيانات لأخر القائمة عن طريق append
+li.append(1) # li is now [1]
+li.append(2) # li is now [1, 2]
+li.append(4) # li is now [1, 2, 4]
+li.append(3) # li is now [1, 2, 4, 3]
+# حذف أخر عنصر في القائمة عن طريق pop
+li.pop() # => 3 and li is now [1, 2, 4]
+# هيا نعيده ثانية
+li.append(3) # li is now [1, 2, 4, 3] again.
+
+# يمكنك الوصول لعناصر القائمة كما تفعل في ال array
+# Access a list like you would any array
+li[0] # => 1
+# للوصول لأخر عنصر
+li[-1] # => 3
+
+# محاولة الوصول لعنصر خارج نطاق القائمة يعتبر خطأ: IndexError
+li[4] # يعرض خطأ IndexError
+
+# يمكنك النظر للنطاقات باستخدام تركيب التقطيع
+# مؤشر/رقم/فهرس البداية مُضمن، مؤشر النهاية ﻻ
+# (لمحبي الرياضيات هو نطاق مفتوح/مغلق)
+li[1:3] # => [2, 4]
+# إحذف أول عنصر ثم إعرض القائمة
+li[2:] # => [4, 3]
+# إحذف أخر عنصر ثم إعرض القائمة
+li[:3] # => [1, 2, 4]
+# حدد عنصر ثم إحذف الذي يليه ثم حدد عنصر وهكذا
+li[::2] # =>[1, 4]
+# اعرض نسخة معكوسة من القائمة
+li[::-1] # => [3, 4, 2, 1]
+# إستخدم أي تجميعة من الطرق المذكورة لعمل تقطيعات متقدمة
+# li[start:end:step]
+
+# عمل نسخة من طبقة واحدة باستخدم التقطيع
+li2 = li[:] # => li2 = [1, 2, 4, 3] لكن عند عمل(li2 is li) سينتج False.
+
+# إمسح أي عنصر من القائمة باستخدام "del"
+del li[2] # li is now [1, 2, 3]
+
+# إمسح أول ظهور لقيمة.
+li.remove(2) # li is now [1, 3]
+li.remove(2) # يعرض خطأ ValueError لأن 2 غير موجود في القائمة
+
+# أضف عنصر في خانة معينة
+li.insert(1, 2) # li is now [1, 2, 3] مرة أخرى
+
+# أحصل على مؤشر/رقم لأول ظهور للقيمة
+li.index(2) # => 1
+li.index(4) # يعرض خطأ ValueError لأن 4 غير موجودة في القائمة
+
+# يمكنك جمع قوائم
+# لاحظ: لا يتم تعديل قيمة li و other_li
+li + other_li # => [1, 2, 3, 4, 5, 6]
+
+# إستخدم دالة "extend()" لربط القوائم
+li.extend(other_li) # Now li is [1, 2, 3, 4, 5, 6]
+
+# راجع وجود قيمة في القائمة باستخدام "in"
+1 in li # => True
+
+# إحصل على طول القائمة باستخدام دالة "len()"
+len(li) # => 6
+
+
+# الصفوف تشبه القوائم لكنها غير قابلة للتغيير.
+tup = (1, 2, 3)
+tup[0] # => 1
+tup[0] = 3 # يعرض خطأ TypeError
+
+# لاحظ أن صف طوله عنصر واحد يحتاج لإضافة فاصلة "," بعد أخر عنصر
+# لكن الصفوف من أي طول أخر، حتى صفر لا تحتاج.
+type((1)) # => <class 'int'>
+type((1,)) # => <class 'tuple'>
+type(()) # => <class 'tuple'>
+
+# يمكنك عمل معظم عمليات القوائم على الصفوف.
+len(tup) # => 3
+tup + (4, 5, 6) # => (1, 2, 3, 4, 5, 6)
+tup[:2] # => (1, 2)
+2 in tup # => True
+
+# يمكنك تفريغ الصفوف (أو القوائم) في متغيرات
+a, b, c = (1, 2, 3) # a is now 1, b is now 2 and c is now 3
+# يمكنك أيضا عمل تفريغ واسع
+a, *b, c = (1, 2, 3, 4) # a is now 1, b is now [2, 3] and c is now 4
+# الصفوف تُنشأ تلقائيا إذا تركت الأقواس
+d, e, f = 4, 5, 6 # تم توسعة الصف 4, 5 ,6 في المتغيرات d, e, f
+# بالترتيب حيث d = 4, e = 5 و f = 6
+# الأن إنظر إلي مدى سهولة التبديل بين قيم متغيرين
+e, d = d, e # d is now 5 and e is now 4
+
+
+# القواميس تُخزن خرائط من المفتاح للقيمة
+empty_dict = {}
+# هذا قاموس مملوء
+filled_dict = {"one": 1, "two": 2, "three": 3}
+
+# لاحظ أن القواميس يجب أن تكون أنواع غير قابلة للتغيير.
+# هذا للتأكد من أن المفتاح يمكن تحويله لقيمة ثابتة للوصول السريع.
+# الأنواع الغير قابلة للتغير تتضمن: الأرقام الصحيحة، الكسور، الكلمات، الصفوف.
+invalid_dict = {[1,2,3]: "123"} # =>يعرض خطأ TypeError: unhashable type: 'list'
+valid_dict = {(1,2,3):[1,2,3]} # القيم يمكن أن تكون من أي نوع.
+
+# يمكنك البحث عن قيمة باستخدام []
+filled_dict["one"] # => 1
+
+# يمكنك الحصول على كل المفاتيح باستخدام "keys()".
+# نحتاج لإرسالها لدالة list() لتحويلها لقائمة. سنتعلم هذا لاحقًا
+# لاحظ - لنسخ بايثون قبل 3.7، ترتيب مفاتيح القاموس غير مضمون. نتائجك
+# يمكن ألا تساوي المثال بالأسفل. مع ذلك، من أول بايثون 3.7،
+# عناصر القاموس تحتفظ بالترتيب الذي تم إضافة المفاتيح به في القاموس.
+list(filled_dict.keys()) # => ["three", "two", "one"] in Python <3.7
+list(filled_dict.keys()) # => ["one", "two", "three"] in Python 3.7+
+
+# يمكنك الحصول على كل القيم باستخدام "values()".
+# مرة أخرى نستخدم list() للحصول عليها كقائمة.
+# نفس الكلام السابق بخصوص ترتيب المفاتيح
+list(filled_dict.values()) # => [3, 2, 1] in Python <3.7
+list(filled_dict.values()) # => [1, 2, 3] in Python 3.7+
+
+# إفحص للتأكد من وجود مغتاح في القاموس باستخدام "in"
+"one" in filled_dict # => True
+1 in filled_dict # => False
+
+# البحث عن مفتاح غير موجود يعرض خطأ KeyError
+filled_dict["four"] # KeyError
+
+# استخدم "get()" لتجنب الخطأ KeyError
+filled_dict.get("one") # => 1
+filled_dict.get("four") # => None
+# دالة get تدعم إدخال قيمة افتراضية عند عدم وجود البحث
+filled_dict.get("one", 4) # => 1
+filled_dict.get("four", 4) # => 4
+
+# "setdefault()" تقوم بإدخال قيمة جديدة في القاموس في حالة عدم وجود المفتاح فقط.
+filled_dict.setdefault("five", 5) # filled_dict["five"] is set to 5
+filled_dict.setdefault("five", 6) # filled_dict["five"] is still 5
+
+# إضافة عنصر للقاموس
+filled_dict.update({"four":4}) # => {"one": 1, "two": 2, "three": 3, "four": 4}
+filled_dict["four"] = 4 # طريقة أخرى للإضافة
+
+# مسح المفاتيح من القاموس باستخدام del
+del filled_dict["one"] # Removes the key "one" from filled dict
+
+# من بايثون 3.5 فما فوق يمكنك أيضا استخدام خيارات تفريغ إضافية
+{'a': 1, **{'b': 2}} # => {'a': 1, 'b': 2}
+{'a': 1, **{'a': 2}} # => {'a': 2}
+
+
+# المجموعات تُخزن .. مجموعات
+empty_set = set()
+# .تهيئة مجموعة بمجموعة قيم. نعم، تشبه قليلا تهيئة القاموس. أسف
+some_set = {1, 1, 2, 2, 3, 4} # some_set is now {1, 2, 3, 4}
+
+# مثل مفتاح القاموس، عناصر المجموعة يجب أن تكون غير قابلة للتغيير.
+invalid_set = {[1], 1} # => يعرض خطأ TypeError: unhashable type: 'list'
+valid_set = {(1,), 1}
+
+# إضافة عنصر أخر للمجموعة
+filled_set = some_set
+filled_set.add(5) # filled_set is now {1, 2, 3, 4, 5}
+# المجموعات لا يمكن أن تحتوي على عناصر مكررة
+filled_set.add(5) # it remains as before {1, 2, 3, 4, 5}
+
+# تقاطع مجموعتين باستخدام &
+other_set = {3, 4, 5, 6}
+filled_set & other_set # => {3, 4, 5}
+
+# اتحاد مجموعتين باستخدام |
+filled_set | other_set # => {1, 2, 3, 4, 5, 6}
+
+# الفرق بين مجموعتين باستخدام -
+{1, 2, 3, 4} - {2, 3, 5} # => {1, 4}
+
+# الفروق بين مجموعتين باستخدام ^
+{1, 2, 3, 4} ^ {2, 3, 5} # => {1, 4, 5}
+
+# لفحص هل المجموعة على اليسار مجموعة عُليا للمجموعة على اليمين (تحتوي على كل عناصرها)
+{1, 2} >= {1, 2, 3} # => False
+
+# لفحص هل المجموعة على اليسار مجموعة فرعية من المجموعة على اليمين
+{1, 2} <= {1, 2, 3} # => True
+
+# للتأكد من وجود عن في مجموعة استخدم in
+2 in filled_set # => True
+10 in filled_set # => False
+
+
+
+####################################################
+## 3. مسار التحكم والعمليات التكرارية #Control Flow and Iterables
+####################################################
+
+# هيا ننشيء متغير
+some_var = 5
+
+# الأن الأمر if. الفجوات (المسافات قبل الأوامر) مهمة في البايثون!
+# العُرف استخدام أربع مسافات. ليس تبويب.
+# هذا السطر البرمجي يطبع "some_var is smaller than 10"
+if some_var > 10:
+ print("some_var is totally bigger than 10.")
+elif some_var < 10: # This elif clause is optional.
+ print("some_var is smaller than 10.")
+else: # This is optional too.
+ print("some_var is indeed 10.")
+
+
+"""
+For عبارة عن حلقات تدور حول عناصر قوائم
+:ثم تطبع
+ dog is a mammal
+ cat is a mammal
+ mouse is a mammal
+"""
+for animal in ["dog", "cat", "mouse"]:
+ # يمكنك استخدام format() لترجمة كلمات بشكل معين.
+ print("{} is a mammal".format(animal))
+
+"""
+"range(number)" يقوم بإعادة مجموعة من الأرقام يمكن الدوران حولها
+من الصفر إلي رقم معين
+ثم يطبع:
+ 0
+ 1
+ 2
+ 3
+"""
+
+for i in range(4):
+ print(i)
+
+"""
+"range(lower, upper)" يقوم بإعادة مجموعة من الأرقام يمكن الدوران حولها من القيمة السُفلى
+lower حتى القيمة العُليا upper
+ثم يطبع:
+ 4
+ 5
+ 6
+ 7
+"""
+for i in range(4, 8):
+ print(i)
+
+"""
+"range(lower, upper, step)" يقوم بإعادة مجموعة من الأرقام يمكن الدوران حولها من القيمة السُفلى
+lower حتى القيمة العُليا upper، ثم يقوم بالزيادة قيمة الstep.
+إذا لم تُحدد ال step, القيمة الأفتراضية 1.
+ثم يطبع:
+ 4
+ 6
+"""
+for i in range(4, 8, 2):
+ print(i)
+
+"""
+While هي عبارة عن حلقات تدور حتى عدم تحقق شرط معين.
+وتطبع:
+ 0
+ 1
+ 2
+ 3
+"""
+x = 0 for
+while x < 4:
+ print(x)
+ x += 1 # اختصار ل x = x + 1
+
+# يمكنك التحكم في الأخطاء والاستثناءات باستخدام مجموعة try/except
+try:
+ # استخدم "raise" لرفع خطأ.
+ raise IndexError("This is an index error")
+except IndexError as e:
+ pass # Pass: هو مجرد أمر ﻻ تفعل شيء. عادة تقوم بتصحيح الخطأ هنا.
+except (TypeError, NameError):
+ pass # يمكنك التحكم في أكثر من خطأ في نفس الوقت، إذا أقتضت الضرورة
+else: # فقرة اختيارية في مجموعة try/except. يجب أن يتبع جميع مجموعات معارضة الأخطاء
+ print("All good!") # تُنفذ في حالة أن السطور البرمجية داخل ال try لم ترفع أي خطأ
+finally: # تُنفذ في كل الحالات
+ print("We can clean up resources here")
+
+# بدلا من مجموعة try/finally لتنظيف الموارد يمكنك استخدام سطر with
+with open("myfile.txt") as f:
+ for line in f:
+ print(line)
+
+# يتيح البايثون تجريد أساسي يسمى المُكرَر.
+# المُكرٍَر عبارة عن متغير يمكن التعامل معه كسلسلة.
+# الكائن الذي يعود من دالة نطاق، يسمى المُكرَر.
+
+filled_dict = {"one": 1, "two": 2, "three": 3}
+our_iterable = filled_dict.keys()
+print(our_iterable) # => dict_keys(['one', 'two', 'three'])
+# هذا عبارة عن متغير يعرض عناصر مفاتيح المُكرَر.
+
+# يمكننا الدوران حوله.
+for i in our_iterable:
+ print(i) # Prints one, two, three
+
+# مع ذلك ﻻ يمكننا الوصول للعناصر بالمؤشر.
+our_iterable[1] # يرفع خطأ TypeError
+
+# المُكرَر هو عبارة عن عنصر يعلم كيفية إنشاء مُكرِر
+our_iterator = iter(our_iterable)
+
+# المُكرِر هو عبارة عن عنصر يمكنه تذكر الحالة أثناء مرورنا بعناصره.
+# يمكننا الحصول على العنصر التالي عن طريق "next()"
+next(our_iterator) # => "one"
+
+# يحفظ الحالة أثناء الدوران.
+next(our_iterator) # => "two"
+next(our_iterator) # => "three"
+
+# بعد عرض المُكرِر كل عناصره، يرفع استثناء StopIteration
+next(our_iterator) # يرفع StopIteration
+
+# يمكنك الحصول على كل عناصر المُكرر بمناداة دالة list() عليه.
+list(filled_dict.keys()) # => Returns ["one", "two", "three"]
+
+
+####################################################
+## 4. الدوال
+####################################################
+
+# إستخدم "def" لإنشاء دوال جديدة.
+def add(x, y):
+ print("x is {} and y is {}".format(x, y))
+ return x + y # يمكنك إرجاع قيمة من الدالة بسطر return
+
+# مناداة دوال بمعطيات
+add(5, 6) # => prints out "x is 5 and y is 6" and returns 11
+
+# طريقة أخرى لمناداة دوال باستخدام كلمات مفتاحية.
+add(y=6, x=5) # الكلمة المفتاحية يمكن أن تُعطى بأي ترتيب.
+
+# يمكنك تعريف دوال تأخذ عدد متغير من المُعطيات
+
+def varargs(*args):
+ return args
+
+varargs(1, 2, 3) # => (1, 2, 3)
+
+# يمكنك تعريف دوال تأخذ عدد متغير من الكلمات المفتاحية كمعطيات أيضا.
+def keyword_args(**kwargs):
+ return kwargs
+
+# هيا ننادي على الدالة لنرى ماذا سيحدث
+keyword_args(big="foot", loch="ness") # => {"big": "foot", "loch": "ness"}
+
+
+# يمكنك فعل الأثنين معًا في نفس الوقت، إذا أردت
+def all_the_args(*args, **kwargs):
+ print(args)
+ print(kwargs)
+"""
+all_the_args(1, 2, a=3, b=4) prints:
+ (1, 2)
+ {"a": 3, "b": 4}
+"""
+
+# عندما تنادي على دوال، يمكنك عمل عكس المعطيات/المفاتيح!
+# استخدم * لتوسعة الصفوف، واستخدم ** لتوسعة المفاتيح.
+args = (1, 2, 3, 4)
+kwargs = {"a": 3, "b": 4}
+all_the_args(*args) # مساوٍ ل all_the_args(1, 2, 3, 4)
+all_the_args(**kwargs) # مساوٍ ل to all_the_args(a=3, b=4)
+all_the_args(*args, **kwargs) # مساوٍ ل to all_the_args(1, 2, 3, 4, a=3, b=4)
+
+# يقوم بإعادة مجموعة من القيم (بتعيين الصفوف)
+def swap(x, y):
+ return y, x # يقوم بإعادة مجموعة من القيم على شكل صفوف بدون الأقواس
+ # (لاحظ: الأقواس حُذفت لكن يمكن إضافتها)
+
+x = 1
+y = 2
+x, y = swap(x, y) # => x = 2, y = 1
+# (x, y) = swap(x,y) # مرة أخرى الأقواس حُذفت لكن يمكن إضافتها.
+
+# مجال الدالة
+x = 5
+
+def set_x(num):
+ # المتغير المحلي x ليس هو المتغير العام x
+ x = num # => 43
+ print(x) # => 43
+
+def set_global_x(num):
+ global x
+ print(x) # => 5
+ x = num #المتغير العام x الأن مساوٍ ل 6
+ print(x) # => 6
+
+set_x(43)
+set_global_x(6)
+
+
+# بايثون تدعم دوال الفئة أولية [first class functions] (أي أنه يمكن إرسال الدوال كمعطيات لدوال أخرى)
+def create_adder(x):
+ def adder(y):
+ return x + y
+ return adder
+
+add_10 = create_adder(10)
+add_10(3) # => 13
+
+# يوجد أيضا دوال مجهولة
+(lambda x: x > 2)(3) # => True
+(lambda x, y: x ** 2 + y ** 2)(2, 1) # => 5
+
+# يوجد دوال مدمجة من درجة أعلى
+list(map(add_10, [1, 2, 3])) # => [11, 12, 13]
+list(map(max, [1, 2, 3], [4, 2, 1])) # => [4, 2, 3]
+
+list(filter(lambda x: x > 5, [3, 4, 5, 6, 7])) # => [6, 7]
+
+# يمكن إشتمال القوائم على خرائط وفلاتر حسنة الشكل
+# هذه القوائم تحفظ المُخرج كقائمة والتي بدورها يمكن أن تكون قائمة مداخلة
+[add_10(i) for i in [1, 2, 3]] # => [11, 12, 13]
+[x for x in [3, 4, 5, 6, 7] if x > 5] # => [6, 7]
+
+# يمكنك بناء مجموعات وقواميس على هذا المنوال أيضا
+{x for x in 'abcddeef' if x not in 'abc'} # => {'d', 'e', 'f'}
+{x: x**2 for x in range(5)} # => {0: 0, 1: 1, 2: 4, 3: 9, 4: 16}
+
+
+####################################################
+## 5. الوحدات البرمجية (الموديولات)
+####################################################
+
+# يمكنك استدعاء موديولات
+import math
+print(math.sqrt(16)) # => 4.0
+
+# يمكنك استدعاء دالة معينة من موديول
+from math import ceil, floor
+print(ceil(3.7)) # => 4.0
+print(floor(3.7)) # => 3.0
+
+# يمكنك استدعاء كل الدوال من مديول.
+# تحذير: هذا الفعل غير موصى به
+from math import *
+
+# يمكنك تصغير اسم موديول
+import math as m
+math.sqrt(16) == m.sqrt(16) # => True
+
+# موديولات البايثون عبارة عن ملفات بايثون عادية.
+# يمكنك كتابة الموديولات الخاصة بك, واستدعاها.
+# اسم الموديول يكون نفس اسم الملف.
+
+# يمكنك معرفة أي الدوال والصفات مُعرفة في الموديول.
+import math
+dir(math)
+
+# إذا كان لديك سكربت بايثون يسمى math.py
+# في نفس المجلد الموجود به السكربت الخاص بك، الملف الخاص بك math.py
+# سَيُستدعى بدلا من موديول البايثون بنفس الاسم
+# هذا يحدث لأن المجلدات المحلية لديها أولوية عن مكتبات البايثون المُدمجة
+
+
+####################################################
+## 6. الفئات/القوالب (الكلاسات)
+####################################################
+
+# نستخدم السطر البرمجي "class" لإنشاء قالب
+class Human:
+
+ # صفة القالب. مشتركة بين كل نسخ القالب
+ species = "H. sapiens"
+
+ # مُهيئ إبتدائي، يُنادى عليه عندما يتم استدعاء القالب.
+ # لاحظ أن الشرطة السٌفلية المُكررة مرتين __ قبل وبعد الاسم تُعبر عن الكائنات
+ # أو الصفات المُستخدمة عن طريق بايثون لكنها تعيش في مساحة تحكم المُستخدم.
+ # العمليات -الدوال- (أو الكائنات أو الصفات) مثل: __init__, __str__,__repr__ ألخ.
+ # تُسمى عمليات خاصة (أو أحيانا تسمى عمليات سحرية أو dunder methods)
+ # يجب عليك ألا تُسمي مثل هذه الاسماء بنفسك.
+ def __init__(self, name):
+ # ساوِ المُعطى بالصفة name الخاصة بهذه النسخة من القالب.
+ self.name = name
+
+ # هيئ الصفة
+ self._age = 0
+
+ # عملية/دالة خاصة بنسخة القالب. كل العمليات تأخذ "self" كأول مُعطى
+ # An instance method. All methods take "self" as the first argument
+ def say(self, msg):
+ print("{name}: {message}".format(name=self.name, message=msg))
+
+ # عملية أخرى خاصة بنسخة القالب.
+ def sing(self):
+ return 'yo... yo... microphone check... one two... one two...'
+
+ # عمليات القالب مشتركة بين كل أجزاء القالب
+ # يتم مناداتهم عن طريق جعل القالب المُنادي أول معطى
+ # They are called with the calling class as the first argument
+ @classmethod
+ def get_species(cls):
+ return cls.species
+
+ # تُنادى العملية الثابتة بدون قالب أو نسخة قالب
+ @staticmethod
+ def grunt():
+ return "*grunt*"
+
+ # الخاصية تشبه تماما إمر الطلب
+ # تُحَوِل العملية age() إلي صفة مقروءة فقط بنفس الاسم.
+ # ﻻ حاجة لكتابة أوامر طلب أو تهيئة
+ @property
+ def age(self):
+ return self._age
+
+ # هذا يتيح تهيئة الخاصية
+ @age.setter
+ def age(self, age):
+ self._age = age
+
+ # هذا يتيح حذف الخاصية
+ @age.deleter
+ def age(self):
+ del self._age
+
+
+# عندما يقرأ مُترجم البايثون ملف مصدري يقوم بتنفيذ كل الكود.
+# فحص ال __name__ يجعل هذا الجزء من الكود يُنَفَذ فقط
+# في حالة أن هذا الموديول هو البرنامج الرئيسي
+if __name__ == '__main__':
+ # Instantiate a class
+ i = Human(name="Ian")
+ i.say("hi") # "Ian: hi"
+ j = Human("Joel")
+ j.say("hello") # "Joel: hello"
+ # i و j نُسخ من النوع Human, أول بكلمات أخرى: هما كائنات للقالب Human
+
+ # نادي على عملية القالب
+ i.say(i.get_species()) # "Ian: H. sapiens"
+ # عدل الخاصية المُشتركة
+ Human.species = "H. neanderthalensis"
+ i.say(i.get_species()) # => "Ian: H. neanderthalensis"
+ j.say(j.get_species()) # => "Joel: H. neanderthalensis"
+
+ # نادي على العملية الثابتة
+ print(Human.grunt()) # => "*grunt*"
+
+ # لا يمكن مناداة العملية الثابتة من نسخة الكائن
+ # لأن i.grunt() سيقوم تلقائيا بوضع "self" (الكائن i) كمُعطى للعملية
+ print(i.grunt()) # => TypeError: grunt() takes 0 positional arguments but 1 was given
+
+ # حدًث الخاصية لهذه النسخة
+ i.age = 42
+ # أحصل على الخاصية
+ i.say(i.age) # => "Ian: 42"
+ j.say(j.age) # => "Joel: 0"
+ # إحذف الخاصية
+ del i.age
+ # i.age # => سوف يرفع استثناء AttributeError
+
+
+####################################################
+## 6.1 الإرث
+####################################################
+
+# الإرث يتيح لقالب ابن أن يُعَرف ويرث بعض عمليات/دوال ومتغيرات القالب الأب.
+
+# باستخدام القالب Human المُعَرف بالأعلى كأساس أو كقالب أب،
+# يمكننا تعريف قالب ابن،Superhero ، يرث متغيرات القالب مثل "species", "name", و "age"،
+# وأيضا العمليات، مثل "sing", "grunt"
+# من القالب Human، لكنه أيضا لديه خواصه الفريدة
+
+# للاستفادة من التقطيع بالملف يمكنك وضع القوالب بالأعلى في ملفاتهم الخاصة،
+# مثلا، human.py
+
+# لاستيراد دالة من ملف أخر استخدم الطريقة التالية
+# from "اسم الملف بدون مُلحق" import "اسم الدالة أو القالب"
+
+from human import Human
+
+# حدد القالب/ات الأب كمُعطى أثناء تعريف القالب.
+class Superhero(Human):
+
+ # إذا أردت أن يرث القالب الابن كل تعريفات القالب الأب بدون تعديل
+ # يمكنك استخدام الكلمة المفتاحية "pass" (بدون شيء أخر)
+ # لكن في هذه الحالة تم أهمالها لإنشاء قالب ابن فريد:
+ # pass
+
+ # القوالب الابن يمكنها تعديل صفات القوالب الأب
+ species = 'Superhuman'
+
+ # القوالب الابن ترث تلقائيا عمليات الإنشاء الخاصة بالقالب الأب بالإضافة إلي مُعطياتهم
+ # لكن يمكن أيضا تعريف مُعطيات إضافية أو تعريفات
+ # وتعديل العمليات مثل منشيء القالب.
+ # هذا المُنشيء يرث المُعطى "name" من القالب "Human"
+ # ويضيف المعطيات"superpower" و "movies":
+ def __init__(self, name, movie=False,
+ superpowers=["super strength", "bulletproofing"]):
+
+ # إضافة صفة جديدة للقالب
+ self.fictional = True
+ self.movie = movie
+ # كن على علم بالقيم الافتراضية المتغيرة، حيث أن القيم الافتراضية تُشارك
+ self.superpowers = superpowers
+
+ # الدالة "super" تتيح لك الوصول لعمليات القالب الأب
+ # التي تم تغييرها عن طريق الابن، في هذه الحالة، العملية __init__<
+ # هذا السطر يُنادي على منشيء القالب الأب.
+ super().__init__(name)
+
+ # تعديل العملية sing
+ def sing(self):
+ return 'Dun, dun, DUN!'
+
+ # إضافة عملية جديدة للنسخة
+ def boast(self):
+ for power in self.superpowers:
+ print("I wield the power of {pow}!".format(pow=power))
+
+
+if __name__ == '__main__':
+ sup = Superhero(name="Tick")
+
+ # فحص نوع النسخة
+ if isinstance(sup, Human):
+ print('I am human')
+ if type(sup) is Superhero:
+ print('I am a superhero')
+
+ # إحصل على ترتيب قرار البحث للعملية (Method Resolution search Order) المُستخدمة بواسطة العمليات getattr() و super()
+ # هذه الصفة ديناميكية ويمكن أن تُحَدًث.
+ print(Superhero.__mro__) # => (<class '__main__.Superhero'>,
+ # => <class 'human.Human'>, <class 'object'>)
+
+ # نادي العملية الأب لكن استخدم صفات القالب الخاص بها.
+ print(sup.get_species()) # => Superhuman
+
+ # نادي العملية المُعدلة.
+ print(sup.sing()) # => Dun, dun, DUN!
+
+ # نادي العملية من القالب Human
+ sup.say('Spoon') # => Tick: Spoon
+
+ # نادي عملية موجودة فقط في Superhero
+ sup.boast() # => I wield the power of super strength!
+ # => I wield the power of bulletproofing!
+
+ # وَرَثَ صفات القالب
+ sup.age = 31
+ print(sup.age) # => 31
+
+ # صفة موجودة فقط في القالب Superhero
+ print('Am I Oscar eligible? ' + str(sup.movie))
+
+####################################################
+## 6.2 الإرث المُتعدد
+####################################################
+
+# تعريف قالب أخرA
+# bat.py
+class Bat:
+
+ species = 'Baty'
+
+ def __init__(self, can_fly=True):
+ self.fly = can_fly
+
+ # هذا القالب لديه عملية تسمى say
+ def say(self, msg):
+ msg = '... ... ...'
+ return msg
+
+ # ولديه عمليته الخاصة به أيضا
+ def sonar(self):
+ return '))) ... ((('
+
+if __name__ == '__main__':
+ b = Bat()
+ print(b.say('hello'))
+ print(b.fly)
+
+# تعريف قالب أخر يرث من Superhero و Bat
+# superhero.py
+from superhero import Superhero
+from bat import Bat
+
+# عَرٍف Batman كقالب ابن يرث من كلا من Superhero و Bat
+class Batman(Superhero, Bat):
+
+ def __init__(self, *args, **kwargs):
+ # عادة لكي ترث صفة يجد أن تنادي على super:
+ # super(Batman, self).__init__(*args, **kwargs)
+ # لكننا في هذه الحالة نتعامل مع إرث متعدد هنا، و super()
+ # تعمل فقط مع القالب التالي في قائمة ال MRO.
+ # لذا بدلا من ذلك ننادي على __init__ صراحة لكل الأباء.
+ # استخدام *args و **kwargs يتيح طريقة نظيفة لتمرير المعطيات.
+ # لكل أب "تقشير طبقة من البصل".
+ Superhero.__init__(self, 'anonymous', movie=True,
+ superpowers=['Wealthy'], *args, **kwargs)
+ Bat.__init__(self, *args, can_fly=False, **kwargs)
+ # تعديل قيمة الصفة name
+ self.name = 'Sad Affleck'
+
+ def sing(self):
+ return 'nan nan nan nan nan batman!'
+
+
+if __name__ == '__main__':
+ sup = Batman()
+
+ # إحصل على ترتيب قرار البحث للعملية (Method Resolution search Order) المُستخدمة بواسطة العمليات getattr() و super()
+ # هذه الصفة ديناميكية ويمكن أن تُحَدًث.
+ print(Batman.__mro__) # => (<class '__main__.Batman'>,
+ # => <class 'superhero.Superhero'>,
+ # => <class 'human.Human'>,
+ # => <class 'bat.Bat'>, <class 'object'>)
+
+ # نادي على العملية الخاصة بالأب لكن استخدم الصفات الخاصة بالقالب الابن
+ print(sup.get_species()) # => Superhuman
+
+ # نادي على العملية المُعدلة
+ print(sup.sing()) # => nan nan nan nan nan batman!
+
+ # نادي على العملية من القالب Human, لأن الترتيب في الأرث مهم.
+ sup.say('I agree') # => Sad Affleck: I agree
+
+ # نادي على العملية الموجودة فقط في القالب الأب الثاني
+ print(sup.sonar()) # => ))) ... (((
+
+ # الصفة الموروثة من القالب الأب
+ sup.age = 100
+ print(sup.age) # => 100
+
+ # الصفة الموروثة من القالب الأب الثاني، الذي تم تعديل قيمته الافتراضية
+ print('Can I fly? ' + str(sup.fly)) # => Can I fly? False
+
+
+
+####################################################
+## 7. مُتَقدم
+####################################################
+
+# المولدات تُساعدك على كتابة كود كسول.
+def double_numbers(iterable):
+ for i in iterable:
+ yield i + i
+
+# المولدات فعالة من حيث الذاكرة، لأنها تُحمٍل الذاكرة بالبيانات التي تحتاج
+# لإجراء العملية عليها في الخطوة التالية في المُكَرِر.
+# هذا يتيح إجراء عمليات على قيم كبيرة ممنوعة في حالات أخرى.
+# ﻻحظ: `range` بديل ل `xrange` في بايثون 3.
+for i in double_numbers(range(1, 900000000)): # `range` is a generator.
+ print(i)
+ if i >= 30:
+ break
+
+# كما يمكنك إنشاء قوائم اشتمال، يمكنك إنشاء مولدات اشتمال أيضا
+values = (-x for x in [1,2,3,4,5])
+for x in values:
+ print(x) # prints -1 -2 -3 -4 -5 to console/terminal
+
+# يمكنك أيضا تغيير نوع مولد الاشتمال مباشرة إلي قائمة
+values = (-x for x in [1,2,3,4,5])
+gen_to_list = list(values)
+print(gen_to_list) # => [-1, -2, -3, -4, -5]
+
+
+# المُحسنات
+# في هذا المثال الدالة`beg` تُغلف الدالة `say`.
+# إذا كانت say_please تساوي True
+# إذا ستُغير الرسالة الراجعة من الدالة
+from functools import wraps
+
+def beg(target_function):
+ @wraps(target_function)
+ def wrapper(*args, **kwargs):
+ msg, say_please = target_function(*args, **kwargs)
+ if say_please:
+ return "{} {}".format(msg, "Please! I am poor :(")
+ return msg
+
+ return wrapper
+
+
+@beg
+def say(say_please=False):
+ msg = "Can you buy me a beer?"
+ return msg, say_please
+
+
+print(say()) # Can you buy me a beer?
+print(say(say_please=True)) # Can you buy me a beer? Please! I am poor :(
+```
+
+## جاهز للمزيد?
+
+### مجانا عبر الانترنت
+
+* [أتمتتة المهمات المُملة عبر بايثون](https://automatetheboringstuff.com)
+* [أفكار لمشروعات بلغة البايثون](http://pythonpracticeprojects.com)
+* [التوثيقات الرسمية](http://docs.python.org/3/)
+* [دليل المُسافر لبايثون](http://docs.python-guide.org/en/latest/)
+* [دورة بايثون](http://www.python-course.eu/index.php)
+* [أولى الخطوات مع بايثون](https://realpython.com/learn/python-first-steps/)
+* [قائمة مُختارة من إطارات عمل بايثون الرائعة, المكتبات والبرمجيات](https://github.com/vinta/awesome-python)
+* [ثلاثون خاصية وخدعة للغة البايثون ربما لم تعرف بها](http://sahandsaba.com/thirty-python-language-features-and-tricks-you-may-not-know.html)
+* [الدليل الرسمي لنمط البايثون](https://www.python.org/dev/peps/pep-0008/)
+* [بايثون 3 دوائر علوم الحاسب](http://cscircles.cemc.uwaterloo.ca/)
+* [غُص في بايثون 3](http://www.diveintopython3.net/index.html)
+* [دورة سريعة في البايثون للعلماء](http://nbviewer.jupyter.org/gist/anonymous/5924718)
diff --git a/asymptotic-notation.html.markdown b/asymptotic-notation.html.markdown
index a1dfe9e1..7a7989d3 100644
--- a/asymptotic-notation.html.markdown
+++ b/asymptotic-notation.html.markdown
@@ -110,7 +110,7 @@ Let's look to the definition of Big-O.
3log n + 100 <= c * log n
```
-Is there some pair of constants c, n<sub>0</sub> that satisfies this for all n > <sub>0</sub>?
+Is there some pair of constants c, n<sub>0</sub> that satisfies this for all n > n<sub>0</sub>?
```
3log n + 100 <= 150 * log n, n > 2 (undefined at n = 1)
diff --git a/awk.html.markdown b/awk.html.markdown
index 3d2c4ccb..3ff3f937 100644
--- a/awk.html.markdown
+++ b/awk.html.markdown
@@ -1,5 +1,6 @@
---
-language: awk
+category: tool
+tool: awk
filename: learnawk.awk
contributors:
- ["Marshall Mason", "http://github.com/marshallmason"]
@@ -10,7 +11,7 @@ AWK is a standard tool on every POSIX-compliant UNIX system. It's like
flex/lex, from the command-line, perfect for text-processing tasks and
other scripting needs. It has a C-like syntax, but without mandatory
semicolons (although, you should use them anyway, because they are required
-when you're writing one-liners, something AWK excells at), manual memory
+when you're writing one-liners, something AWK excels at), manual memory
management, or static typing. It excels at text processing. You can call to
it from a shell script, or you can use it as a stand-alone scripting language.
@@ -32,7 +33,7 @@ pattern2 { action; }
# There is an implied loop and AWK automatically reads and parses each
# record of each file supplied. Each record is split by the FS delimiter,
# which defaults to white-space (multiple spaces,tabs count as one)
-# You cann assign FS either on the command line (-F C) or in your BEGIN
+# You can assign FS either on the command line (-F C) or in your BEGIN
# pattern
# One of the special patterns is BEGIN. The BEGIN pattern is true
@@ -238,7 +239,7 @@ function io_functions( localvar) {
# handle for you when you use something that needs one. The string you used
# for this can be treated as a file handle, for purposes of I/O. This makes
# it feel sort of like shell scripting, but to get the same output, the string
- # must match exactly, so use a vaiable:
+ # must match exactly, so use a variable:
outfile = "/tmp/foobar.txt";
@@ -381,3 +382,5 @@ Further Reading:
* [Awk man page](https://linux.die.net/man/1/awk)
* [The GNU Awk User's Guide](https://www.gnu.org/software/gawk/manual/gawk.html) GNU Awk is found on most Linux systems.
* [AWK one-liner collection](http://tuxgraphics.org/~guido/scripts/awk-one-liner.html)
+* [Awk alpinelinux wiki](https://wiki.alpinelinux.org/wiki/Awk) a technical summary and list of "gotchas" (places where different implementations may behave in different or unexpected ways).
+* [basic libraries for awk](https://github.com/dubiousjim/awkenough)
diff --git a/bash.html.markdown b/bash.html.markdown
index 8c40931e..856db706 100644
--- a/bash.html.markdown
+++ b/bash.html.markdown
@@ -11,30 +11,34 @@ contributors:
- ["Rahil Momin", "https://github.com/iamrahil"]
- ["Gregrory Kielian", "https://github.com/gskielian"]
- ["Etan Reisner", "https://github.com/deryni"]
- - ["Jonathan Wang", "https://github.com/Jonathansw"]
+ - ["Jonathan Wang", "https://github.com/Jonathansw"]
- ["Leo Rudberg", "https://github.com/LOZORD"]
- ["Betsy Lorton", "https://github.com/schbetsy"]
- ["John Detter", "https://github.com/jdetter"]
- ["Harry Mumford-Turner", "https://github.com/harrymt"]
- ["Martin Nicholson", "https://github.com/mn113"]
filename: LearnBash.sh
+translators:
+ - ["Dimitri Kokkonis", "https://github.com/kokkonisd"]
---
-Bash is a name of the unix shell, which was also distributed as the shell for the GNU operating system and as default shell on Linux and Mac OS X.
-Nearly all examples below can be a part of a shell script or executed directly in the shell.
+Bash is a name of the unix shell, which was also distributed as the shell
+for the GNU operating system and as default shell on Linux and Mac OS X.
+Nearly all examples below can be a part of a shell script
+or executed directly in the shell.
[Read more here.](http://www.gnu.org/software/bash/manual/bashref.html)
```bash
#!/usr/bin/env bash
-# First line of the script is shebang which tells the system how to execute
+# First line of the script is the shebang which tells the system how to execute
# the script: http://en.wikipedia.org/wiki/Shebang_(Unix)
# As you already figured, comments start with #. Shebang is also a comment.
# Simple hello world example:
echo Hello world! # => Hello world!
-# Each command starts on a new line, or after semicolon:
+# Each command starts on a new line, or after a semicolon:
echo 'This is the first line'; echo 'This is the second line'
# => This is the first line
# => This is the second line
@@ -47,7 +51,7 @@ Variable = "Some string" # => returns error "Variable: command not found"
# Bash will decide that Variable is a command it must execute and give an error
# because it can't be found.
-# Or like this:
+# Nor like this:
Variable= 'Some string' # => returns error: "Some string: command not found"
# Bash will decide that 'Some string' is a command it must execute and give an
# error because it can't be found. (In this case the 'Variable=' part is seen
@@ -65,8 +69,9 @@ echo '$Variable' # => $Variable
# Parameter expansion ${ }:
echo ${Variable} # => Some string
# This is a simple usage of parameter expansion
-# Parameter Expansion gets a value from a variable. It "expands" or prints the value
-# During the expansion time the value or parameter are able to be modified
+# Parameter Expansion gets a value from a variable.
+# It "expands" or prints the value
+# During the expansion time the value or parameter can be modified
# Below are other modifications that add onto this expansion
# String substitution in variables
@@ -84,7 +89,7 @@ echo ${Variable: -5} # => tring
echo ${#Variable} # => 11
# Default value for variable
-echo ${Foo:-"DefaultValueIfFooIsMissingOrEmpty"}
+echo ${Foo:-"DefaultValueIfFooIsMissingOrEmpty"}
# => DefaultValueIfFooIsMissingOrEmpty
# This works for null (Foo=) and empty string (Foo=""); zero (Foo=0) returns 0.
# Note that it only returns default value and doesn't change variable value.
@@ -114,8 +119,8 @@ echo {1..10} # => 1 2 3 4 5 6 7 8 9 10
echo {a..z} # => a b c d e f g h i j k l m n o p q r s t u v w x y z
# This will output the range from the start value to the end value
-# Builtin variables:
-# There are some useful builtin variables, like
+# Built-in variables:
+# There are some useful built-in variables, like
echo "Last program's return value: $?"
echo "Script's PID: $$"
echo "Number of arguments passed to script: $#"
@@ -127,7 +132,7 @@ echo "Script's arguments separated into different variables: $1 $2..."
# Our current directory is available through the command `pwd`.
# `pwd` stands for "print working directory".
-# We can also use the builtin variable `$PWD`.
+# We can also use the built-in variable `$PWD`.
# Observe that the following are equivalent:
echo "I'm in $(pwd)" # execs `pwd` and interpolates output
echo "I'm in $PWD" # interpolates the variable
@@ -143,7 +148,7 @@ read Name # Note that we didn't need to declare a new variable
echo Hello, $Name!
# We have the usual if structure:
-# use 'man test' for more info about conditionals
+# use `man test` for more info about conditionals
if [ $Name != $USER ]
then
echo "Your name isn't your username"
@@ -180,7 +185,7 @@ then
echo "This will run if $Name is Daniya OR Zach."
fi
-# There is also the =~ operator, which tests a string against a Regex pattern:
+# There is also the `=~` operator, which tests a string against a Regex pattern:
Email=me@example.com
if [[ "$Email" =~ [a-z]+@[a-z]{2,}\.(com|net|org) ]]
then
@@ -190,9 +195,9 @@ fi
# which are subtly different from single [ ].
# See http://www.gnu.org/software/bash/manual/bashref.html#Conditional-Constructs for more on this.
-# Redefine command 'ping' as alias to send only 5 packets
+# Redefine command `ping` as alias to send only 5 packets
alias ping='ping -c 5'
-# Escape alias and use command with this name instead
+# Escape the alias and use command with this name instead
\ping 192.168.1.1
# Print all aliases
alias -p
@@ -205,14 +210,14 @@ echo $(( 10 + 5 )) # => 15
# directory with the ls command:
ls # Lists the files and subdirectories contained in the current directory
-# These commands have options that control their execution:
+# This command has options that control its execution:
ls -l # Lists every file and directory on a separate line
ls -t # Sorts the directory contents by last-modified date (descending)
ls -R # Recursively `ls` this directory and all of its subdirectories
# Results of the previous command can be passed to the next command as input.
-# grep command filters the input with provided patterns. That's how we can list
-# .txt files in the current directory:
+# The `grep` command filters the input with provided patterns.
+# That's how we can list .txt files in the current directory:
ls -l | grep "\.txt"
# Use `cat` to print files to stdout:
@@ -241,7 +246,7 @@ cp -r srcDirectory/ dst/ # recursively copy
# `mv` is also useful for renaming files!
mv s0urc3.txt dst.txt # sorry, l33t hackers...
-# Since bash works in the context of a current directory, you might want to
+# Since bash works in the context of a current directory, you might want to
# run your command in some other directory. We have cd for changing location:
cd ~ # change to home directory
cd # also goes to home directory
@@ -277,13 +282,20 @@ for line in sys.stdin:
EOF
# Variables will be expanded if the first "EOF" is not quoted
-# Run the hello.py Python script with various stdin, stdout, and
+# Run the hello.py Python script with various stdin, stdout, and
# stderr redirections:
python hello.py < "input.in" # pass input.in as input to the script
+
python hello.py > "output.out" # redirect output from the script to output.out
+
python hello.py 2> "error.err" # redirect error output to error.err
-python hello.py > "output-and-error.log" 2>&1 # redirect both output and errors to output-and-error.log
-python hello.py > /dev/null 2>&1 # redirect all output and errors to the black hole, /dev/null, i.e., no output
+
+python hello.py > "output-and-error.log" 2>&1
+# redirect both output and errors to output-and-error.log
+
+python hello.py > /dev/null 2>&1
+# redirect all output and errors to the black hole, /dev/null, i.e., no output
+
# The output error will overwrite the file if it exists,
# if you want to append instead, use ">>":
python hello.py >> "output.out" 2>> "error.err"
@@ -312,11 +324,11 @@ rm -r tempDir/ # recursively delete
# current directory.
echo "There are $(ls | wc -l) items here."
-# The same can be done using backticks `` but they can't be nested - the preferred way
-# is to use $( ).
+# The same can be done using backticks `` but they can't be nested -
+#the preferred way is to use $( ).
echo "There are `ls | wc -l` items here."
-# Bash uses a case statement that works similarly to switch in Java and C++:
+# Bash uses a `case` statement that works similarly to switch in Java and C++:
case "$Variable" in
#List patterns for the conditions you want to meet
0) echo "There is a zero.";;
@@ -324,7 +336,7 @@ case "$Variable" in
*) echo "It is not null.";;
esac
-# for loops iterate for as many arguments given:
+# `for` loops iterate for as many arguments given:
# The contents of $Variable is printed three times.
for Variable in {1..3}
do
@@ -345,14 +357,14 @@ done
# => 3
# They can also be used to act on files..
-# This will run the command 'cat' on file1 and file2
+# This will run the command `cat` on file1 and file2
for Variable in file1 file2
do
cat "$Variable"
done
# ..or the output from a command
-# This will cat the output from ls.
+# This will `cat` the output from `ls`.
for Output in $(ls)
do
cat "$Output"
@@ -432,8 +444,8 @@ grep "^foo.*bar$" file.txt | grep -v "baz"
# and not the regex, use fgrep (or grep -F)
fgrep "foobar" file.txt
-# The trap command allows you to execute a command whenever your script
-# receives a signal. Here, trap will execute `rm` if it receives any of the
+# The `trap` command allows you to execute a command whenever your script
+# receives a signal. Here, `trap` will execute `rm` if it receives any of the
# three listed signals.
trap "rm $TEMP_FILE; exit" SIGHUP SIGINT SIGTERM
@@ -442,7 +454,7 @@ NAME1=$(whoami)
NAME2=$(sudo whoami)
echo "Was $NAME1, then became more powerful $NAME2"
-# Read Bash shell builtins documentation with the bash 'help' builtin:
+# Read Bash shell built-ins documentation with the bash `help` built-in:
help
help help
help for
@@ -450,12 +462,12 @@ help return
help source
help .
-# Read Bash manpage documentation with man
+# Read Bash manpage documentation with `man`
apropos bash
man 1 bash
man bash
-# Read info documentation with info (? for help)
+# Read info documentation with `info` (`?` for help)
apropos info | grep '^info.*('
man info
info info
diff --git a/bc.html.markdown b/bc.html.markdown
new file mode 100644
index 00000000..9d63acfb
--- /dev/null
+++ b/bc.html.markdown
@@ -0,0 +1,98 @@
+---
+language: bc
+contributors:
+ - ["Btup"]
+filename: learnbc.bc
+---
+```c
+/*This is a multi-
+line comment.*/
+# This is also a (one-line) comment! (in GNU bc).
+
+ /*1. Variables and control structures*/
+num = 45 /*All variables save only doubles, and you cannot save
+ string constants directly.*/
+num = 45; /*You can choose to add a semicolon after
+ every statement. This is optional.*/
+/*Blocks are denoted using the {} operators(similar to C):*/
+while(num < 50) {
+ num += 1 /*equivalent to num=num+1.
+ a = a op b is equivalent to a op= b.*/
+}
+/*And there are ++(increment) and --(decrement) operators.*/
+/*There are 3 special variables:
+scale: defines the scale of the double numbers.
+ibase: defines the base of input.
+obase: defines the base of output.*/
+/*If clauses:*/
+hour = read() /*Input a number*/
+
+if(hour < 12) { /*Operators are exactly like C.*/
+ print "Good morning\n" /*"print" outputs strings or variables
+ separated by commas.*/
+} else if(hour == 12) {
+ print "Hello\n"
+ /*Escaping sequences start with a \ in a string.
+ In order to make the escaping sequences clearer, here
+ is a simplified list of them that will work in bc:
+ \b: backspace
+ \c: carriage return
+ \n: newline
+ \t: tab
+ \\: backslash*/
+} else {
+ /*Variables are global by default.*/
+ thisIsGlobal = 5
+ /*You can make a variable local. Use the "auto" keyword in a function.*/
+}
+
+/*Every variable is pre-set to 0.*/
+num = blankVariable /*num is set to 0.*/
+
+/*Like C, only 0 is falsy.*/
+if(!num) {print "false\n"}
+
+/*Unlike C, bc does not have the ?: operators. For example,
+ this block of code will cause an error:
+a = (num) ? 1 : 0
+However, you can simulate one:*/
+a = (num) && (1) || (0) /*&& is and, || is or*/
+
+/*For loops*/
+num = 0
+for(i = 1; i <= 100; i++) {/*Similar to the C for loop.*/
+ num += i
+}
+
+ /*2.Functions and Arrays*/
+define fac(n) { /*define a function using define.*/
+ if(n == 1 || n == 0) {
+ return 1 /*return a value*/
+ }
+ return n * fac(n - 1) /*recursion is possible*/
+}
+
+/*Closures and anonymous functions are impossible.*/
+
+num = fac(4) /*24*/
+
+/*This is an example of local variables:*/
+define x(n) {
+ auto x
+ x = 1
+ return n + x
+}
+x(3) /*4*/
+print x /*It turns out that x is not accessible out of the function.*/
+/*Arrays are equivalent to the C array.*/
+for(i = 0; i <= 3; i++) {
+ a[i] = 1
+}
+/*Access it like this:*/
+print a[0], " ", a[1], " ", a[2], " ", a[3], "\n"
+quit /*Add this line of code to make sure
+that your program exits. This line of code is optional.*/
+```
+Enjoy this simple calculator! (Or this programming language, to be exact.)
+
+This whole program is written in GNU bc. To run it, use ```bc learnbc.bc```.
diff --git a/c++.html.markdown b/c++.html.markdown
index 4113d5f4..176ea1a8 100644
--- a/c++.html.markdown
+++ b/c++.html.markdown
@@ -72,13 +72,13 @@ void func(); // function which may accept any number of arguments
int* ip = nullptr;
// C standard headers are available in C++.
-// C headers end in .h, while
+// C headers end in .h, while
// C++ headers are prefixed with "c" and have no ".h" suffix.
// The C++ standard version:
#include <cstdio>
-//The C standard version:
+// The C standard version:
#include <stdio.h>
int main()
@@ -257,7 +257,7 @@ fooRef = bar;
cout << &fooRef << endl; //Still prints the address of foo
cout << fooRef; // Prints "I am bar"
-//The address of fooRef remains the same, i.e. it is still referring to foo.
+// The address of fooRef remains the same, i.e. it is still referring to foo.
const string& barRef = bar; // Create a const reference to bar.
@@ -553,10 +553,14 @@ Point Point::operator+(const Point& rhs) const
return Point(x + rhs.x, y + rhs.y);
}
+// It's good practice to return a reference to the leftmost variable of
+// an assignment. `(a += b) == c` will work this way.
Point& Point::operator+=(const Point& rhs)
{
x += rhs.x;
y += rhs.y;
+
+ // `this` is a pointer to the object, on which a method is called.
return *this;
}
@@ -657,7 +661,7 @@ printMessage<10>(); // Prints "Learn C++ faster in only 10 minutes!"
// The standard library provides a few exception types
// (see http://en.cppreference.com/w/cpp/error/exception)
-// but any type can be thrown an as exception
+// but any type can be thrown as an exception
#include <exception>
#include <stdexcept>
@@ -757,7 +761,7 @@ failure:
// things are a little cleaner, but still sub-optimal.
void doSomethingWithAFile(const char* filename)
{
- FILE* fh = fopen(filename, "r"); // Open the file in read mode
+ FILE* fh = fopen(filename, "r"); // Open the file in shared_ptrread mode
if (fh == nullptr)
throw std::runtime_error("Could not open the file.");
@@ -809,7 +813,154 @@ void doSomethingWithAFile(const std::string& filename)
// all automatically destroy their contents when they fall out of scope.
// - Mutexes using lock_guard and unique_lock
-// containers with object keys of non-primitive values (custom classes) require
+
+/////////////////////
+// Smart Pointer
+/////////////////////
+
+// Generally a smart pointer is a class, which wraps a "raw pointer" (usage of "new"
+// respectively malloc/calloc in C). The goal is to be able to
+// manage the lifetime of the object being point to without explicitly deleting
+// the object. The term itself simply describes a set of pointers with the
+// mentioned abstraction.
+// Basically smart pointers should preferred over raw pointers, to prevent
+// risky memory leaks, which happens if you forget to delete the object.
+
+// Usage of a raw pointer:
+Dog* ptr = new Dog();
+ptr->bark();
+delete ptr;
+
+// With the usage of smart pointers you dont have to worry about the deletion
+// of a object anymore.
+// A smart pointer describes a policy, to count the references on the
+// pointer. As matter of fact the objects gets destroyed when the last
+// reference on the object gets destroyed.
+
+// Usage of "std::shared_ptr":
+void foo()
+{
+// Its not longer necessary to delete the Dog.
+std::shared_ptr<Dog> doggo(new Dog());
+doggo->bark();
+}
+
+// Beware of possible circular references!!!
+// There will be always a reference, so it will be never destroyed!
+std::shared_ptr<Dog> doggo_one (new Dog());
+std::shared_ptr<Dog> doggo_two (new Dog());
+doggo_one = doggo_two; // p1 references p2
+doggo_two = doggo_one; // p2 references p1
+
+// As mentioned before there is a set of smart pointers. The way you have to
+// use it, is always the same.
+// This leads us to question, when to use which one?
+// std::unique_ptr - use it when you just want to hold one reference on
+// the same object.
+// std::shared_ptr - use it when you want to hold multiple references on the
+// same object and want to make sure that it´s de-allocated
+// when all refences are gone.
+// std::weak_ptr - use it when you want to hold multiple references from
+// different places for references for which it´s no problem
+// tp de-allocate.
+
+
+/////////////////////
+// Containers
+/////////////////////
+
+// Containers or the Standard Template Library are some predefined templates.
+// They manage the storage space for its elements and provide
+// member functions to access and manipulate them.
+
+// Few containers are as follows:
+
+// Vector (Dynamic array)
+// Allow us to Define the Array or list of objects at run time
+#include <vector>
+string val;
+vector<string> my_vector; // initialize the vector
+cin >> val;
+my_vector.push_back(val); // will push the value of 'val' into vector ("array") my_vector
+my_vector.push_back(val); // will push the value into the vector again (now having two elements)
+
+// To iterate through a vector we have 2 choices:
+// Either classic looping (iterating through the vector from index 0 to its last index):
+for (int i = 0; i < my_vector.size(); i++) {
+ cout << my_vector[i] << endl; // for accessing a vector's element we can use the operator []
+}
+
+// or using an iterator:
+vector<string>::iterator it; // initialize the iterator for vector
+for (it = my_vector.begin(); it != my_vector.end(); ++it) {
+ cout << *it << endl;
+}
+
+// Set
+// Sets are containers that store unique elements following a specific order.
+// Set is a very useful container to store unique values in sorted order
+// without any other functions or code.
+
+#include<set>
+set<int> ST; // Will initialize the set of int data type
+ST.insert(30); // Will insert the value 30 in set ST
+ST.insert(10); // Will insert the value 10 in set ST
+ST.insert(20); // Will insert the value 20 in set ST
+ST.insert(30); // Will insert the value 30 in set ST
+// Now elements of sets are as follows
+// 10 20 30
+
+// To erase an element
+ST.erase(20); // Will erase element with value 20
+// Set ST: 10 30
+// To iterate through Set we use iterators
+set<int>::iterator it;
+for(it=ST.begin();it<ST.end();it++) {
+ cout << *it << endl;
+}
+// Output:
+// 10
+// 30
+
+// To clear the complete container we use Container_name.clear()
+ST.clear();
+cout << ST.size(); // will print the size of set ST
+// Output: 0
+
+// NOTE: for duplicate elements we can use multiset
+// NOTE: For hash sets, use unordered_set. They are more efficient but
+// do not preserve order. unordered_set is available since C++11
+
+// Map
+// Maps store elements formed by a combination of a key value
+// and a mapped value, following a specific order.
+
+#include<map>
+map<char, int> mymap; // Will initialize the map with key as char and value as int
+
+mymap.insert(pair<char,int>('A',1));
+// Will insert value 1 for key A
+mymap.insert(pair<char,int>('Z',26));
+// Will insert value 26 for key Z
+
+// To iterate
+map<char,int>::iterator it;
+for (it=mymap.begin(); it!=mymap.end(); ++it)
+ std::cout << it->first << "->" << it->second << '\n';
+// Output:
+// A->1
+// Z->26
+
+// To find the value corresponding to a key
+it = mymap.find('Z');
+cout << it->second;
+
+// Output: 26
+
+// NOTE: For hash maps, use unordered_map. They are more efficient but do
+// not preserve order. unordered_map is available since C++11.
+
+// Containers with object keys of non-primitive values (custom classes) require
// compare function in the object itself or as a function pointer. Primitives
// have default comparators, but you can override it.
class Foo {
@@ -822,12 +973,13 @@ struct compareFunction {
return a.j < b.j;
}
};
-//this isn't allowed (although it can vary depending on compiler)
-//std::map<Foo, int> fooMap;
+// this isn't allowed (although it can vary depending on compiler)
+// std::map<Foo, int> fooMap;
std::map<Foo, int, compareFunction> fooMap;
fooMap[Foo(1)] = 1;
fooMap.find(Foo(1)); //true
+
///////////////////////////////////////
// Lambda Expressions (C++11 and above)
///////////////////////////////////////
@@ -994,101 +1146,6 @@ cout << get<3>(concatenated_tuple) << "\n"; // prints: 15
cout << get<5>(concatenated_tuple) << "\n"; // prints: 'A'
-/////////////////////
-// Containers
-/////////////////////
-
-// Containers or the Standard Template Library are some predefined templates.
-// They manage the storage space for its elements and provide
-// member functions to access and manipulate them.
-
-// Few containers are as follows:
-
-// Vector (Dynamic array)
-// Allow us to Define the Array or list of objects at run time
-#include <vector>
-string val;
-vector<string> my_vector; // initialize the vector
-cin >> val;
-my_vector.push_back(val); // will push the value of 'val' into vector ("array") my_vector
-my_vector.push_back(val); // will push the value into the vector again (now having two elements)
-
-// To iterate through a vector we have 2 choices:
-// Either classic looping (iterating through the vector from index 0 to its last index):
-for (int i = 0; i < my_vector.size(); i++) {
- cout << my_vector[i] << endl; // for accessing a vector's element we can use the operator []
-}
-
-// or using an iterator:
-vector<string>::iterator it; // initialize the iterator for vector
-for (it = my_vector.begin(); it != my_vector.end(); ++it) {
- cout << *it << endl;
-}
-
-// Set
-// Sets are containers that store unique elements following a specific order.
-// Set is a very useful container to store unique values in sorted order
-// without any other functions or code.
-
-#include<set>
-set<int> ST; // Will initialize the set of int data type
-ST.insert(30); // Will insert the value 30 in set ST
-ST.insert(10); // Will insert the value 10 in set ST
-ST.insert(20); // Will insert the value 20 in set ST
-ST.insert(30); // Will insert the value 30 in set ST
-// Now elements of sets are as follows
-// 10 20 30
-
-// To erase an element
-ST.erase(20); // Will erase element with value 20
-// Set ST: 10 30
-// To iterate through Set we use iterators
-set<int>::iterator it;
-for(it=ST.begin();it<ST.end();it++) {
- cout << *it << endl;
-}
-// Output:
-// 10
-// 30
-
-// To clear the complete container we use Container_name.clear()
-ST.clear();
-cout << ST.size(); // will print the size of set ST
-// Output: 0
-
-// NOTE: for duplicate elements we can use multiset
-// NOTE: For hash sets, use unordered_set. They are more efficient but
-// do not preserve order. unordered_set is available since C++11
-
-// Map
-// Maps store elements formed by a combination of a key value
-// and a mapped value, following a specific order.
-
-#include<map>
-map<char, int> mymap; // Will initialize the map with key as char and value as int
-
-mymap.insert(pair<char,int>('A',1));
-// Will insert value 1 for key A
-mymap.insert(pair<char,int>('Z',26));
-// Will insert value 26 for key Z
-
-// To iterate
-map<char,int>::iterator it;
-for (it=mymap.begin(); it!=mymap.end(); ++it)
- std::cout << it->first << "->" << it->second << '\n';
-// Output:
-// A->1
-// Z->26
-
-// To find the value corresponding to a key
-it = mymap.find('Z');
-cout << it->second;
-
-// Output: 26
-
-// NOTE: For hash maps, use unordered_map. They are more efficient but do
-// not preserve order. unordered_map is available since C++11.
-
///////////////////////////////////
// Logical and Bitwise operators
//////////////////////////////////
diff --git a/chapel.html.markdown b/chapel.html.markdown
index 354cd832..7e8fc41a 100644
--- a/chapel.html.markdown
+++ b/chapel.html.markdown
@@ -708,7 +708,7 @@ class MyClass {
// We also get the compiler-generated initializer, with one argument per field.
// Note that soon there will be no compiler-generated initializer when we
// define any initializer(s) explicitly.
- proc MyClass(val : real) {
+ proc init(val : real) {
this.memberInt = ceil(val): int;
}
diff --git a/cmake.html.markdown b/cmake.html.markdown
index c705beea..32a7b758 100644
--- a/cmake.html.markdown
+++ b/cmake.html.markdown
@@ -1,5 +1,6 @@
---
-language: cmake
+category: tool
+tool: cmake
contributors:
- ["Bruno Alano", "https://github.com/brunoalano"]
filename: CMake
diff --git a/crystal.html.markdown b/crystal.html.markdown
index 8210b443..9fae9da3 100644
--- a/crystal.html.markdown
+++ b/crystal.html.markdown
@@ -25,17 +25,19 @@ true.class #=> Bool
1.class #=> Int32
-# Four signed integer types
-1_i8.class #=> Int8
-1_i16.class #=> Int16
-1_i32.class #=> Int32
-1_i64.class #=> Int64
-
-# Four unsigned integer types
-1_u8.class #=> UInt8
-1_u16.class #=> UInt16
-1_u32.class #=> UInt32
-1_u64.class #=> UInt64
+# Five signed integer types
+1_i8.class #=> Int8
+1_i16.class #=> Int16
+1_i32.class #=> Int32
+1_i64.class #=> Int64
+1_i128.class #=> Int128
+
+# Five unsigned integer types
+1_u8.class #=> UInt8
+1_u16.class #=> UInt16
+1_u32.class #=> UInt32
+1_u64.class #=> UInt64
+1_u128.class #=> UInt128
2147483648.class #=> Int64
9223372036854775808.class #=> UInt64
diff --git a/cs-cz/python3.html.markdown b/cs-cz/python3.html.markdown
index dbaae88b..2cbf52e6 100644
--- a/cs-cz/python3.html.markdown
+++ b/cs-cz/python3.html.markdown
@@ -572,7 +572,7 @@ Clovek.odkaslej_si() # => "*ehm*"
# Lze importovat moduly
import math
-print(math.sqrt(16.0)) # => 4
+print(math.sqrt(16.0)) # => 4.0
# Lze také importovat pouze vybrané funkce z modulu
from math import ceil, floor
diff --git a/csharp.html.markdown b/csharp.html.markdown
index f27adf18..df6544d3 100644
--- a/csharp.html.markdown
+++ b/csharp.html.markdown
@@ -344,7 +344,7 @@ on a new line! ""Wow!"", the masses cried";
tryInt.ToString();
// Casting
- // Cast decimal 15 to a int
+ // Cast decimal 15 to an int
// and then implicitly cast to long
long x = (int) 15M;
}
diff --git a/cypher.html.markdown b/cypher.html.markdown
index acd44733..32868354 100644
--- a/cypher.html.markdown
+++ b/cypher.html.markdown
@@ -50,7 +50,7 @@ Relationships (or Edges)
**Connects two nodes**
`[:KNOWS]`
-It's a *relationship* with the *label* **KNOWS**. It's a *label* as the node's label. It begins with uppercase and use UPPER_SNAKE_CASE.
+It's a *relationship* with the *label* **KNOWS**. It's a *label* as the node's label. It begins with uppercase and use UPPER\_SNAKE\_CASE.
`[k:KNOWS]`
The same *relationship*, referred by the variable **k**, reusable in the query, but it's not necessary.
diff --git a/dart.html.markdown b/dart.html.markdown
index 76857306..07f755f7 100644
--- a/dart.html.markdown
+++ b/dart.html.markdown
@@ -25,42 +25,42 @@ import "dart:math" as DM;
// The fat arrow function declaration has an implicit return for the result of
// the expression.
example1() {
- example1nested1() {
- example1nested2() => print("Example1 nested 1 nested 2");
- example1nested2();
+ nested1() {
+ nested2() => print("Example1 nested 1 nested 2");
+ nested2();
}
- example1nested1();
+ nested1();
}
// Anonymous functions don't include a name.
example2() {
- example2nested1(fn) {
+ nested1(fn) {
fn();
}
- example2nested1(() => print("Example2 nested 1"));
+ nested1(() => print("Example2 nested 1"));
}
// When a function parameter is declared, the declaration can include the
// number of parameters the function takes by specifying the names of the
// parameters it takes.
example3() {
- example3nested1(fn(informSomething)) {
- fn("Example3 nested 1");
+ planA(fn(informSomething)) {
+ fn("Example3 plan A");
}
- example3planB(fn) { // Or don't declare number of parameters.
+ planB(fn) { // Or don't declare number of parameters.
fn("Example3 plan B");
}
- example3nested1((s) => print(s));
- example3planB((s) => print(s));
+ planA((s) => print(s));
+ planB((s) => print(s));
}
// Functions have closure access to outer variables.
var example4Something = "Example4 nested 1";
example4() {
- example4nested1(fn(informSomething)) {
+ nested1(fn(informSomething)) {
fn(example4Something);
}
- example4nested1((s) => print(s));
+ nested1((s) => print(s));
}
// Class declaration with a sayIt method, which also has closure access
@@ -81,9 +81,9 @@ example5() {
// Where classBody can include instance methods and variables, but also
// class methods and variables.
class Example6Class {
- var example6InstanceVariable = "Example6 instance variable";
+ var instanceVariable = "Example6 instance variable";
sayIt() {
- print(example6InstanceVariable);
+ print(instanceVariable);
}
}
example6() {
@@ -92,12 +92,12 @@ example6() {
// Class methods and variables are declared with "static" terms.
class Example7Class {
- static var example7ClassVariable = "Example7 class variable";
+ static var classVariable = "Example7 class variable";
static sayItFromClass() {
- print(example7ClassVariable);
+ print(classVariable);
}
sayItFromInstance() {
- print(example7ClassVariable);
+ print(classVariable);
}
}
example7() {
@@ -110,40 +110,40 @@ example7() {
// or outside of class have to be constant. Strings and numbers are constant
// by default. But arrays and maps are not. They can be made constant by
// declaring them "const".
-var example8A = const ["Example8 const array"],
- example8M = const {"someKey": "Example8 const map"};
+var example8Array = const ["Example8 const array"],
+ example8Map = const {"someKey": "Example8 const map"};
example8() {
- print(example8A[0]);
- print(example8M["someKey"]);
+ print(example8Array[0]);
+ print(example8Map["someKey"]);
}
// Loops in Dart take the form of standard for () {} or while () {} loops,
// slightly more modern for (.. in ..) {}, or functional callbacks with many
// supported features, starting with forEach.
-var example9A = const ["a", "b"];
+var example9Array = const ["a", "b"];
example9() {
- for (var i = 0; i < example9A.length; i++) {
- print("Example9 for loop '${example9A[i]}'");
+ for (var i = 0; i < example9Array.length; i++) {
+ print("Example9 for loop '${example9Array[i]}'");
}
var i = 0;
- while (i < example9A.length) {
- print("Example9 while loop '${example9A[i]}'");
+ while (i < example9Array.length) {
+ print("Example9 while loop '${example9Array[i]}'");
i++;
}
- for (var e in example9A) {
+ for (var e in example9Array) {
print("Example9 for-in loop '${e}'");
}
- example9A.forEach((e) => print("Example9 forEach loop '${e}'"));
+ example9Array.forEach((e) => print("Example9 forEach loop '${e}'"));
}
// To loop over the characters of a string or to extract a substring.
-var example10S = "ab";
+var example10String = "ab";
example10() {
- for (var i = 0; i < example10S.length; i++) {
- print("Example10 String character loop '${example10S[i]}'");
+ for (var i = 0; i < example10String.length; i++) {
+ print("Example10 String character loop '${example10String[i]}'");
}
- for (var i = 0; i < example10S.length; i++) {
- print("Example10 substring loop '${example10S.substring(i, i + 1)}'");
+ for (var i = 0; i < example10String.length; i++) {
+ print("Example10 substring loop '${example10String.substring(i, i + 1)}'");
}
}
@@ -176,23 +176,47 @@ example13() {
match(s2);
}
-// Boolean expressions need to resolve to either true or false, as no
-// implicit conversions are supported.
+// Boolean expressions support implicit conversions and dynamic type
example14() {
- var v = true;
- if (v) {
- print("Example14 value is true");
+ var a = true;
+ if (a) {
+ print("true, a is $a");
}
- v = null;
+ a = null;
+ if (a) {
+ print("true, a is $a");
+ } else {
+ print("false, a is $a"); // runs here
+ }
+
+ // dynamic typed null can be convert to bool
+ var b;// b is dynamic type
+ b = "abc";
try {
- if (v) {
- // Never runs
+ if (b) {
+ print("true, b is $b");
} else {
- // Never runs
+ print("false, b is $b");
}
} catch (e) {
- print("Example14 null value causes an exception: '${e}'");
+ print("error, b is $b"); // this could be run but got error
}
+ b = null;
+ if (b) {
+ print("true, b is $b");
+ } else {
+ print("false, b is $b"); // runs here
+ }
+
+ // statically typed null can not be convert to bool
+ var c = "abc";
+ c = null;
+ // complie failed
+ // if (c) {
+ // print("true, c is $c");
+ // } else {
+ // print("false, c is $c");
+ // }
}
// try/catch/finally and throw are used for exception handling.
diff --git a/de-de/asciidoc-de.html.markdown b/de-de/asciidoc-de.html.markdown
index 24100e0b..e3f64a00 100644
--- a/de-de/asciidoc-de.html.markdown
+++ b/de-de/asciidoc-de.html.markdown
@@ -88,7 +88,7 @@ Abteilungstitel
Listen
-Um eine Aufzählung zu erstellen verwendest du Sternchen.
+Um eine Aufzählung zu erstellen, verwendest du Sternchen.
```
* foo
@@ -96,7 +96,7 @@ Um eine Aufzählung zu erstellen verwendest du Sternchen.
* baz
```
-Um eine nummerierte Liste zu erstellen verwendest du Punkte.
+Um eine nummerierte Liste zu erstellen, verwendest du Punkte.
```
. item 1
@@ -104,7 +104,7 @@ Um eine nummerierte Liste zu erstellen verwendest du Punkte.
. item 3
```
-Um Listen zu verschachteln musst du zusätzliche Sternchen beziehungsweise Punkte hinzufügen. Dies ist bis zu fünf Mal möglich.
+Um Listen zu verschachteln, musst du zusätzliche Sternchen beziehungsweise Punkte hinzufügen. Dies ist bis zu fünf Mal möglich.
```
* foo 1
diff --git a/de-de/c++-de.html.markdown b/de-de/c++-de.html.markdown
new file mode 100644
index 00000000..cef7514b
--- /dev/null
+++ b/de-de/c++-de.html.markdown
@@ -0,0 +1,1157 @@
+---
+language: c++
+filename: learncpp-de.cpp
+contributors:
+ - ["Steven Basart", "http://github.com/xksteven"]
+ - ["Matt Kline", "https://github.com/mrkline"]
+ - ["Geoff Liu", "http://geoffliu.me"]
+ - ["Connor Waters", "http://github.com/connorwaters"]
+ - ["Ankush Goyal", "http://github.com/ankushg07"]
+ - ["Jatin Dhankhar", "https://github.com/jatindhankhar"]
+ - ["Maximilian Sonnenburg", "https://github.com/LamdaLamdaLamda"]
+lang: de-de
+---
+
+C++ ist eine Systemprogrammiersprache die,
+
+[laut dem Begründer Bjarne Stroustrup](http://channel9.msdn.com/Events/Lang-NEXT/Lang-NEXT-2014/Keynote)
+entworfen wurde um,
+
+- "besseres C" zu sein
+- Datenabstraktion zu unterstützen
+- Objektorientierung zu unterstützen
+- generische Programmierung zu unterstützen
+
+Durch seinen Syntax kann sie durchaus schwieriger und komplexer als neuere Sprachen sein.
+
+Sie ist weit verbreitet, weil sie in Maschinen-Code kompiliert, welches direkt vom Prozessor ausgeführt
+werden kann und somit eine strikte Kontrolle über die Hardware bietet und gleichzeitig
+High-Level-Features wie generics, exceptions und Klassen enthält.
+
+Diese Kombination aus Geschwindigkeit und Funktionalität bildet C++ und ist eine der
+weitverbreitesten Programmiersprachen.
+
+```c++
+//////////////////
+// Vergleich zu C
+//////////////////
+
+// C ist fast eine Untermenge von C++ und teilt sich grundsätzlich den
+// Syntax für Variablen Deklarationen, primitiven Typen und Funktionen.
+
+// Wie in C ist der Programmeinsprungpunkt eine Funktion, welche "main" genannt wird und
+// einen Integer als Rückgabetyp besitzt.
+
+// Dieser Wert fungiert als Beendigungsstatus des Programms.
+// Siehe: https://de.wikipedia.org/wiki/Return_Code für weitere Informationen
+int main(int argc, char** argv)
+{
+ // Kommandozeilen Argumente werden genauso wie in C über argc und argv übergeben
+ // argc entspricht der Anzahl von Argumenten und argv ist ein Array von C-style
+ // strings (char*), welche die Argumente repräsentieren.
+ // Das erste Argument ist der Name des Programms, welches aufgerufen wird.
+ // Argc und argv können, wenn nicht benötigt, weg gelassen werden, indem
+ // die Funktionssignatur "int main()" verwendet wird.
+
+ // Ein Rückgabewert von 0 repräsentiert die erfolgreiche Ausführung.
+ return 0;
+}
+
+// C++ unterscheidet sich in einigen Punkten von C:
+
+// In C++ sind Zeichen-Literale char´s
+sizeof('c') == sizeof(char) == 1
+
+// In C sind Zeichen-Literale int´s
+sizeof('c') == sizeof(int)
+
+// C++ verwendet striktes prototyping
+void func(); // Funktion ohne Argumente
+
+// In C
+void func(); // Funktion mit beliebiger Anzahl von Argumenten
+
+// Verwende nullptr, anstatt von NULL!!!
+int* ip = nullptr;
+
+// C standard header sind in C++ verfügbar.
+// C header enden mit .h, während
+// C++ header das Präfix "c" besitzen und kein ".h" Suffix verwenden.
+
+// Die C++ Standard Version:
+#include <cstdio>
+
+// Die C Standard Version:
+#include <stdio.h>
+
+int main()
+{
+ printf("Hello, world!\n");
+ return 0;
+}
+
+///////////////////////
+// Funktionsüberladung
+///////////////////////
+
+// C++ unterstützt Funktionsüberladung
+// Jede Funktion kann unterschiedliche Parameter erhalten.
+void print(char const* myString)
+{
+ printf("String %s\n", myString);
+}
+
+void print(int myInt)
+{
+ printf("My int is %d", myInt);
+}
+
+int main()
+{
+ print("Hello"); // Wird aufgelöst zu "void print(const char*)"
+ print(15); // Wird aufgelöst zu "void print(int)"
+}
+
+/////////////////////////////
+// Standard Funktionsargumente
+/////////////////////////////
+
+// Argumente können per Standard für eine Funktion gesetzt werden,
+// wenn diese beim Aufruf nicht bereitgestellt werden.
+void doSomethingWithInts(int a = 1, int b = 4)
+{
+ // führe Anweisungen mit "int´s" aus.
+}
+
+int main()
+{
+ doSomethingWithInts(); // a = 1, b = 4
+ doSomethingWithInts(20); // a = 20, b = 4
+ doSomethingWithInts(20, 5); // a = 20, b = 5
+}
+
+// Standard-Argumente müssen am Ende der Liste der Argumente stehen.
+void invalidDeclaration(int a = 1, int b) // Fehler!
+{
+}
+
+
+/////////////
+// Namespaces (Namesräume)
+/////////////
+
+// Namespaces stellen einen getrennten Gültigkeitsbereich für Variablen,
+// Funktionen und andere Deklarationen zur Verfügung.
+// Namespaces können geschachtelt werden.
+namespace First
+{
+ namespace Nested
+ {
+ void foo()
+ {
+ printf("This is First::Nested::foo\n");
+ }
+ } // Ende des Namespace "Nested"
+} // Ende des Namespace "First"
+
+namespace Second
+{
+ void foo()
+ {
+ printf("This is Second::foo\n");
+ }
+}
+
+void foo()
+{
+ printf("This is global foo\n");
+}
+
+int main()
+{
+ // Fügt all Symbole aus dem namespace Second in den aktuellen Gültigkeitsbereich (scope).
+ // "foo()" wird nun nicht länger funktionieren, da es nun doppeldeutig ist, ob foo aus
+ // dem namespace foo oder darüberliegenden aufgerufen wird.
+ using namespace Second;
+
+ Second::foo(); // Gibt "This is Second::foo" aus.
+ First::Nested::foo(); // Gibt "This is First::Nested::foo" aus.
+ ::foo(); // Gibt "This is global foo" aus.
+}
+
+///////////////
+// Eingabe/Ausgabe
+///////////////
+
+// C++ verwendet für die Eingabe und Ausgabe streams.
+// cin, cout und cerr repräsentieren stdin, stdout und stderr.
+// << ist der Einfügeoperator und >> ist der Extraktionsoperator.
+
+#include <iostream> // Include für Eingabe/Ausgabe (I/O) streams
+
+using namespace std; // Streams befinden sich im std namespace (standard library)
+
+int main()
+{
+ int myInt;
+
+ // Ausgabe auf stdout (oder Terminal/Bildschirm)
+ cout << "Enter your favorite number:\n";
+
+ // Empfängt Eingabe
+ cin >> myInt;
+
+ // cout kann ebenfalls formatiert werden
+ cout << "Your favorite number is " << myInt << "\n";
+ // Gibt "Your favorite number is <myInt>" aus
+
+ cerr << "Used for error messages";
+}
+
+//////////
+// Zeichenketten (Strings)
+//////////
+
+// Strings in C++ sind Objekte und haben diverse member-functions
+#include <string>
+
+using namespace std; // Strings sind ebenfalls im namespace std (Standard Bibliothek)
+
+string myString = "Hello";
+string myOtherString = " World";
+
+// + wird für das Anhängen von strings verwendet.
+cout << myString + myOtherString; // "Hello World"
+
+cout << myString + " You"; // "Hello You"
+
+// C++ strings sind mutable.
+myString.append(" Dog");
+cout << myString; // "Hello Dog"
+
+
+/////////////
+// Referenzen
+/////////////
+
+// Zusätzlich zu Pointern, wie jene in C.
+// C++ besitzt _Referenzen_.
+// Diese sind Pointer-Typen, welche nicht erneut zugewiesen werden können
+// und nicht Null sein können.
+// Sie besitzen den selben Syntax wie Variablen.
+// Für die Dereferenzierung ist kein * notwendig und
+// & (die Adresse) wird nicht für die Zuweisung verwendet.
+
+using namespace std;
+
+string foo = "I am foo";
+string bar = "I am bar";
+
+
+string& fooRef = foo; // Erzeugt eine Referenz auf foo.
+fooRef += ". Hi!"; // Verändert foo durch die Referenz
+cout << fooRef; // Gibt "I am foo. Hi!" aus.
+
+
+// Weist "fooRef" nicht erneut zu. Dies ist dasselbe, wie "foo = bar" und
+// foo == "I am bar"
+// nach dieser Zeile
+cout << &fooRef << endl; // Gibt die Adresse von foo aus
+fooRef = bar;
+cout << &fooRef << endl; // Gibt ebenfalls die Adresse von foo aus
+cout << fooRef; // Gibt "I am bar" aus
+
+// Die Adresse von fooRef verbleibt die selbe, sie verweist immer noch auf foo
+
+const string& barRef = bar; // Erzeugt konstante Referenz auf bar.
+// Wie in C, können konstante Werte ( und Pointer bzw. Referenzen) nicht verändert werden.
+
+barRef += ". Hi!"; // Fehler: konstante Referenzen können nicht verändert werden.
+
+// Hinweis: bevor wir genauer Referenzen besprechen, schauen wir uns zuerst ein Konzept an,
+// welches als "temporäres Objekt" bezeichnet wird. Gehen wir von folgenden Code aus:
+string tempObjectFun() { ... }
+string retVal = tempObjectFun();
+
+// Was passiert nun in der zweiten Zeile:
+// - ein String Objekt wird von "tempObjectFun" zurückgegeben
+// - ein neuer String wird mit dem zurückgegebenen Objekt als Argument für den Konstruktor erzeugt.
+// - das zurückgegebene Objekt wird zerstört
+// Das zurückgegbene Objekt wird temporäres Objekt genannt. Temporäre Objekte werden erzeugt
+// wann immer eine Funktion ein Objekt zurückgibt. Zerstört werden diese am Ende der Auswertung des Ausdrucks
+// (dies schreibt der Standard vor, aber Compiler sind berechtigt dieses Verhalten zu ändern. Siehe "return value optimization"
+// für Details). Wie in diesem Code:
+foo(bar(tempObjectFun()))
+
+// Nehmen wir an foo und bar existieren. Das Objekt wird von "tempObjectFun" zurückgegeben,
+// wird an bar übergeben und ist zerstört bevor foo aufgerufen wird.
+
+// Zurück zu Referenzen. Die Annahme, dass die "am Ende des Ausdrucks" Regel gültig ist,
+// wenn das temporäre Objekt an eine konstante Referenz gebunden ist, ist der Fall, wenn die Lebensdauer
+// auf den aktuellen Gültigkeitsbereich erweitert wird.
+
+void constReferenceTempObjectFun() {
+ // constRef erhält das temporäre Objekt und ist gültig bis ans Ende der Funktion
+ const string& constRef = tempObjectFun();
+ ...
+}
+
+// Eine andere Art von Referenzen wurde in C++11 eingeführt und ist speziell für
+// temporäre Objekte. Es ist nicht möglich Variablen des Typs zu besitzen, aber
+// Vorrechte bei der Auflösung zu besitzen.
+
+void someFun(string& s) { ... } // Reguläre Referenz
+void someFun(string&& s) { ... } // Referenz auf ein temporäres Objekt
+
+string foo;
+someFun(foo); // Ruft die Funktion mit der regulären Referenz auf
+someFun(tempObjectFun()); // Ruft die Funktion mit der temporären Referenz auf
+
+// Zum Beispiel existieren diese zwei Varianten von Konstruktoren für
+// std::basic_string:
+basic_string(const basic_string& other);
+basic_string(basic_string&& other);
+
+// Nehmen wir an, wir erzeugen einen neuen String eines temporären Objekts (welches später
+// zerstört wird), hierbei existiert ein effizienterer Konstruktor. Dieses Konzept wird
+// als "move semantics" bezeichnet (bewegen eines Objekts in ein anderes in C++).
+
+/////////////////////
+// Enumerations (Aufzählungstypen)
+/////////////////////
+
+// Enums sind eine einfachere Art und Weise einen Wert einer Konstante zu zuweisen.
+// Häufig wird dies verwendet, um den Code lesbarer zu gestalten bzw. zu visualisieren.
+enum ECarTypes
+{
+ Sedan,
+ Hatchback,
+ SUV,
+ Wagon
+};
+
+ECarTypes GetPreferredCarType()
+{
+ return ECarTypes::Hatchback;
+}
+
+// Mit C++11 existiert eine einfache Möglichkeit einem Typ dem Enum zu zuweisen. Dies
+// kann durchaus sinnvoll bei der Serialisierung von Daten sein, oder bei der Konvertierung
+// zwischen Typen bzw. Konstanten.
+enum ECarTypes : uint8_t
+{
+ Sedan, // 0
+ Hatchback, // 1
+ SUV = 254, // 254
+ Hybrid // 255
+};
+
+void WriteByteToFile(uint8_t InputValue)
+{
+ // Serialisierung von "InputValue" in eine Datei
+}
+
+void WritePreferredCarTypeToFile(ECarTypes InputCarType)
+{
+ // Das enum wird implizit zu einem "uint8_t" konvertiert. Bedingt dadurch, dass
+ // es sich um ein "enum" handelt.
+ WriteByteToFile(InputCarType);
+}
+
+// Nicht immer ist es gewünscht, dass enum´s zu einem Integer oder zu einem anderen
+// enum umgewandelt werden. Daher ist es möglich eine enum-Klasse zu erzeugen, welche
+// nicht implizit umgewandelt wird.
+enum class ECarTypes : uint8_t
+{
+ Sedan, // 0
+ Hatchback, // 1
+ SUV = 254, // 254
+ Hybrid // 255
+};
+
+void WriteByteToFile(uint8_t InputValue)
+{
+ // Serialisierung von InputValue in eine Datei
+}
+
+void WritePreferredCarTypeToFile(ECarTypes InputCarType)
+{
+ // Wird nicht kompilieren, da "ECarTypes" ein "uint8_t" ist, da das enum
+ // als "enum class" deklariert wurde!
+ WriteByteToFile(InputCarType);
+}
+
+//////////////////////////////////////////
+// Klassen und objekorientierte Programmierung
+//////////////////////////////////////////
+
+// Erstes Beispiel einer Klasse
+#include <iostream>
+
+// Deklaration einer Klasse.
+// Klassen werden üblicherweise im header (.h oder .hpp) deklariert.
+class Dog
+{
+ // Member Variablen und Funktionen sind private per default (standard).
+ std::string name;
+ int weight;
+
+// Alle nachfolgenden member sind "public" bis
+// "private:" oder "protected:" auftritt.
+public:
+
+ // Standard Konstruktor
+ Dog();
+
+ // Member-Funktionsdeklaration (Implementierung folgt).
+ // Bemerkung: std::string statt der Verwendung von namespace std;
+ // "using namespace" sollte niemals in einem header verwendet werden.
+ void setName(const std::string& dogsName);
+
+ void setWeight(int dogsWeight);
+
+ // Funktionen, die Objekte nicht ändern, sollten mit const deklariert werden.
+ // Funktionen müssen explizit als "virtual" deklariert werden, um in einer
+ // abgeleiteten Klassen überschrieben zu werden.
+ // Aus performance Gründen sind Funktionen nicht per default virtual.
+ virtual void print() const;
+
+ // Funktionen können ebenfalls im class body definiert werden.
+ // Derart definierte Funktionen sind automatisch "inline".
+ void bark() const { std::cout << name << " barks!\n"; }
+
+ // Neben Konstruktoren, bietet C++ Destruktoren.
+ // Diese werden aufgerufen, wenn ein Objekt freigegeben wird oder
+ // seinen Wertebereich verlässt.
+ // Dies ermöglicht mächtige Paradigmen, wie auch RAII.
+ // Destruktoren sollten virtual sein, wenn eine Klasse von ihr
+ // abgeleitet wird. Ist dieser nicht virtual, dann wird der
+ // Destruktor der abgeleiteten Klasse nicht aufgerufen, insofern
+ // das Objekt durch eine Referenz/Pointer der Basisklasse entfernt wird.
+ virtual ~Dog();
+
+}; // Ein Semikolon schließt die Definition der Klasse ab.
+
+// Klassen-Member-Funktionen sind üblicherweise in der .cpp Datei implementiert.
+Dog::Dog()
+{
+ std::cout << "A dog has been constructed\n";
+}
+
+// Objekte sollten als Referenz übergeben werden und wenn diese nicht
+// verändert werden sollen, sollte das Objekt als const Referenz übergeben werden.
+void Dog::setName(const std::string& dogsName)
+{
+ name = dogsName;
+}
+
+void Dog::setWeight(int dogsWeight)
+{
+ weight = dogsWeight;
+}
+
+// "Virtual" wird nur bei der Deklaration benötigt und nicht bei der Definition.
+void Dog::print() const
+{
+ std::cout << "Dog is " << name << " and weighs " << weight << "kg\n";
+}
+
+Dog::~Dog()
+{
+ std::cout << "Goodbye " << name << "\n";
+}
+
+int main()
+{
+ Dog myDog; // Ausgabe: "A dog has been constructed"
+ myDog.setName("Barkley");
+ myDog.setWeight(10);
+ myDog.print(); // Ausgabe: "Dog is Barkley and weighs 10 kg"
+ return 0;
+} // Ausgabe: "Goodbye Barkley"
+
+// Diese Klasse erbt alles was public bzw. protected ist von der Dog-Klasse
+// und darüber hinaus auch private Methoden/Attribute, jedoch kann auf diese
+// nicht direkt zugegriffen werden. Lediglich über public/procted getter/setter.
+class OwnedDog : public Dog {
+
+public:
+ void setOwner(const std::string& dogsOwner);
+
+ // Überschreibt das Verhalten der "print" Funktion für alle "OwnedDogs".
+ // Siehe: http://en.wikipedia.org/wiki/Polymorphism_(computer_science)#Subtyping
+ // für eine grundlegende Einführung in "Subtype Polymorphismus".
+ // Das "override" Schlüsselwort ist optional, aber stellt sicher, dass die
+ // Methode der Basisklasse tatsächlich überschrieben wurde.
+ void print() const override;
+
+private:
+ std::string owner;
+};
+
+// Die zugehörige .cpp Datei
+void OwnedDog::setOwner(const std::string& dogsOwner)
+{
+ owner = dogsOwner;
+}
+
+void OwnedDog::print() const
+{
+ Dog::print(); // Ruft die "print" Funktion der Basisklasse auf.
+ std::cout << "Dog is owned by " << owner << "\n";
+ // Ausgaben: "Dog is <name> and weights <weight>"
+ // "Dog is owned by <owner>"
+}
+
+//////////////////////////////////////////
+// Initialisierung und Operatorüberladung
+//////////////////////////////////////////
+
+// In C++ können Operatoren wie: +, -, *, / etc. überladen werden.
+// Dies wird umgesetzt, indem eine entsprechende Funktion definiert wird,
+// welche immer dann aufgerufen wird, sobald der Operator verwendet wird.
+#include <iostream>
+using namespace std;
+
+class Point
+{
+public:
+ // Member Variablen können mit einem default Wert initialisiert werden.
+ double x = 0;
+ double y = 0;
+
+ // Definition des Standard Konstruktor, welcher nichts tut
+ // außer den Punkt auf den default Wert (0,0) zu setzen.
+ Point() { };
+
+ // Die nachfolgende Syntax ist bekannt als "initialization list"
+ // und ist eine gängige Art Klassen-Member zu initialisieren.
+ Point (double a, double b) :
+ x(a),
+ y(b)
+ { /* Außschließliche Initialisierung der Werte */ }
+
+ // Überladung des "+" Operator.
+ Point operator+(const Point& rhs) const;
+
+ // Überladung des "+=" Operator
+ Point& operator+=(const Point& rhs);
+
+ // Sinnhaft wäre es an dieser Stelle den "-" und "-=" Operator
+ // ebenfalls zu überladen.
+};
+
+Point Point::operator+(const Point& rhs) const
+{
+ // Erzeugung eines neuen Punkts, welcher die Summe aus sich
+ // selbst und "rhs" bildet
+ return Point(x + rhs.x, y + rhs.y);
+}
+
+Point& Point::operator+=(const Point& rhs)
+{
+ x += rhs.x;
+ y += rhs.y;
+ return *this;
+}
+
+int main ()
+{
+ Point up (0,1);
+ Point right (1,0);
+
+ // Ruft den + Operator mit den entsprechenden Parametern auf.
+ Point result = up + right;
+ // Ausgabe: "Result is upright (1,1)"
+ cout << "Result is upright (" << result.x << ',' << result.y << ")\n";
+ return 0;
+}
+
+/////////////////////
+// Templates
+/////////////////////
+
+// Templates in C++ werden in erster Linie dafür verwendet generisch zu programmieren.
+// Sie unterstützen explizite und partielle Spezialisierung und darüber hinaus können
+// sie für funktionale Klassen verwendet werden.
+// Tatsächlich bilden templates die Turing-Vollständigkeit
+// (universelle Programmierbarkeit) ab.
+
+
+// Zu Beginn ein einführendes Beispiel der generischen Programmierung.
+// Die Definition einer Klasse bzw. Funktion, welche mit dem Typ T parametriert wird.
+template<class T>
+class Box
+{
+public:
+ // T repräsentiert an dieser Stelle einen beliebigen Typen.
+ void insert(const T&) { ... }
+};
+
+// Während der Kompilierung generiert der Compiler Kopien für jedes template, wobei
+// hierbei die Parameter substituiert werden. Somit muss bei jedem Aufruf die gesamte
+// Definition der Klasse zur Verfügung stehen. Aus diesem Grund wird ein Template
+// komplett im header definiert.
+
+// Erzeugung einer Template-Klasse auf dem stack:
+Box<int> intBox;
+
+// eine der zu erwartenden Verwendungen:
+intBox.insert(123);
+
+// Verschachtelungen von Templates sind möglich.
+Box<Box<int> > boxOfBox;
+boxOfBox.insert(intBox);
+
+// Bis C++11 war es erforderlich ein Leerzeichen zwischen '>' einzufügen,
+// andernfalls wurde es als '>>' geparsed (right shift).
+
+// Manchmal ist folgende Notation anzutreffen:
+// template<typename T>
+// Das 'class' Schlüsselwort und das 'typename' Schlüsselwort
+// sind fast identisch hinsichtlich der Funktionalität. Weitere
+// Informationen auf: http://en.wikipedia.org/wiki/Typename
+
+// Eine template-Funktion:
+template<class T>
+void barkThreeTimes(const T& input)
+{
+ input.bark();
+ input.bark();
+ input.bark();
+}
+
+// Hierbei ist zu beachten, dass an dieser Stelle nichts über den Typen des Parameters
+// definiert wurde. Der Kompiler wird bei jedem Aufruf bzw. jeder Erzeugung den Typen
+// prüfen. Somit funktioniert die zuvor definierte Funktion für jeden Typ 'T', die die
+// const Methode 'bark' implementiert hat.
+
+Dog fluffy;
+fluffy.setName("Fluffy")
+barkThreeTimes(fluffy); // Gibt "Fluffy barks" dreimal aus.
+
+// Template Parameter müssen keine Klassen sein.
+template<int Y>
+void printMessage()
+{
+ cout << "Learn C++ in " << Y << " minutes!" << endl;
+}
+
+// Des Weiteren können templates aus Effizienzgründen genauer spezifiziert werden.
+// Selbstverständlich sind reale-Problemen, welche genauer spezifiziert werden nicht
+// derart trivial. Auch wenn alle Parameter explizit definiert wurden, muss die
+// Funktion oder Klasse als template deklariert werden.
+template<>
+void printMessage<10>()
+{
+ cout << "Learn C++ faster in only 10 minutes!" << endl;
+}
+
+printMessage<20>(); // Gibt "Learn C++ in 20 minutes!" aus.
+printMessage<10>(); // Gibt "Learn C++ faster in only 10 minutes!" aus.
+
+
+/////////////////////
+// Ausnahme Behandlungen (Exception-Handling)
+/////////////////////
+
+// Die Standard Bibliothek bietet einige exceptions.
+// Siehe: http://en.cppreference.com/w/cpp/error/exception.
+// Grundsätzlich können alle Typen als exception geworfen werden.
+#include <exception>
+#include <stdexcept>
+
+// Alle exceptions, die in dem "try" Block geworfen werden, können mittels
+// "catch" abgefangen werden.
+try
+{
+ // exceptions sollten nicht auf dem heap mithilfe
+ // von "new" allokiert werden.
+ throw std::runtime_error("A problem occurred");
+}
+
+// Exceptions sollten als const Referenz abgefangen werden
+// insofern diese Objekte sind.
+catch (const std::exception& ex)
+{
+ std::cout << ex.what();
+}
+
+// Abfangen aller Exceptions, welche zuvor nicht abgefangen wurden.
+catch (...)
+{
+ std::cout << "Unknown exception caught";
+ throw; // Erneutes werfen der exception
+}
+
+///////
+// RAII
+///////
+
+// RAII steht für "Resource Acquisition Is Initialization".
+// Oft wird dies als eines der wichtigsten Paradigmen in C++ betrachtet.
+// RAII beschreibt das Konzept, dass der Konstruktor für ein Objekt
+// die Ressourcen akquiriert und der Destruktor diese freigibt.
+
+// Zum Verständnis, warum dies sinnvoll ist, nachfolgend
+// ein einführendes Beispiel:
+void doSomethingWithAFile(const char* filename)
+{
+ // Wir nehmen an, dass nichts schiefgehen wird.
+ FILE* fh = fopen(filename, "r"); // Öffnen der Datei im read-mode.
+
+ doSomethingWithTheFile(fh);
+ doSomethingElseWithIt(fh);
+
+ fclose(fh); // Schließen des file-handle.
+}
+
+// Unglücklicherweise ist die Fehlerbehandlung äußerst kompliziert.
+// Sollte fopen fehlschlagen und "doSomethingWithTheFile" bzw.
+// "doSomethingElseWithIt", geben diese einen Fehlercode zurück.
+// (Exceptions sind eine bevorzugte Möglichkeit Fehler abzufangen
+// , allerdings bei einigen Programmierern, besonders solchen die einen C
+// background besitzen, ein unbeliebtes Mittel zur Fehlerbehandlung).
+// Nun müssen wir jeden Aufruf auf mögliche auftretende Fehler überprüfen.
+bool doSomethingWithAFile(const char* filename)
+{
+ FILE* fh = fopen(filename, "r"); // Öffnet die Datei im read-mode
+ if (fh == nullptr) // Der Pointer ist bei einem Fehler NULL .
+ return false; // Benachrichtigt den Aufrufer über den Fehler.
+
+ // Wir nehmen an, dass jede Funktion false zurückgibt, in einem Fehlerfall
+ if (!doSomethingWithTheFile(fh))
+ {
+ fclose(fh); // File handle schließen.
+ return false; // Fehler "melden".
+ }
+
+ if (!doSomethingElseWithIt(fh))
+ {
+ fclose(fh); // File handle schließen.
+ return false; // Fehler "melden".
+ }
+
+ fclose(fh); // File handle schließen.
+ return true; // Erfolg "melden".
+}
+
+// C-Programmierer handhaben dies häufig durch goto-Anweisungen:
+bool doSomethingWithAFile(const char* filename)
+{
+ FILE* fh = fopen(filename, "r");
+ if (fh == nullptr)
+ return false;
+
+ if (!doSomethingWithTheFile(fh))
+ goto failure;
+
+ if (!doSomethingElseWithIt(fh))
+ goto failure;
+
+ fclose(fh); // File handle schließen.
+ return true; // Erfolg "melden".
+
+failure:
+ fclose(fh);
+ return false; // Fehler "melden".
+}
+
+// Insofern Funktionen Fehler durch exceptions indizieren,
+// ist dies "sauberer", aber immer noch suboptimal.
+void doSomethingWithAFile(const char* filename)
+{
+ FILE* fh = fopen(filename, "r"); // Öffnet die Datei im read-mode
+ if (fh == nullptr)
+ throw std::runtime_error("Could not open the file.");
+
+ try
+ {
+ doSomethingWithTheFile(fh);
+ doSomethingElseWithIt(fh);
+ }
+ catch (...)
+ {
+ // Im Fehlerfall sollte sichergestellt sein, dass die
+ // Datei geschlossen wird.
+ fclose(fh);
+ throw; // Erneutes werfen der exception
+ }
+
+ fclose(fh); // Schließen der Datei
+}
+
+// Folgendes ist mit der C++ file stream Klasse (fstream) zu vergleichen.
+// fstream verwendet den Destruktor, um die Datei zu schließen.
+// Der obige Destruktor wird automatisch aufgerufen, sobald das Objekt
+// den Gültigkeitsbereich verlässt.
+void doSomethingWithAFile(const std::string& filename)
+{
+ // ifstream entspricht der Kurzform von "input file stream".
+ std::ifstream fh(filename); // Öffnen der Datei
+
+ doSomethingWithTheFile(fh);
+ doSomethingElseWithIt(fh);
+
+} // Die Datei wird automatisch vom Destruktor geschlossen.
+
+// Diese Vorgehensweise bietet massive Vorteile:
+// 1. Egal was passiert, die Ressource (das Datei-Handle) wird aufgelöst,
+// insofern der Destruktor korrekt beschrieben wurde. Es ist möglich
+// zu vergessen das Datei-Handle zu schließen, was zu einem "leak" der
+// entsprechenden Ressource führt.
+// 2. Der Code selbst ist wesentlich "sauberer".
+// Der Destruktor wird das Datei-Handle im Hintergrund schließen und der
+// Programmierer muss sich darum keinerlei Sorgen machen.
+// 3. Der Code ist "exception sicher".
+// Egal wo die exception geworfen wird, das Aufräumen wird definitiv vollzogen.
+
+// Der gesamte idiomatische C++ Code verwendet RAII für alle Ressourcen.
+// Weitere Beispiele:
+// - Speicher verwenden "unique_ptr" und "shared_ptr".
+// - Container - verkettete Listen (linked list), vector (selbst organisierende
+// Arrays), hash maps, etc., entfernen deren Inhalt, wenn diese außerhalb des
+// Gültigkeitsbereichs laufen.
+// - Mutex´s verwenden lock_guard und unique_lock.
+
+/////////////////////
+// Container
+/////////////////////
+
+// Die Container der Standard template Bibliothek beinhaltet einige vordefinierter templates.
+// Diese verwalten die Speicherbereiche für die eigenen Elemente und stellen Member-Funktionen
+// für den Zugriff und die Maniplulation bereit.
+
+// Beispielhafte Container:
+
+// Vector (dynamisches array)
+// Erlaubt das Definieren von Arrays oder Listen zur Laufzeit
+#include <vector>
+string val;
+vector<string> my_vector; // Initialisierung des Vectors.
+cin >> val;
+my_vector.push_back(val); // Fügt den Wert "val" zum Vektor "my_vector" hinzu.
+my_vector.push_back(val); // Fügt den Wert "val" zum Vektor "my_vector" hinzu (nun zwei Elemente).
+
+// Für die Iteration über Vektoren stehen zwei Methodiken zu Verfügung:
+// Entweder die klassische Iteration über den Index:
+for (int i = 0; i < my_vector.size(); i++)
+{
+ cout << my_vector[i] << endl; // Zugriff auf die Elemente des Vektors über den [] Operator
+}
+
+// Oder die Verwendung von Iteratoren:
+vector<string>::iterator it; // Initialisierng des Iterators.
+for (it = my_vector.begin(); it != my_vector.end(); ++it)
+{
+ cout << *it << endl;
+}
+
+// Set (Mengen)
+// Sets sind Container, welche einzigartige Elemente beinhalten die einer
+// spezifischen Ordnung folgen.
+
+#include<set>
+set<int> ST; // Initialisierung des Sets mit einem Integer Datentyp.
+ST.insert(30); // Einfügen des Werts 30 in das Set ST
+ST.insert(10); // Einfügen des Werts 10 in das Set ST
+ST.insert(20); // Einfügen des Werts 20 in das Set ST
+ST.insert(30); // Einfügen des Werts 30 in das Set ST
+// Folgende Elemente befinden sich nun in dem Set:
+// 10 20 30
+
+// Entfernen eines Elements:
+ST.erase(20);
+
+// Set ST: 10 30
+// Für das iterieren verwenden wir Iteratoren:
+set<int>::iterator it;
+
+for(it=ST.begin();it<ST.end();it++)
+{
+ cout << *it << endl;
+}
+
+// Ausgabe:
+// 10
+// 30
+
+// Zum leeren des gesamten Container wird die Methode
+// Container._name.clear() verwendet.
+ST.clear();
+cout << ST.size(); // Ausgabe der Set-Größe
+
+// Ausgabe: 0
+
+// Bemerkung: für mehrdeutige Elemente werden multisets verwendet.
+// Für hash-Sets sollten unordered_set´s verwendet werden, da diese
+// wesentlich effizienter sind, allerdings keiner Ordnung folgen.
+// Verfügbar sind diese Features ab C++11.
+
+// Map
+// Maps speichern Elemente, welche einer Kombination aus "Key"
+// und "Value" folgen.
+
+#include<map>
+map<char, int> mymap; // Initialisierung der Map: char -> Key, int -> Value.
+
+mymap.insert(pair<char,int>('A',1)); // Einfügen des Werts "1" für den Key "A".
+
+mymap.insert(pair<char,int>('Z',26)); // Einfügen des Werts "26" für den Key "Z".
+
+// Das Iterieren über Maps:
+map<char,int>::iterator it;
+for (it=mymap.begin(); it!=mymap.end(); ++it)
+ std::cout << it->first << "->" << it->second << '\n';
+
+// Ausgabe:
+// A->1
+// Z->26
+
+// Für das Finden des dazugehörigen Value des Keys.
+it = mymap.find('Z');
+cout << it->second;
+
+// Ausabe: 26
+
+// Bemerkung: für "hash maps" sollten die "unordered_map´s" verwendet werden. Diese
+// sind effizienter und benötigen keine Reihenfolge. "unordered_maps" sind ab
+// C++11 verfügbar.
+
+// Container für nicht-primitive Datentypen benötigen Vergleichsfunktionen im Objekt selbst,
+// oder als Funktionspointer. Primitive Datentypen besitzen default-Vergleichsfunktionen.
+// Allerdings können diese überschrieben werden.
+class Foo
+{
+public:
+ int j;
+ Foo(int a) : j(a) {}
+};
+
+struct compareFunction
+{
+ bool operator()(const Foo& a, const Foo& b) const
+ {
+ return a.j < b.j;
+ }
+};
+
+// Folgender Code ist nicht valide, könnte aber von einigen Compilern
+// als valide angesehen werden:
+// std::map<Foo, int> fooMap;
+std::map<Foo, int, compareFunction> fooMap;
+fooMap[Foo(1)] = 1;
+fooMap.find(Foo(1)); // Wahr
+
+
+///////////////////////////////////////
+// Lambda Ausdrücke (C++11 und höher)
+///////////////////////////////////////
+
+// Lambdas sind eine gängige Methodik um anonyme Funktionen an dem
+// Ort der Verwendung zu definieren. Darüber hinaus auch bei der
+// Verwendung von Funktionen als Argument einer Funktion.
+
+// Nehmen wir an es soll ein Vektor von "pairs" (Paaren) mithilfe
+// des zweiten Werts des "pairs" sortiert werden.
+
+vector<pair<int, int> > tester;
+tester.push_back(make_pair(3, 6));
+tester.push_back(make_pair(1, 9));
+tester.push_back(make_pair(5, 0));
+
+// Übergabe des Lambda-Ausdrucks als drittes Argument für die nachfolgende Sortierfunktion.
+sort(tester.begin(), tester.end(), [](const pair<int, int>& lhs, const pair<int, int>& rhs)
+{
+ return lhs.second < rhs.second;
+});
+
+// Beachte den Syntax von Lambda-Ausdrücken.
+// Die [] im Lambda Ausdruck werden für die Variablen verwendet.
+// Diese so genannte "capture list" definiert, was außerhalb des Lambdas,
+// innerhalb der Funktion verfügbar sein soll und in welcher Form.
+// Dies kann folgendes sein:
+// 1. ein Wert [x]
+// 2. eine Referenz [&x]
+// 3. eine beliebige Variable, welche sich im Gültigkeitsbereich durch
+// die Referenz [&] befindet.
+// 4. wie bei 3. aber mithilfe des Werts [=]
+// Beispiel:
+
+vector<int> dog_ids;
+
+for(int i = 0; i < 3; i++)
+{
+ dog_ids.push_back(i);
+}
+
+int weight[3] = {30, 50, 10};
+
+// Nehmen wir an wir möchten die "dog_ids" gemäß des Gewichts des Hundes sortieren.
+// So sollten sich die "dog_ids" wie folgt verhalten: [2, 0, 1]
+
+// Hier werden Lambdas praktisch:
+sort(dog_ids.begin(), dog_ids.end(), [&weight](const int &lhs, const int &rhs)
+{
+ return weight[lhs] < weight[rhs];
+});
+
+
+// Weiterführender Link über Lambda-Ausdrücke:
+// http://stackoverflow.com/questions/7627098/what-is-a-lambda-expression-in-c11
+
+///////////////////////////////
+// Range For (C++11 und höher)
+///////////////////////////////
+
+// Range-For Schleifen können verwendet werden, um über Container zu iterieren.
+int arr[] = {1, 10, 3};
+
+for(int elem: arr)
+{
+ cout << elem << endl;
+}
+
+// Insofern "auto" verwendet wird, muss der Typ nicht weiter beachtet werden.
+for(auto elem: arr)
+{
+ // Anweisungen ...
+}
+
+/////////////////////
+// Weiteres:
+/////////////////////
+
+// Einige Aspekte von C++ sind für Neueinsteiger häufig überraschend (aber auch für
+// C++ Veteranen).
+// Der nachfolgende Abschnitt ist leider nicht vollständig:
+// C++ ist eine der Sprachen, bei der es ein leichtes ist sich selbst ins Bein zu schießen.
+
+// Private-Methoden können überschrieben werden
+class Foo
+{
+ virtual void bar();
+};
+
+class FooSub : public Foo
+{
+ virtual void bar(); // Überschreibt Foo::bar!
+};
+
+// 0 == false == NULL
+bool* pt = new bool;
+*pt = 0; // Setzt den Wert des Pointers 'pt' auf false.
+pt = 0; // Setzt 'pt' auf den "null-pointer". Keine Compiler-Warnung.
+
+// nullptr sollte dieses Problem nicht lösen:
+int* pt2 = new int;
+*pt2 = nullptr; // Kompiliert nicht.
+pt2 = nullptr; // Setzt pt2 auf null.
+
+// Eine Ausnahme bilden bool´s.
+// Dies erlaubt es "null-pointer" zu testen: if(!ptr)
+// Die Konsequenz ist jedoch, dass dem nullptr ein bool zugewiesen werden kann.
+*pt = nullptr; // Kompiliert auch, wenn '*pt' ein bool ist!
+
+// '=' != '=' != '='!
+// Ruft Foo::Foo(const Foo&) auf, oder den Kopierkonstruktor
+Foo f2;
+Foo f1 = f2;
+
+// Ruft Foo::Foo(const Foo&) auf, aber kopiert lediglich den "Foo" Teil von
+// "fooSub". Alle zusätzlichen Member werden verworfen. Diese eigenartige Verhalten
+// wird auch "object slicing" genannt.
+FooSub fooSub;
+Foo f1 = fooSub;
+
+// Ruft Foo::operator=(Foo&) oder eine andere Variante auf.
+Foo f1;
+f1 = f2;
+
+///////////////////////////////////////
+// Tuple (C++11 und höher)
+///////////////////////////////////////
+
+#include<tuple>
+
+// Konzeptionell sind Tuple´s alten Datenstrukturen sehr ähnlich, allerdings haben diese keine
+// bezeichneten Daten-Member, sondern werden durch die Reihenfolge angesprochen.
+
+// Erstellen des Tuples und das Einfügen eines Werts.
+auto first = make_tuple(10, 'A');
+const int maxN = 1e9;
+const int maxL = 15;
+auto second = make_tuple(maxN, maxL);
+
+// Ausgabe der Elemente des "first" Tuple.
+cout << get<0>(first) << " " << get<1>(first) << "\n"; // Ausgabe : 10 A
+
+// Ausgabe der Elemente des "second" Tuple.
+cout << get<0>(second) << " " << get<1>(second) << "\n"; // Ausgabe: 1000000000 15
+
+int first_int;
+char first_char;
+tie(first_int, first_char) = first;
+cout << first_int << " " << first_char << "\n"; // Ausgabe : 10 A
+
+// Tuple können auch wie folgt erzeugt werden:
+
+tuple<int, char, double> third(11, 'A', 3.14141);
+// tuple_size gibt die Anzahl der Elemente in einem Tuple zurück.
+// Als "constexpr".
+
+cout << tuple_size<decltype(third)>::value << "\n"; // prints: 3
+
+// tuple_cat fügt die Elemente eines Tuples aneinander (in der selben Reihenfolge).
+
+auto concatenated_tuple = tuple_cat(first, second, third);
+// concatenated_tuple wird zu = (10, 'A', 1e9, 15, 11, 'A', 3.14141)
+
+cout << get<0>(concatenated_tuple) << "\n"; // Ausgabe: 10
+cout << get<3>(concatenated_tuple) << "\n"; // Ausgabe: 15
+cout << get<5>(concatenated_tuple) << "\n"; // Ausgabe: 'A'
+
+
+///////////////////////////////////
+// Logische- und Bitoperatoren
+//////////////////////////////////
+
+// Die meisten Operatoren in C++ entsprechen denen aus anderen Sprachen
+
+// Logische Operatoren.
+// C++ verwendet so genannte "Short-circuit" Evaluierung für Boolean-Ausdrücke.
+// Das zweite Argument wird ausgeführt bzw. evaluiert, wenn das erste Argument genügt,
+// um den Ausdruck zu bestimmen.
+
+true && false // Führt **logisches und** aus.
+true || false // Führt **logisches oder** aus.
+! true // Führt **logisches nicht** aus.
+
+// Anstelle von Symbolen können auch Schlüsselwörter verwendet werden.
+true and false // Führt **logisches und** aus.
+true or false // Führt **logisches oder** aus.
+not true // Führt **logisches nicht** aus.
+
+// Bitoperationen
+
+// **<<** Links-Shift
+// **>>** Rechts-Shift
+
+~4 // Führt bitweises nicht aus.
+4 | 3 // Führt bitweises oder aus.
+4 & 3 // Führt bitweises und aus.
+4 ^ 3 // Führt bitweises xor aus.
+
+// Gleichwertige Schlüsselwörter:
+compl 4 // Führt bitweises nicht aus.
+4 bitor 3 // Führt bitweises oder aus.
+4 bitand 3 // Führt bitweises und aus.
+4 xor 3 // Führt bitweises xor aus.
+
+
+```
+Weiterführende Literatur:
+
+* Aktuelle Sprachen-Referenz [CPP Reference](http://cppreference.com/w/cpp).
+* Zusätzliches: [CPlusPlus](http://cplusplus.com).
+* Grundlagen Tutorial: [TheChernoProject - C++](https://www.youtube.com/playlist?list=PLlrATfBNZ98dudnM48yfGUldqGD0S4FFb).
diff --git a/de-de/git-de.html.markdown b/de-de/git-de.html.markdown
index 7c68d785..0896f513 100644
--- a/de-de/git-de.html.markdown
+++ b/de-de/git-de.html.markdown
@@ -49,7 +49,7 @@ Ein Repository besteht in Git aus dem .git-Verzeichnis und dem Arbeitsverzeichni
### .git-Verzeichnis (Teil des Repositorys)
-Das .git-Verzeichnis enthält alle Einstellung, Logs, Branches, den HEAD und mehr.
+Das .git-Verzeichnis enthält alle Einstellungen, Logs, Branches, den HEAD und mehr.
[Ausführliche Übersicht](http://gitready.com/advanced/2009/03/23/whats-inside-your-git-directory.html)
### Arbeitsverzeichnis (Teil des Repositorys)
diff --git a/de-de/hq9+-de.html.markdown b/de-de/hq9+-de.html.markdown
index b343201a..841de5bb 100644
--- a/de-de/hq9+-de.html.markdown
+++ b/de-de/hq9+-de.html.markdown
@@ -1,6 +1,6 @@
---
language: HQ9+
-filename: hq9+.html
+filename: hq9+-de.html
contributors:
- ["Alexey Nazaroff", "https://github.com/rogaven"]
translators:
diff --git a/de-de/make-de.html.markdown b/de-de/make-de.html.markdown
index bc5c7bcb..cf90dc29 100644
--- a/de-de/make-de.html.markdown
+++ b/de-de/make-de.html.markdown
@@ -1,5 +1,6 @@
---
-language: make
+category: tool
+tool: make
contributors:
- ["Robert Steed", "https://github.com/robochat"]
- ["Stephan Fuhrmann", "https://github.com/sfuhrm"]
diff --git a/de-de/markdown-de.html.markdown b/de-de/markdown-de.html.markdown
index cccf5e68..729e883c 100644
--- a/de-de/markdown-de.html.markdown
+++ b/de-de/markdown-de.html.markdown
@@ -144,7 +144,7 @@ indem du eine Zeile mit vier Leerzeichen oder einem Tabulator einrückst -->
puts item
end
-<!-- Innerhalb normalen Texts kannst du Code mit Backticks ` auszeichnen -->
+<!-- Innerhalb normalen Texts kannst du Code mit Backticks \` auszeichnen -->
Hermann hatte nicht die leiseste Ahnung, was dieses `go_to()` bedeuten könnte!
diff --git a/de-de/opencv-de.html.markdown b/de-de/opencv-de.html.markdown
index 2d9a2c4e..223e6cd8 100644
--- a/de-de/opencv-de.html.markdown
+++ b/de-de/opencv-de.html.markdown
@@ -1,7 +1,7 @@
---
category: tool
tool: OpenCV
-filename: learnopencv.py
+filename: learnopencv-de.py
contributors:
- ["Yogesh Ojha", "http://github.com/yogeshojha"]
translators:
diff --git a/de-de/paren-de.html.markdown b/de-de/paren-de.html.markdown
index 0d914c05..641e226e 100644
--- a/de-de/paren-de.html.markdown
+++ b/de-de/paren-de.html.markdown
@@ -1,7 +1,7 @@
---
language: Paren
-filename: learnparen.paren
+filename: learnparen-de.paren
contributors:
- ["KIM Taegyoon", "https://github.com/kimtg"]
- ["Claudson Martins", "https://github.com/claudsonm"]
diff --git a/de-de/python-de.html.markdown b/de-de/python-de.html.markdown
index ae29d6f9..ee77683e 100644
--- a/de-de/python-de.html.markdown
+++ b/de-de/python-de.html.markdown
@@ -386,25 +386,73 @@ filter(lambda x: x > 5, [3, 4, 5, 6, 7]) #=> [6, 7]
[add_10(i) for i in [1, 2, 3]] #=> [11, 12, 13]
[x for x in [3, 4, 5, 6, 7] if x > 5] #=> [6, 7]
+
####################################################
-## 5. Klassen
+## 5. Module
####################################################
-# Wir bilden die Unterklasse eines Objekts, um Klassen zu erhalten.
+# Wir können Module importieren
+import math
+print math.sqrt(16) #=> 4.0
+
+# Wir können auch nur spezielle Funktionen eines Moduls importieren
+from math import ceil, floor
+print ceil(3.7) #=> 4.0
+print floor(3.7) #=> 3.0
+
+# Wir können auch alle Funktionen eines Moduls importieren
+# Warnung: Dies wird nicht empfohlen
+from math import *
+
+# Wir können Modulnamen abkürzen
+import math as m
+math.sqrt(16) == m.sqrt(16) #=> True
+
+# Module sind in Python nur gewöhnliche Dateien. Wir
+# können unsere eigenen schreiben und importieren. Der Name des
+# Moduls ist der Dateiname.
+
+# Wir können herausfinden, welche Funktionen und Attribute in einem
+# Modul definiert sind.
+import math
+dir(math)
+
+# Wenn Sie ein Python-Skript namens math.py im selben Ordner
+# wie Ihr aktuelles Skript haben, wird die Datei math.py
+# anstelle des integrierten Python-Moduls geladen.
+# Dies geschieht, weil der lokale Ordner Vorrang
+# vor den in Python integrierten Bibliotheken hat.
+
+
+####################################################
+## 6. Klassen
+####################################################
+
+# Wir verwenden das Schlüsselwort "class" um eine Klasse zu erzeugen.
class Human(object):
# Ein Klassenattribut. Es wird von allen Instanzen einer Klasse geteilt
species = "H. sapiens"
- # Ein simpler Konstruktor
+ # Ein simpler Konstruktor, wird aufgerufen, wenn diese Klasse instanziiert wird.
+ # Beachten Sie, dass die doppelten vorangestellten und nachgestellten
+ # Unterstriche Objekte oder Attribute bezeichnen, die von Python verwendet werden,
+ # aber in benutzergesteuerten Namespaces leben.
+ # Methoden (oder Objekte oder Attribute) wie: __init__, __str__, __repr__ usw.
+ # werden als Sondermethoden (oder manchmal als Dundermethoden bezeichnet) bezeichnet.
+ # Sie sollten solche Namen nicht selbst erfinden.
def __init__(self, name):
# Wir weisen das Argument name dem name-Attribut der Instanz zu
self.name = name
- # Eine Instanzmethode. Alle Methoden erhalten self als erstes Argument.
+ # Eine Instanzmethode. Alle Methoden erhalten "self" als erstes Argument.
def say(self, msg):
return "%s: %s" % (self.name, msg)
+ # Eine weitere Instanzmethode
+ def sing(self):
+ return 'yo... yo... microphone check... one two... one two...'
+
# Eine Klassenmethode wird von allen Instanzen geteilt.
# Sie werden mit der aufrufenden Klasse als erstem Argument aufgerufen
@classmethod
@@ -416,56 +464,287 @@ class Human(object):
def grunt():
return "*grunt*"
+ # Eine Eigenschaft (Property) ist wie ein Getter.
+    # Es verwandelt die Methode age() in ein schreibgeschütztes Attribut mit demselben Namen.
+    # Es ist jedoch nicht nötig, triviale Getter und Setter in Python zu schreiben.
+ @property
+ def age(self):
+ return self._age
+
+    # Damit kann die Eigenschaft festgelegt werden
+ @age.setter
+ def age(self, age):
+ self._age = age
+
+    # Damit kann die Eigenschaft gelöscht werden
+ @age.deleter
+ def age(self):
+ del self._age
+
+# Wenn ein Python-Interpreter eine Quelldatei liest, führt er den gesamten Code aus.
+# Diese __name__-Prüfung stellt sicher, dass dieser Codeblock nur ausgeführt wird,
+# wenn dieses Modul das Hauptprogramm ist.
+if __name__ == '__main__':
+ # Eine Instanz einer Klasse erstellen
+ i = Human(name="Ian")
+ i.say("hi") # "Ian: hi"
+ j = Human("Joel")
+ j.say("hello") # "Joel: hello"
+ # i und j sind Instanzen des Typs Mensch, oder anders ausgedrückt: Sie sind Objekte des Menschen
+
+ # Rufen wir unsere Klassenmethode auf
+ i.say(i.get_species()) # "Ian: H. sapiens"
+
+ # Ändern wir das gemeinsame Attribut
+ Human.species = "H. neanderthalensis"
+ i.say(i.get_species()) # => "Ian: H. neanderthalensis"
+ j.say(j.get_species()) # => "Joel: H. neanderthalensis"
+
+ # Aufruf der statischen Methode
+ print(Human.grunt()) # => "*grunt*"
+
+ # Kann keine statische Methode mit Instanz des Objekts aufrufen,
+ # da i.grunt () automatisch "self" (das Objekt i) als Argument verwendet
+ print(i.grunt()) # => TypeError: grunt() takes 0 positional arguments but 1 was given
+
+ # Die Eigenschaft für diese Instanz aktualisieren
+ i.age = 42
+ # die Eigenschaft auslesen
+ i.say(i.age) # => "Ian: 42"
+ j.say(j.age) # => "Joel: 0"
+ # die Eigenschaft löschen
+ del i.age
+ # i.age # => würde einen AttributeError werfen
+
+####################################################
+## 6.1 Inheritance
+####################################################
+
+# Vererbung ermöglicht die Definition neuer untergeordneter Klassen,
+# die Methoden und Variablen von ihrer übergeordneten Klasse erben.
+
+# Wenn Sie die oben definierte Human-Klasse als Basis- oder Elternklasse verwenden,
+# können Sie eine untergeordnete Klasse, Superhero, definieren, die die Klassenvariablen
+# wie "species", "name" und "age" sowie Methoden wie "sing" und "grunzen" aus der Klasse Human erbt.
+# Die Untergeordnete Klasse kann aber auch eigene Eigenschaften haben.
+
+# Um von der Modularisierung per Datei zu profitieren, können Sie die Klassen
+# in ihren eigenen Dateien platzieren, z. B. human.py
+
+# Um Funktionen aus anderen Dateien zu importieren, verwenden Sie das folgende Format
+# from "Dateiname-ohne-Erweiterung" impotr "Funktion-oder-Klasse"
+
+from human import Human
+
+# Geben Sie die übergeordnete(n) Klasse(n) als Parameter für die Klassendefinition an
+class Superhero(Human):
+
+ # Wenn die untergeordnete Klasse alle Definitionen des übergeordneten Elements
+ # ohne Änderungen erben soll, können Sie einfach das Schlüsselwort "pass"
+ # (und nichts anderes) verwenden. In diesem Fall wird jedoch auskommentiert,
+ # um eine eindeutige untergeordnete Klasse zuzulassen:
+ # pass
+
+ # Kindklassen können die Attribute ihrer Eltern überschreiben
+ species = 'Superhuman'
+
+ # Kinder erben automatisch den Konstruktor ihrer übergeordneten Klasse
+ # einschließlich ihrer Argumente, können aber auch zusätzliche Argumente oder
+ # Definitionen definieren und ihre Methoden zB den Klassenkonstruktor überschreiben.
+ # Dieser Konstruktor erbt das Argument "name" von der Klasse "Human" und
+ # fügt die Argumente "superpowers" und "movie" hinzu:
+ def __init__(self, name, movie=False,
+ superpowers=["super strength", "bulletproofing"]):
+
+ # zusätzliche Klassenattribute hinzufügen:
+ self.fictional = True
+ self.movie = movie
+ # Beachten Sie die veränderlichen Standardwerte, da die Standardwerte gemeinsam genutzt werden
+ self.superpowers = superpowers
+
+ # Mit der Funktion "super" können Sie auf die Methoden der übergeordneten Klasse
+ # zugreifen, die vom untergeordneten Objekt überschrieben werden,
+ # in diesem Fall die Methode __init__.
+        # Dies ruft den Konstruktor der übergeordneten Klasse auf:
+ super().__init__(name)
+
+ # überschreiben der "sing" Methode
+ def sing(self):
+ return 'Dun, dun, DUN!'
+
+ # eine zusätzliche Instanzmethode hinzufügen
+ def boast(self):
+ for power in self.superpowers:
+ print("I wield the power of {pow}!".format(pow=power))
+
+if __name__ == '__main__':
+ sup = Superhero(name="Tick")
+
+ # Instanztypprüfungen
+ if isinstance(sup, Human):
+ print('I am human')
+ if type(sup) is Superhero:
+ print('I am a superhero')
+
+ # Die Reihenfolge der Methodenauflösung (MRO = Method Resolution Order) anzeigen, die sowohl von getattr() als auch von super() verwendet wird.
+    # Dieses Attribut ist dynamisch und kann aktualisiert werden.
+ print(Superhero.__mro__) # => (<class '__main__.Superhero'>,
+ # => <class 'human.Human'>, <class 'object'>)
+
+ # Ruft die übergeordnete Methode auf, verwendet jedoch das eigene Klassenattribut
+ print(sup.get_species()) # => Superhuman
+
+ # Ruft die überschriebene Methode auf
+ print(sup.sing()) # => Dun, dun, DUN!
+
+ # Ruft die Methode von Human auf
+ sup.say('Spoon') # => Tick: Spoon
+
+ # Aufruf einer Methode, die nur in Superhero existiert
+ sup.boast() # => I wield the power of super strength!
+ # => I wield the power of bulletproofing!
+
+ # Vererbtes Klassenattribut
+ sup.age = 31
+ print(sup.age) # => 31
+
+ # Attribut, das nur in Superhero existiert
+ print('Am I Oscar eligible? ' + str(sup.movie))
+
+####################################################
+## 6.2 Multiple Inheritance
+####################################################
-# Eine Instanz einer Klasse erstellen
-i = Human(name="Ian")
-print i.say("hi") # gibt "Ian: hi" aus
+# Eine weitere Klassendefinition
+# bat.py
-j = Human("Joel")
-print j.say("hello") #gibt "Joel: hello" aus
+class Bat:
-# Rufen wir mal unsere Klassenmethode auf
-i.get_species() #=> "H. sapiens"
+ species = 'Baty'
-# Ändern wir mal das gemeinsame Attribut
-Human.species = "H. neanderthalensis"
-i.get_species() #=> "H. neanderthalensis"
-j.get_species() #=> "H. neanderthalensis"
+ def __init__(self, can_fly=True):
+ self.fly = can_fly
-# Aufruf der statischen Methode
-Human.grunt() #=> "*grunt*"
+ # This class also has a say method
+ def say(self, msg):
+ msg = '... ... ...'
+ return msg
+ # And its own method as well
+ def sonar(self):
+ return '))) ... ((('
+if __name__ == '__main__':
+ b = Bat()
+ print(b.say('hello'))
+ print(b.fly)
+
+# Und noch eine andere Klassendefinition, die von Superhero und Bat erbt
+# superhero.py
+from superhero import Superhero
+from bat import Bat
+
+# Definieren Sie Batman als eine Kindklasse, das von Superheld und Bat erbt
+class Batman(Superhero, Bat):
+
+ def __init__(self, *args, **kwargs):
+ # In der Regel müssen Sie super aufrufen, um Attribute zu erben:
+ # super (Batman, selbst) .__ init__ (* args, ** kwargs)
+ # Allerdings handelt es sich hier um Mehrfachvererbung, und super()
+ # funktioniert nur mit der nächsten Basisklasse in der MRO-Liste.
+ # Stattdessen rufen wir explizit __init__ für alle Vorfahren auf.
+ # Die Verwendung von *args und **kwargs ermöglicht die saubere Übergabe von
+ # Argumenten, wobei jedes übergeordnete Element eine Schicht der Zwiebel "abschält".
+ Superhero.__init__(self, 'anonymous', movie=True,
+ superpowers=['Wealthy'], *args, **kwargs)
+ Bat.__init__(self, *args, can_fly=False, **kwargs)
+ # überschreibt den Wert für das Namensattribut
+ self.name = 'Sad Affleck'
+
+ def sing(self):
+ return 'nan nan nan nan nan batman!'
+
+if __name__ == '__main__':
+ sup = Batman()
+
+ # Die Reihenfolge der Methodenauflösung (MRO = Method Resolution Order) anzeigen,
+ # die sowohl von getattr() als auch von super() verwendet wird.
+ # Dieses Attribut ist dynamisch und kann aktualisiert werden.
+ print(Batman.__mro__) # => (<class '__main__.Batman'>,
+ # => <class 'superhero.Superhero'>,
+ # => <class 'human.Human'>,
+ # => <class 'bat.Bat'>, <class 'object'>)
+
+ # Ruft die übergeordnete Methode auf, verwendet jedoch das eigene Klassenattribut
+ print(sup.get_species()) # => Superhuman
+
+ # Ruft die überschriebene Methode auf
+ print(sup.sing()) # => nan nan nan nan nan batman!
+
+ # Ruft die Methode von Human auf, weil die Reihenfolge der Vererbung wichtig ist
+ sup.say('I agree') # => Sad Affleck: I agree
+
+ # Aufrufmethode, die nur im 2. Vorfahren existiert
+ print(sup.sonar()) # => ))) ... (((
+
+ # Vererbtes Klassenattribut
+ sup.age = 100
+ print(sup.age) # => 100
+
+ # Vererbtes Attribut vom 2. Vorfahren, dessen Standardwert überschrieben wurde.
+ print('Can I fly? ' + str(sup.fly)) # => Can I fly? False
+
+
####################################################
-## 6. Module
-####################################################
-
-# Wir können Module importieren
-import math
-print math.sqrt(16) #=> 4
+## 7. Fortgeschrittenes
+####################################################
+
+# Generatoren helfen Ihnen, lazy Code zu erstellen.
+def double_numbers(iterable):
+ for i in iterable:
+ yield i + i
+
+# Generatoren sind speichereffizient, da sie nur die Daten laden,
+# die zur Verarbeitung des nächsten Werts in der iterierbaren Komponente
+# erforderlich sind. Dadurch können sie ansonsten unzulässig große Wertebereiche ausführen.
+# HINWEIS: `range` ersetzt` xrange` in Python 3.
+for i in double_numbers(range(1, 900000000)): # `range` ist ein Generator.
+ print(i)
+ if i >= 30:
+ break
+
+# Genauso wie Sie ein 'list comprehension' (Listen Abstraktion) erstellen können, können Sie auch 'generator comprehension' (Generator Abstraktion) erstellen.
+values = (-x for x in [1,2,3,4,5])
+for x in values:
+ print(x) # prints -1 -2 -3 -4 -5 to console/terminal
+
+# Sie können eine Generator Abstraktion auch direkt in eine Liste umwandeln (casten).
+values = (-x for x in [1,2,3,4,5])
+gen_to_list = list(values)
+print(gen_to_list) # => [-1, -2, -3, -4, -5]
-# Wir können auch nur spezielle Funktionen eines Moduls importieren
-from math import ceil, floor
-print ceil(3.7) #=> 4.0
-print floor(3.7) #=> 3.0
+# Decorators
+# In diesem Beispiel umschliesst "beg" "say". Wenn say_please True ist, wird die zurückgegebene Nachricht geändert.
+from functools import wraps
-# Wir können auch alle Funktionen eines Moduls importieren
-# Warnung: Dies wird nicht empfohlen
-from math import *
+def beg(target_function):
+ @wraps(target_function)
+ def wrapper(*args, **kwargs):
+ msg, say_please = target_function(*args, **kwargs)
+ if say_please:
+ return "{} {}".format(msg, "Please! I am poor :(")
+ return msg
-# Wir können Modulnamen abkürzen
-import math as m
-math.sqrt(16) == m.sqrt(16) #=> True
+ return wrapper
-# Module sind in Python nur gewöhnliche Dateien. Wir
-# können unsere eigenen schreiben und importieren. Der Name des
-# Moduls ist der Dateiname.
+@beg
+def say(say_please=False):
+ msg = "Can you buy me a beer?"
+ return msg, say_please
-# Wir können auch die Funktionen und Attribute eines
-# Moduls herausfinden.
-import math
-dir(math)
+print(say()) # Can you buy me a beer?
+print(say(say_please=True)) # Can you buy me a beer? Please! I am poor :(
```
diff --git a/de-de/python3-de.html.markdown b/de-de/python3-de.html.markdown
index b313727c..4ef997a1 100644
--- a/de-de/python3-de.html.markdown
+++ b/de-de/python3-de.html.markdown
@@ -14,7 +14,7 @@ Python wurde in den frühen Neunzigern von Guido van Rossum entworfen. Es ist he
Feedback ist herzlich willkommen! Ihr erreicht mich unter [@louiedinh](http://twitter.com/louiedinh) oder louiedinh [at] [google's email service].
-Hinweis: Dieser Beitrag bezieht sich insplizit auf Python 3. Falls du lieber Python 2.7 lernen möchtest, schau [hier](http://learnxinyminutes.com/docs/python/) weiter.
+Hinweis: Dieser Beitrag bezieht sich implizit auf Python 3. Falls du lieber Python 2.7 lernen möchtest, schau [hier](http://learnxinyminutes.com/docs/python/) weiter.
```python
@@ -555,7 +555,7 @@ Human.grunt() #=> "*grunt*"
# Wir können Module importieren
import math
-print(math.sqrt(16)) #=> 4
+print(math.sqrt(16)) #=> 4.0
# Wir können auch nur spezielle Funktionen eines Moduls importieren
from math import ceil, floor
diff --git a/de-de/rst-de.html.markdown b/de-de/rst-de.html.markdown
index bcfe21bd..072299f5 100644
--- a/de-de/rst-de.html.markdown
+++ b/de-de/rst-de.html.markdown
@@ -1,6 +1,6 @@
---
language: restructured text (RST)
-filename: restructuredtext.rst
+filename: restructuredtext-de.rst
contributors:
- ["DamienVGN", "https://github.com/martin-damien"]
- ["Andre Polykanine", "https://github.com/Oire"]
diff --git a/de-de/shutit-de.html.markdown b/de-de/shutit-de.html.markdown
index f66ed906..29ed639e 100644
--- a/de-de/shutit-de.html.markdown
+++ b/de-de/shutit-de.html.markdown
@@ -1,6 +1,6 @@
---
category: tool
-filename: learnshutit.html
+filename: learnshutit-de.html
tool: ShutIt
contributors:
- ["Ian Miell", "http://ian.meirionconsulting.tk"]
diff --git a/de-de/yaml-de.html.markdown b/de-de/yaml-de.html.markdown
index 25f2edc4..ff45dc8d 100644
--- a/de-de/yaml-de.html.markdown
+++ b/de-de/yaml-de.html.markdown
@@ -10,7 +10,7 @@ lang: de-de
YAML ist eine Sprache zur Datenserialisierung, die sofort von Menschenhand geschrieben und gelesen werden kann.
-YAML ist ein Erweiterung von von JSON mit der Erweiterung um syntaktisch wichtige Zeilenumbrüche und Einrückungen, ähnlich wie auch in Python. Anders als in Python allerdings erlaubt YAML keine Tabulator-Zeichen.
+YAML ist ein Erweiterung von JSON mit der Erweiterung um syntaktisch wichtige Zeilenumbrüche und Einrückungen, ähnlich wie auch in Python geschrieben werden können. Anders als in Python allerdings erlaubt YAML keine Tabulator-Zeichen.
```yaml
# Kommentare in YAML schauen so aus.
@@ -111,7 +111,7 @@ python_komplexe_Zahlen: !!python/komplex 1+2j
# EXTRA YAML TYPEN #
####################
-# Strings and Zahlen sind nicht die einzigen Skalare, welche YAML versteht.
+# Strings und Zahlen sind nicht die einzigen Skalare, welche YAML versteht.
# ISO-formatierte Datumsangaben and Zeiangaben können ebenso geparsed werden.
DatumZeit: 2001-12-15T02:59:43.1Z
DatumZeit_mit_Leerzeichen: 2001-12-14 21:59:43.10 -5
diff --git a/dhall.html.markdown b/dhall.html.markdown
new file mode 100644
index 00000000..21126c8a
--- /dev/null
+++ b/dhall.html.markdown
@@ -0,0 +1,362 @@
+---
+language: Dhall
+filename: learndhall.dhall
+contributors:
+ - ["Gabriel Gonzalez", "http://www.haskellforall.com/"]
+---
+
+Dhall is a programmable configuration language that provides a non-repetitive
+alternative to YAML.
+
+You can think of Dhall as: JSON + functions + types + imports
+
+Note that while Dhall is programmable, Dhall is not Turing-complete. Many
+of Dhall's features take advantage of this restriction to provider stronger
+safety guarantees and more powerful tooling.
+
+```haskell
+-- Single-line comment
+
+{- Multi-line comment
+
+ Unicode is fine 🙂
+
+ This file is a valid Dhall expression that evaluates to a large record
+ collecting the results of each step.
+
+ You can view the results by interpreting the file:
+
+ $ dhall --file learndhall.dhall
+
+ {- Comments can be nested -}
+-}
+
+let greeting = "Hello, world!"
+
+let fruits = "🍋🍓🍍🍉🍌"
+
+let interpolation = "Enjoy some delicious fruit: ${fruits}"
+
+let multilineText {- Inline comments work, too -} =
+ ''
+ Leading whitespace is stripped from multi-line text literals.
+
+ That means you can freely indent or dedent a text literal without
+ changing the result.
+
+ Relative indentation within the literal is still preserved.
+
+ Other than that, the text literal is preserved verbatim, similar to a
+ "literal" YAML multiline string.
+ ''
+
+let bool = True
+
+-- Type annotations on bindings are optional, but helpful, so we'll use them
+let annotation : Bool = True
+
+let renderedBool : Text = if bool then "True" else "False"
+
+-- Natural numbers are non-negative and are unsigned
+let naturalNumber : Natural = 42
+
+-- Integers may be negative, but require an explicit sign, even if positive
+let positiveInteger : Integer = +1
+
+let negativeInteger : Integer = -12
+
+let pi : Double = 3.14159265359
+
+{- You can use a wider character range for identifiers (such as quotation
+ marks and whitespace) if you quote them using backticks
+-}
+let `Avogadro's Number` : Double = 6.0221409e+23
+
+let origin : { x : Double, y : Double } = { x = 0.0, y = 0.0 }
+
+let somePrimes : List Natural = [ 2, 3, 5, 7, 11 ]
+
+{- A schema is the same thing as a type
+
+ Types begin with an uppercase letter by convention, but this convention is
+ not enforced
+-}
+let Profile : Type
+ = { person :
+ { name : Text
+ , age : Natural
+ }
+ , address :
+ { country : Text
+ , state : Text
+ , city : Text
+ }
+ }
+
+let john : Profile =
+ { person =
+ { name = "John Doe"
+ , age = 67
+ }
+ , address =
+ { country = "United States"
+ , state = "Pennsylvania"
+ , city = "Philadelphia"
+ }
+ }
+
+let philadelphia : Text = john.address.city
+
+{- Enum alternatives also begin with an uppercase letter by convention. This
+ convention is not enforced
+-}
+let DNA : Type = < Adenine | Cytosine | Guanine | Thymine >
+
+let dnaSequence : List DNA = [ DNA.Thymine, DNA.Guanine, DNA.Guanine ]
+
+let compactDNASequence : List DNA =
+ let a = DNA.Adenine
+ let c = DNA.Cytosine
+ let g = DNA.Guanine
+ let t = DNA.Thymine
+ in [ c, t, t, a, t, c, g, g, c ]
+
+-- You can transform enums by providing a record with one field per alternative
+let theLetterG : Text =
+ merge
+ { Adenine = "A"
+ , Cytosine = "C"
+ , Guanine = "G"
+ , Thymine = "T"
+ }
+ DNA.Guanine
+
+let presentOptionalValue : Optional Natural = Some 1
+
+let absentOptionalValue : Optional Natural = None Natural
+
+let points : List { x : Double, y : Double } =
+ [ { x = 1.1, y = -4.2 }
+ , { x = 4.4, y = -3.0 }
+ , { x = 8.2, y = -5.5 }
+ ]
+
+{- `Natural -> List Natural` is the type of a function whose input type is a
+ `Natural` and whose output type is a `List Natural`
+
+ All functions in Dhall are anonymous functions (a.k.a. "lambdas"),
+ which you can optionally give a name
+
+ For example, the following function is equivalent to this Python code:
+
+ lambda n : [ n, n + 1 ]
+
+ ... and this JavaScript code:
+
+ function (n) { return [ n, n + 1 ]; }
+-}
+let exampleFunction : Natural -> List Natural =
+ \(n : Natural) -> [ n, n + 1 ]
+
+-- Dhall also supports Unicode syntax, but this tutorial will stick to ASCII
+let unicodeFunction : Natural → List Natural =
+ λ(n : Natural) → [ n, n + 1 ]
+
+-- You don't need to parenthesize function arguments
+let exampleFunctionApplication : List Natural =
+ exampleFunction 2
+
+let functionOfMultipleArguments : Natural -> Natural -> List Natural =
+ \(x : Natural) -> \(y : Natural) -> [ x, y ]
+
+let functionAppliedToMultipleArguments : List Natural =
+ functionOfMultipleArguments 2 3
+
+{- Same as `exampleFunction` except we gave the function's input type a
+ name: "n"
+-}
+let namedArgumentType : forall (n : Natural) -> List Natural =
+ \(n : Natural) -> [ n, n + 1 ]
+
+{- If you name a function's input type, you can use that name later within the
+ same type
+
+ This lets you write a function that works for more than one type of input
+ (a.k.a. a "polymorphic" function)
+-}
+let duplicate : forall (a : Type) -> a -> List a =
+ \(a : Type) -> \(x : a) -> [ x, x ]
+
+let duplicatedNumber : List Natural =
+ duplicate Natural 2
+
+let duplicatedBool : List Bool =
+ duplicate Bool False
+
+{- The language also has some built-in polymorphic functions, such as:
+
+ List/head : forall (a : Type) -> List a -> Optional a
+-}
+let firstPrime : Optional Natural = List/head Natural somePrimes
+
+let functionOfARecord : { x : Natural, y : Natural } -> List Natural =
+ \(args : { x : Natural, y : Natural }) -> [ args.x, args.y ]
+
+let functionAppliedToARecord : List Natural =
+ functionOfARecord { x = 2, y = 5 }
+
+{- All type conversions are explicit
+
+ `Natural/show` is a built-in function of the following type:
+
+ Natural/show : Natural -> Text
+
+ ... that converts `Natural` numbers to their `Text` representation
+-}
+let typeConversion : Natural -> Text =
+ \(age : Natural) -> "I am ${Natural/show age} years old!"
+
+-- A template is the same thing as a function whose output type is `Text`
+let mitLicense : { year : Natural, copyrightHolder : Text } -> Text =
+ \(args : { year : Natural, copyrightHolder : Text }) ->
+''
+Copyright ${Natural/show args.year} ${args.copyrightHolder}
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal in
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+of the Software, and to permit persons to whom the Software is furnished to do
+so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+''
+
+-- Template instantiation is the same thing as function application
+let templatedLicense : Text =
+ mitLicense { year = 2019, copyrightHolder = "Jane Smith" }
+
+{- You can import expressions by URL
+
+ Also, like Bash, you can import code from your local filesystem (not shown)
+
+ Security-conscious users can pin remotely-imported expressions by adding a
+ semantic integrity check. The interpreter rejects any attempt to tamper with
+ an expression pinned in this way. However, behavior-preserving refactors
+ of imported content will not perturb the hash.
+
+ Imported expressions pinned in this way are also locally cached in a
+ content-addressable store (typically underneath `~/.cache/dhall`)
+-}
+let Natural/sum : List Natural -> Natural =
+ https://prelude.dhall-lang.org/Natural/sum
+ sha256:33f7f4c3aff62e5ecf4848f964363133452d420dcde045784518fb59fa970037
+
+let twentyEight : Natural = Natural/sum somePrimes
+
+-- A package is the same thing as a (possibly nested) record that you can import
+let Prelude = https://prelude.dhall-lang.org/package.dhall
+
+let false : Bool = Prelude.Bool.not True
+
+-- You can import the raw contents of a file by adding `as Text` to an import
+let sourceCode : Text = https://prelude.dhall-lang.org/Bool/not as Text
+
+-- You can import environment variables, too:
+let presentWorkingDirectory = env:PWD as Text
+
+-- You can provide a fallback expression if an import fails
+let home : Optional Text = Some env:HOME ? None Text
+
+-- Fallback expressions can contain alternative imports of their own
+let possiblyCustomPrelude =
+ env:DHALL_PRELUDE
+ ? https://prelude.dhall-lang.org/package.dhall
+
+{- Tie everything together by auto-generating configurations for 10 build users
+ using the `generate` function:
+
+ Prelude.List.generate
+ : Natural -> forall (a : Type) -> (Natural -> a) -> List a
+-}
+let buildUsers =
+ let makeUser = \(user : Text) ->
+ let home = "/home/${user}"
+ let privateKey = "${home}/.ssh/id_ed25519"
+ let publicKey = "${privateKey}.pub"
+ in { home = home
+ , privateKey = privateKey
+ , publicKey = publicKey
+ }
+
+ let buildUser =
+ \(index : Natural) -> makeUser "build${Natural/show index}"
+
+ let Config =
+ { home : Text
+ , privateKey : Text
+ , publicKey : Text
+ }
+
+ in Prelude.List.generate 10 Config buildUser
+
+-- Present all of the results in a final record
+in { greeting = greeting
+ , fruits = fruits
+ , interpolation = interpolation
+ , multilineText = multilineText
+ , bool = bool
+ , annotation = annotation
+ , renderedBool = renderedBool
+ , naturalNumber = naturalNumber
+ , positiveInteger = positiveInteger
+ , negativeInteger = negativeInteger
+ , pi = pi
+ , `Avogadro's Number` = `Avogadro's Number`
+ , origin = origin
+ , somePrimes = somePrimes
+ , john = john
+ , philadelphia = philadelphia
+ , dnaSequence = dnaSequence
+ , compactDNASequence = compactDNASequence
+ , theLetterG = theLetterG
+ , presentOptionalValue = presentOptionalValue
+ , absentOptionalValue = absentOptionalValue
+ , points = points
+ , exampleFunction = exampleFunction
+ , unicodeFunction = unicodeFunction
+ , exampleFunctionApplication = exampleFunctionApplication
+ , functionOfMultipleArguments = functionOfMultipleArguments
+ , functionAppliedToMultipleArguments = functionAppliedToMultipleArguments
+ , namedArgumentType = namedArgumentType
+ , duplicate = duplicate
+ , duplicatedNumber = duplicatedNumber
+ , duplicatedBool = duplicatedBool
+ , firstPrime = firstPrime
+ , functionOfARecord = functionOfARecord
+ , functionAppliedToARecord = functionAppliedToARecord
+ , typeConversion = typeConversion
+ , mitLicense = mitLicense
+ , templatedLicense = templatedLicense
+ , twentyEight = twentyEight
+ , false = false
+ , sourceCode = sourceCode
+ , presentWorkingDirectory = presentWorkingDirectory
+ , home = home
+ , buildUsers = buildUsers
+ }
+```
+
+To learn more, visit the official website, which also lets you try the
+language live in your browser:
+
+* [https://dhall-lang.org](http://dhall-lang.org/)
diff --git a/dynamic-programming.html.markdown b/dynamic-programming.html.markdown
index f5f1743c..c73b1845 100644
--- a/dynamic-programming.html.markdown
+++ b/dynamic-programming.html.markdown
@@ -49,3 +49,5 @@ for i=0 to n-1
## Online Resources
* [codechef](https://www.codechef.com/wiki/tutorial-dynamic-programming)
+* [InterviewBit](https://www.interviewbit.com/courses/programming/topics/dynamic-programming/)
+
diff --git a/el-gr/bash-gr.html.markdown b/el-gr/bash-gr.html.markdown
new file mode 100644
index 00000000..2989969d
--- /dev/null
+++ b/el-gr/bash-gr.html.markdown
@@ -0,0 +1,528 @@
+---
+category: tool
+tool: bash
+contributors:
+ - ["Dimitri Kokkonis", "https://github.com/kokkonisd"]
+filename: LearnBash-gr.sh
+lang: el-gr
+---
+
+Η λέξη «bash» είναι ένα από τα ονόματα του unix shell (τερματικός), το οποίο
+διανέμεται επίσης ως προεπιλεγμένος τερματικός για το λειτουργικό σύστημα GNU, τα Linux και τα Mac OS X.
+Σχεδόν όλα τα παραδείγματα που ακολουθούν μπορούν να αποτελέσουν μέρος ενός
+προγράμματος τερματικού (shell script) ή να εκτελεσθούν απευθείας από τον
+τερματικό.
+
+[Διαβάστε περισσότερα εδώ.](http://www.gnu.org/software/bash/manual/bashref.html)
+
+```bash
+#!/usr/bin/env bash
+# Η πρώτη γραμμή του προγράμματος είναι το shebang που υποδεικνύει στο σύστημα
+# πώς να εκτελέσει το πρόγραμμα: http://en.wikipedia.org/wiki/Shebang_(Unix)
+# Όπως ήδη θα καταλάβατε, τα σχόλια ξεκινούν με τον χαρακτήρα #. Το shebang
+# είναι επίσης ένα σχόλιο.
+# ΣτΜ.: Τα ονόματα των μεταβλητών είναι γραμμένα σε greeklish καθώς η Bash δεν
+# επιτρέπει την χρήση unicode χαρακτήρων.
+
+# Ένα απλό παράδειγμα τύπου «hello world»:
+echo Καλημέρα, Κόσμε! # => Καλημέρα, Κόσμε!
+
+# Κάθε εντολή ξεκινά σε μια νέα γραμμή, ή μετά από ένα ελληνικό ερωτηματικό:
+echo 'Αυτή είναι η πρώτη γραμμή'; echo 'Αυτή είναι η δεύτερη γραμμή'
+# => Αυτή είναι η πρώτη γραμμή
+# => Αυτή είναι η δεύτερη γραμμή
+
+# Ορίζουμε μεταβλητές ως εξής:
+Metavliti="Κάποιο αλφαριθμητικό"
+
+# Αλλά όχι ως εξής:
+Metavliti = "Κάποιο αλφαριθμητικό" # => επιστρέφει το λάθος
+# «Metavliti: command not found»
+# Η Bash θα καταλάβει πως η Metavliti είναι κάποια εντολή που πρέπει να
+# εκτελέσει και θα επιστρέψει ένα λάθος γιατί δεν μπορεί να την βρει.
+
+# Ούτε έτσι μπορούμε να δηλώσουμε μεταβλητές:
+Metavliti= 'Κάποιο αλφαριθμητικό' # => επιστρέφει το λάθος: «Κάποιο
+ # αλφαριθμητικό: command not found»
+# Η Bash θα καταλάβει πως το αλφαριθμητικό «Κάποιο αλφαριθμητικό» είναι μια
+# εντολή που πρέπει να εκτελέσει και θα επιστρέψει ένα λάθος γιατί δεν μπορεί
+# να την βρει. (Σε αυτή την περίπτωση το τμήμα της εντολής «Metavliti=» θα
+# ερμηνευθεί ως ορισμός μεταβλητής ισχύων μόνο στο πλαίσιο της εντολής
+# «Κάποιο αλφαριθμητικό».)
+
+# Ας χρησιμοποιήσουμε την μεταβλητή:
+echo $Metavliti # => Κάποιο αλφαριθμητικό
+echo "$Metavliti" # => Κάποιο αλφαριθμητικό
+echo '$Metavliti' # => $Metavliti
+# Όταν χρησιμοποιούμε την ίδια την μεταβλητή - είτε είναι για να της δώσουμε
+# μια νέα αξία, για να την εξάγουμε ή για οτιδήποτε άλλο - γράφουμε το όνομά
+# της χωρίς τον χαρακτήρα $. Αν θέλουμε να χρησιμοποιήσουμε την αξία της
+# μεταβλητής, πρέπει να χρησιμοποιήσουμε τον χαρατήρα $.
+# Να σημειωθεί πώς ο χαρακτήρας ' δεν θα μετατρέψει τις μεταβλητές στις αξίες
+# τους!
+
+# Επέκταση παραμέτρων ${ }:
+echo ${Metavliti} # => Κάποιο αλφαριθμητικό
+# Αυτή είναι μια απλή χρήση της επέκτασης παραμέτρων.
+# Η επέκταση παραμέτρων εξάγει μια αξία από μια μεταβλητή.
+# Κατά την επέκταση η τιμή ή η παράμετρος μπορεί να τροποποιηθεί.
+# Ακολουθούν άλλες μετατροπές που μπορούν να προστεθούν σε αυτή την επέκταση.
+
+# Αντικατάσταση αλφαριθμητικών μέσα σε μεταβλητές
+echo ${Metavliti/Κάποιο/Ένα} # => Ένα αλφαριθμητικό
+# Αυτή η τροποποίηση θα αντικαταστήσει την πρώτη εμφάνιση της λέξης «Κάποιο»
+# με την λέξη «Ένα».
+
+# Υποαλφαριθμητικό μιας μεταβλητής
+Mikos=7
+echo ${Metavliti:0:Mikos} # => Κάποιο
+# Αυτή η τροποποίηση θα επιστρέψει μόνο τους πρώτους 7 χαρακτήρες της τιμής
+# της μεταβλητής.
+echo ${Metavliti: -5} # => ητικό
+# Αυτή η τροποποίηση θα επιστρέψει τους τελευταίους 5 χαρακτήρες (προσοχή στο
+# κενό πριν το -5).
+
+# Μήκος αλφαριθμητικού
+echo ${#Metavliti} # => 20
+
+# Προεπιλεγμένη αξία για μια μεταβλητή
+echo ${Foo:-"ΠροεπιλεγμένηΑξίαΑνΤοFooΕίναιΑόριστοΉΆδειο"}
+# => ΠροεπιλεγμένηΑξίαΑνΤοFooΕίναιΑόριστοΉΆδειο
+# Αυτό δουλεύει στην περίπτωση που το Foo είναι αόριστο (Foo=) ή άδειο
+# (Foo="")· το μηδέν (Foo=0) επιστρέφει 0.
+# Να σημειωθεί πως αυτή η εντολή απλώς επιστρέφει την προεπιλεγμένη αξία και
+# δεν τροποποιεί την αξία της μεταβλητής.
+
+# Ορισμός ενός πίνακα με 6 στοιχεία
+pinakas0=(ένα δύο τρία τέσσερα πέντε έξι)
+# Εντολή που τυπώνει το πρώτο στοιχείο
+echo $pinakas0 # => "ένα"
+# Εντολή που τυπώνει το πρώτο στοιχείο
+echo ${pinakas0[0]} # => "ένα"
+# Εντολή που τυπώνει όλα τα στοιχεία
+echo ${pinakas0[@]} # => "ένα δύο τρία τέσσερα πέντε έξι"
+# Εντολή που τυπώνει τον αριθμό των στοιχείων
+echo ${#pinakas0[@]} # => "6"
+# Εντολή που τυπώνει τον αριθμό των χαρακτήρων στο τρίτο στοιχείο
+echo ${#pinakas0[2]} # => "4"
+# Εντολή που τυπώνει δύο στοιχεία ξεκινώντας από το τέταρτο
+echo ${pinakas0[@]:3:2} # => "τέσσερα πέντε"
+# Εντολή που τυπώνει όλα τα στοιχεία, το καθένα σε διαφορετική γραμμή
+for i in "${pinakas0[@]}"; do
+ echo "$i"
+done
+
+# Επέκταση αγκίστρων { }
+# Χρησιμοποιείται για την παραγωγή αλφαριθμητικών
+echo {1..10} # => 1 2 3 4 5 6 7 8 9 10
+echo {a..z} # => a b c d e f g h i j k l m n o p q r s t u v w x y z
+# Η εντολή θα τυπώσει όλο το εύρος, από την πρώτη μέχρι την τελευταία αξία
+
+# Ενσωματωμένες μεταβλητές
+# Υπάρχουν κάποιες χρήσιμες ενσωματωμένες μεταβλητές, όπως:
+echo "Η τιμή την οποία επέστρεψε το τελευταίο πρόγραμμα: $?"
+echo "Ο αριθμός PID αυτού του script: $$"
+echo "Ο αριθμός των παραμέτρων που περάστηκαν σε αυτό το script: $#"
+echo "Όλες οι παράμετροι που περάστηκαν σε αυτό το script: $@"
+echo "Οι παράμετροι του script διαχωρισμένες σε μεταβλητές: $1 $2..."
+
+# Τώρα που γνωρίζουμε πως να τυπώνουμε (echo) και να χρησιμοποιούμε μεταβλητές,
+# ας μάθουμε κάποια από τα υπόλοιπα βασικά στοιχεία της Bash!
+
+# Ο τρέχων κατάλογος (ή αλλιώς, φάκελος) μπορεί να βρεθεί μέσω της εντολής
+# `pwd`.
+# `pwd` σημαίνει «print working directory».
+# Μπορούμε επίσης να χρησιμοποιούμε την ενσωματωμένη μεταβλητή `$PWD`.
+# Παρακολουθήστε πως οι δύο εντολές που ακολουθούν είναι ισοδύναμες:
+echo "Είμαι στον κατάλογο $(pwd)" # εκτελεί την εντολή `pwd` και τυπώνει το
+ # αποτέλεσμα
+echo "Είμαι στον κατάλογο $PWD" # τυπώνει την αξία της μεταβλητής
+
+# Αν έχετε πολλά μηνύματα στον τερματικό, η εντολή `clear` μπορεί να
+# «καθαρίσει» την οθόνη σας
+clear
+# Η συντόμευση Ctrl-L δουλεύει επίσης όσον αφορά το «καθάρισμα»
+
+# Ας διαβάσουμε μια αξία από κάποια είσοδο:
+echo "Πώς σε λένε;"
+read Onoma # Προσέξτε πως δεν χρειάστηκε να ορίσουμε μια νέα μεταβλητή
+echo Καλημέρα, $Onoma!
+
+# Η δομή των if statements έχει ως εξής:
+# (μπορείτε να εκτελέσετε την εντολή `man test` για περισσότερες πληροφορίες
+# σχετικά με τα conditionals)
+if [ $Onoma != $USER ]
+then
+ echo "Το όνομά σου δεν είναι το όνομα χρήστη σου"
+else
+ echo "Το όνομά σου είναι το όνομα χρήστη σου"
+fi
+# Η συνθήκη είναι αληθής αν η τιμή του $Onoma δεν είναι ίδια με το τρέχον
+# όνομα χρήστη στον υπολογιστή
+
+# ΣΗΜΕΙΩΣΗ: Αν το $Onoma είναι άδειο, η Bash βλέπει την συνθήκη ως:
+if [ != $USER ]
+# το οποίο αποτελεί συντακτικό λάθος
+# οπότε ο «ασφαλής» τρόπος να χρησιμοποιούμε εν δυνάμει άδειες μεταβλητές στην
+# Bash είναι ο εξής:
+if [ "$Onoma" != $USER ] ...
+# ο οποίος, όταν το $Onoma είναι άδειο, θα ερμηνευθεί από την Bash ως:
+if [ "" != $USER ] ...
+# το οποίο και δουλεύει όπως θα περιμέναμε.
+
+# Υπάρχει επίσης η εκτέλεση εντολών βάσει συνθηκών
+echo "Εκτελείται πάντα" || echo "Εκτελείται μόνο αν η πρώτη εντολή αποτύχει"
+# => Εκτελείται πάντα
+echo "Εκτελείται πάντα" && echo "Εκτελείται μόνο αν η πρώτη εντολή ΔΕΝ αποτύχει"
+# => Εκτελείται πάντα
+# => Εκτελείται μόνο αν η πρώτη εντολή ΔΕΝ αποτύχει
+
+
+# Για να χρησιμοποιήσουμε τους τελεστές && και || με τα if statements,
+# χρειαζόμαστε πολλαπλά ζευγάρια αγκύλων:
+if [ "$Onoma" == "Σταύρος" ] && [ "$Ilikia" -eq 15 ]
+then
+ echo "Αυτό θα εκτελεστεί αν το όνομα ($Onoma) είναι Σταύρος ΚΑΙ η ηλικία ($Ilikia) είναι 15."
+fi
+
+if [ "$Onoma" == "Δανάη" ] || [ "$Onoma" == "Ζαχαρίας" ]
+then
+ echo "Αυτό θα εκτελεστεί αν το όνομα ($Onoma) είναι Δανάη Ή Ζαχαρίας."
+fi
+
+# Υπάρχει επίσης ο τελεστής `=~`, που εκτελεί ένα regex πάνω σε ένα
+# αλφαριθμητικό:
+Email=me@example.com
+if [[ "$Email" =~ [a-z]+@[a-z]{2,}\.(com|net|org) ]]
+then
+ echo "Η διεύθυνση email είναι σωστά διατυπωμένη!"
+fi
+# Να σημειωθεί πως ο τελεστής `=~` δουλεύει μόνο με διπλές αγκύλες [[ ]],
+# που είναι ωστόσο διαφορετικές από τις μονές [ ].
+# Δείτε το http://www.gnu.org/software/bash/manual/bashref.html#Conditional-Constructs
+# για περισσότερες πληροφορίες σχετικά με αυτό.
+
+# Επαναπροσδιορισμός της εντολής `ping` ως alias (ψευδώνυμο) για την αποστολή 5
+# πακέτων
+alias ping='ping -c 5'
+# Ακύρωση του alias και χρήση της εντολής όπως είναι κανονικά ορισμένη
+\ping 192.168.1.1
+# Εκτύπωση όλων των aliases
+alias -p
+
+# Οι μαθηματικές εκφράσεις ορίζονται ως εξής:
+echo $(( 10 + 5 )) # => 15
+
+# Αντίθετα με άλλες γλώσσες προγραμματισμού, η Bash είναι επίσης ένα shell, άρα
+# δουλεύει στο πλαίσιο ενός «τρέχοντος καταλόγου». Μπορούμε να δούμε μια λίστα
+# αρχείων και καταλόγων στον τρέχων κατάλογο με την εντολή ls:
+ls # Τυπώνει μια λίστα των αρχείων και υποκαταλόγων που περιέχονται στον τρέχων
+ # κατάλογο
+
+# Αυτή η εντολή έχει επιλογές που ελέγχουν την εκτέλεσή της:
+ls -l # Τυπώνει κάθε αρχείο και κατάλογο σε διαφορετική γραμμή
+ls -t # Ταξινομεί τα περιεχόμενα του καταλόγου με βάσει την ημερομηνία
+ # τελευταίας τροποποίησης (σε φθίνουσα σειρά)
+ls -R # Εκτελεί την εντολή `ls` αναδρομικά στον τρέχων κατάλογο και σε όλους
+ # τους υποκαταλόγους του.
+
+# Τα αποτελέσματα μιας εντολής μπορούν να μεταβιβαστούν σε μιαν άλλη.
+# Η εντολή `grep` φιλτράρει τα δεδομένα που δέχεται βάσει μοτίβων.
+# Έτσι, μπορούμε να τυπώσουμε μια λίστα αρχείων κειμένου (.txt) στον τρέχων
+# κατάλογο:
+ls -l | grep "\.txt"
+
+# Μπορούμε να χρησιμοποιήσουμε την εντολή `cat` για να τυπώσουμε το περιεχόμενο
+# ενός ή περισσότερων αρχείων στην προεπιλεγμένη έξοδο (stdout):
+cat file.txt
+
+# Μπορούμε επίσης να διαβάσουμε το αρχείο μέσω της `cat`:
+Periexomena=$(cat file.txt)
+echo "ΑΡΧΗ ΤΟΥ ΑΡΧΕΙΟΥ\n$Periexomena\nΤΕΛΟΣ ΤΟΥ ΑΡΧΕΙΟΥ" # Ο χαρακτήρας "\n"
+ # δημιουργεί μια νέα
+ # γραμμή
+# => ΑΡΧΗ ΤΟΥ ΑΡΧΕΙΟΥ
+# => [περιεχόμενα του αρχείου file.txt]
+# => ΤΕΛΟΣ ΤΟΥ ΑΡΧΕΙΟΥ
+
+# Μπορούμε να χρησιμοποιήσουμε την εντολή `cp` για να αντιγράψουμε αρχεία ή
+# καταλόγους από ένα σημείο σε ένα άλλο.
+# Η εντολή `cp` δημιουργεί ΝΕΕΣ εκδοχές των πρωτοτύπων, το οποίο σημαίνει ότι
+# μια τροποποίηση του αντιγράφου δεν θα επηρεάσει το πρωτότυπο (και
+# αντιστρόφως).
+# Να σημειωθεί πως αν υπάρχει ήδη αρχείο ή κατάλογος με το ίδιο όνομα στην ίδια
+# θέση με το αντίγραφο, το αντίγραφο θα αντικαταστήσει το αρχείο/κατάλογο και
+# άρα τα δεδομένα του θα χαθούν.
+cp prototipo.txt antigrafo.txt
+cp -r prototipo/ antigrafo/ # Αναδρομική αντιγραφή (αντιγραφή όλων των
+ # περιεχομένων του καταλόγου prototipo/)
+
+# Ενημερωθείτε σχετικά με τις εντολές `scp` και `sftp` αν σχεδιάζετε να
+# αντιγράψετε αρχεία από έναν υπολογιστή σε έναν άλλο.
+# Η εντολή `scp` μοιάζει πολύ με την `cp`, ενώ η `sftp` είναι πιο διαδραστική.
+
+# Μπορούμε να χρησιμοποιήσουμε την εντολή `mv` για να μετακινήσουμε αρχεία ή
+# καταλόγους από μια θέση σε μια άλλη.
+# Η εντολή `mv` μοιάζει με την `cp`, με τη διαφορά ότι διαγράφει το πρωτότυπο.
+# Η `mv` χρησιμοποιείται επίσης για τη μετονομασία αρχείων!
+mv prototipo.txt prototipo2.txt
+
+# Δεδομένου του ότι η Bash δουλεύει στο πλαίσιο του τρέχοντος καταλόγου,
+# μπορεί να θελήσουμε να τρέξουμε κάποια εντολή σε κάποιον άλλο κατάλογο.
+# Η εντολή `cd` (Change Directory) μας επιτρέπει να αλλάξουμε θέση μέσα στο
+# σύστημα αρχείων:
+cd ~ # Μετατόπιση στον κατάλογο «home»
+cd # Αυτή η εντολή μας μετατοπίζει επίσης στον κατάλογο «home»
+cd .. # Μετατόπιση προς τα πάνω κατά έναν κατάλογο
+ # (για παράδειγμα, μετατόπιση από τη θέση /home/username/Downloads
+ # στη θέση /home/username)
+cd /home/username/Documents # Μετατόπιση προς έναν συγκεκριμένο κατάλογο
+cd ~/Documents/.. # Μετατόπιση προς τον κατάλογο «home»... σωστά;
+cd - # Μετατόπιση προς τον προηγούμενο κατάλογο
+# => /home/username/Documents
+
+# Μπορούμε να χρησιμοποιήσουμε subshells για να δουλέψουμε σε πολλούς
+# διαφορετικούς καταλόγους:
+(echo "Πρώτα, είμαι εδώ: $PWD") && (cd kapoiosKatalogos; echo "Έπειτα, είμαι εδώ: $PWD")
+pwd # Εδώ θα είμαστε στον πρώτο κατάλογο
+
+# Μπορούμε να χρησιμοποιήσουμε την εντολή `mkdir` για να δημιουργήσουμε νέους
+# καταλόγους.
+mkdir neosKatalogos
+# Η επιλογή `-p` επιτρέπει σε ενδιάμεσους καταλόγους να δημιουργηθούν αν
+# χρειάζεται.
+mkdir -p neosKatalogos/me/epipleon/katalogous
+# Αν οι ενδιάμεσοι κατάλογοι δεν υπήρχαν ήδη, η παραπάνω εντολή χωρίς την
+# επιλογή `-p` θα είχε επιστρέψει κάποιο λάθος.
+
+# Μπορούμε να διευθύνουμε τις εισόδους και εξόδους των εντολών (χρησιμοποιώντας
+# τα κανάλια stdin, stdout και stderr).
+# Για παράδειγμα, μπορούμε να «διαβάσουμε» από το stdin μέχρι να βρεθεί ένα
+# ^EOF$ (End Of File) και να αντικαταστήσουμε το περιεχόμενο του αρχείου
+# hello.py με τις γραμμές που διαβάσαμε έως και πριν το "EOF":
+cat > hello.py << EOF
+#!/usr/bin/env python
+from __future__ import print_function
+import sys
+print("#stdout", file=sys.stdout)
+print("#stderr", file=sys.stderr)
+for line in sys.stdin:
+ print(line, file=sys.stdout)
+EOF
+
+# Μπορούμε να τρέξουμε το πρόγραμμα Python «hello.py» με διάφορες
+# ανακατευθύνσεις χρησιμοποιώντας τα stdin, stdout και stderr:
+python hello.py < "eisodos.in" # Περνάμε το eisodos.in ως είσοδο στο πρόγραμμα
+
+python hello.py > "eksodos.out" # Ανακατευθύνουμε την έξοδο του προγράμματος
+ # προς το αρχείο eksodos.out
+
+python hello.py 2> "lathos.err" # ανακατευθύνουμε την έξοδο λάθους (stderr)
+ # προς το αρχείο lathos.err
+
+python hello.py > "eksodos-kai-lathos.log" 2>&1
+# Ανακατευθύνουμε την κανονική έξοδο (stdout) και την έξοδο λάθους (stderr)
+# προς το αρχείο eksodos-kai-lathos.log
+
+python hello.py > /dev/null 2>&1
+# Ανακατευθύνουμε όλες τις εξόδους προς τη «μαύρη τρύπα» που λέγεται /dev/null,
+# δηλαδή τίποτα δεν θα τυπωθεί στον τερματικό
+
+# Αν θέλετε να προσθέσετε την έξοδο σε κάποιο αρχείο αντί να διαγράψετε τα
+# περιεχόμενά του με τη νέα έξοδο, μπορείτε να χρησιμοποιήσετε τον τελεστή
+# `>>` αντί στη θέση του `>`:
+python hello.py >> "eksodos.out" 2>> "lathos.err"
+
+# Αντικατάσταση του αρχείου eksodos.out, προσθήκη στο αρχείο lathos.err, και
+# καταμέτρηση των γραμμών τους:
+info bash 'Basic Shell Features' 'Redirections' > eksodos.out 2>> lathos.err
+wc -l eksodos.out lathos.err
+
+# Μπορούμε να εκτελέσουμε μια εντολή και να τυπώσουμε τον file descriptor της
+# (https://en.wikipedia.org/wiki/File_descriptor)
+# Για παράδειγμα: /dev/fd/123
+# Δείτε επίσης: man fd
+echo <(echo "#καλημέρακόσμε")
+
+# Αντικατάσταση του περιεχομένου του αρχείου eksodos.out με το αλφαριθμητικό
+# «#καλημέρακόσμε»:
+cat > eksodos.out <(echo "#καλημέρακόσμε")
+echo "#καλημέρακόσμε" > eksodos.out
+echo "#καλημέρακόσμε" | cat > eksodos.out
+echo "#καλημέρακόσμε" | tee eksodos.out >/dev/null
+
+# Εκκαθάριση προσωρινών αρχείων με την επιλογή `-v` (verbose) (προσθέστε την
+# επιλογή `-i` για περισσότερη διάδραση)
+# ΠΡΟΣΟΧΗ: τα αποτελέσματα της εντολής `rm` είναι μόνιμα.
+rm -v eksodos.out lathos.err eksodos-kai-lathos.log
+rm -r tempDir/ # Αναδρομική διαγραφή
+
+# Οι εντολές μπορούν να αντικατασταθούν μέσα σε άλλες εντολές χρησιμοποιώντας
+# το μοτίβο $( ).
+# Το παράδειγμα που ακολουθεί τυπώνει τον αριθμό των αρχείων και των καταλόγων
+# στον τρέχων κατάλογο.
+echo "Υπάρχουν $(ls | wc -l) αντικείμενα εδώ."
+
+# Μπορούμε να επιτύχουμε το ίδιο αποτέλεσμα με τους χαρακτήρες ``, αλλά δεν
+# μπορούμε να τους χρησιμοποιήσουμε αναδρομικά (δηλαδή `` μέσα σε ``).
+# Ο προτεινόμενος τρόπος από την Bash είναι το μοτίβο $( ).
+echo "Υπάρχουν `ls | wc -l` αντικείμενα εδώ."
+
+# Η Bash έχει επίσης τη δομή `case` που δουλεύει παρόμοια με τη δομή switch
+# όπως στην Java ή την C++ για παράδειγμα:
+case "$Metavliti" in
+ # Λίστα μοτίβων για τις συνθήκες που θέλετε να ορίσετε:
+ 0) echo "Η μεταβλητή έχει ένα μηδενικό.";;
+ 1) echo "Η μεταβλητή έχει έναν άσσο.";;
+ *) echo "Η μεταβλητή δεν είναι αόριστη (null).";;
+esac
+
+# Οι βρόγχοι `for` εκτελούνται τόσες φορές όσο είναι το πλήθος των παραμέτρων
+# που τους δίνονται:
+# Το περιεχόμενο της μεταβλητής $Metavliti τυπώνεται τρεις φορές.
+for Metavliti in {1..3}
+do
+ echo "$Metavliti"
+done
+# => 1
+# => 2
+# => 3
+
+# Μπορούμε επίσης να το γράψουμε πιο «παραδοσιακά»:
+for ((a=1; a <= 3; a++))
+do
+ echo $a
+done
+# => 1
+# => 2
+# => 3
+
+# Μπορούμε επίσης να περάσουμε αρχεία ως παραμέτρους.
+# Το παράδειγμα που ακολουθεί θα τρέξει την εντολή `cat` με τα αρχεία file1
+# και file2:
+for Metavliti in file1 file2
+do
+ cat "$Metavliti"
+done
+
+# Μπορούμε ακόμα να χρησιμοποιήσουμε την έξοδο μας εντολής.
+# Το παράδειγμα που ακολουθεί θα τρέξει την εντολή `cat` με την έξοδο της
+# εντολής `ls`.
+for Output in $(ls)
+do
+ cat "$Output"
+done
+
+# Ο βρόγχος `while` έχει ως εξής:
+while [ true ]
+do
+ echo "το «σώμα» του βρόγχου μπαίνει εδώ..."
+ break
+done
+# => το «σώμα» του βρόγχου μπαίνει εδώ...
+
+# Μπορούμε επίσης να ορίσουμε συναρτήσεις, ως εξής:
+function synartisi ()
+{
+ echo "Οι παράμετροι συναρτήσεων δουλεύουν όπως αυτές των προγραμμάτων: $@"
+ echo "Και: $1 $2..."
+ echo "Αυτή είναι μια συνάρτηση"
+ return 0
+}
+# Ας καλέσουμε την συνάρτηση `synartisi` με δύο παραμέτρους, param1 και param2
+synartisi param1 param2
+# => Οι παράμετροι συναρτήσεων δουλεύουν όπως αυτές των προγραμμάτων: param1 param2
+# => Και: param1 param2...
+# => Αυτή είναι μια συνάρτηση
+
+# Ή επίσης:
+synartisi2 ()
+{
+ echo "Ένας άλλος τρόπος να ορίσουμε συναρτήσεις!"
+ return 0
+}
+# Ας καλέσουμε την συνάρτηση `synartisi2` χωρίς παραμέτρους:
+synartisi2 # => Ένας άλλος τρόπος να ορίσουμε συναρτήσεις!
+
+# Ας καλέσουμε την πρώτη συνάρτηση:
+synartisi "Το όνομά μου είναι" $Onoma
+
+# Υπάρχουν πολλές χρήσιμες εντολές που μπορείτε να μάθετε.
+# Για παράδειγμα, αυτή που ακολουθεί τυπώνει τις 10 τελευταίες γραμμές του
+# αρχείου file.txt:
+tail -n 10 file.txt
+
+# Ενώ αυτή τυπώνει τις 10 πρώτες:
+head -n 10 file.txt
+
+# Αυτή ταξινομεί τις γραμμές:
+sort file.txt
+
+# Αυτή αναφέρει ή παραλείπει τις γραμμές που επαναλαμβάνονται (η επιλογή
+# -d τις αναφέρει):
+uniq -d file.txt
+
+# Αυτή τυπώνει μόνο ό,τι βρίσκεται πριν τον πρώτο χαρακτήρα «,» σε κάθε γραμμή:
+cut -d ',' -f 1 file.txt
+
+# Αυτή αντικαθιστά κάθε εμφάνιση της λέξης «οκ» με τη λέξη «τέλεια» στο αρχείο
+# file.txt (δέχεται επίσης μοτίβα regex):
+sed -i 's/οκ/τέλεια/g' file.txt
+
+# Αυτή τυπώνει στο stdout όλες τις γραμμές που είναι συμβατές με κάποιο
+# συγκεκριμένο μοτίβο regex.
+# Για παράδειγμα, όλες τις γραμμές που ξεκινούν με «καλημέρα» και τελειώνουν με
+# «καληνύχτα»:
+grep "^καλημέρα.*καληνύχτα$" file.txt
+
+# Η επιλογή `-c` θα τυπώσει τον αριθμό των γραμμών που περιέχουν το μοτίβο:
+grep -c "^καλημέρα.*καληνύχτα$" file.txt
+
+# Άλλες χρήσιμες επιλογές:
+grep -r "^καλημέρα.*καληνύχτα$" someDir/ # Αναδρομική εκτέλεση μέσα σε κάποιο κατάλογο
+grep -n "^καλημέρα.*καληνύχτα$" file.txt # Τυπώνει επίσης τον αριθμό των γραμμών
+grep -rI "^καλημέρα.*καληνύχτα$" someDir/ # Αναδρομική εκτέλεση αγνοώντας τα αρχεία binary
+
+# Η ίδια εντολή, αλλά τώρα αγνοώντας τις γραμμές που περιέχουν «αντίο»
+grep "^καλημέρα.*καληνύχτα$" file.txt | grep -v "αντίο"
+
+# Αν θέλετε να ψάξετε κυριολεκτικά για ένα αλφαριθμητικό, και όχι για κάποιο
+# μοτίβο, μπορείτε να χρησιμοποιήσετε την εντολή `fgrep` (ή `grep -F`):
+fgrep "καλημέρα" file.txt
+
+# Η εντολή `trap` επιτρέπει την εκτέλεση μιας εντολής μόλις το πρόγραμμά μας
+# λάβει κάποιο σήμα. Στο παράδειγμα που ακολουθεί, η εντολή `trap` θα
+# εκτελέσει την εντολή `rm` αν λάβει κάποιο από τα τρία σήματα που ακολουθούν
+# (SIGHUP, SIGINT, SIGTERM):
+trap "rm $TEMP_FILE; exit" SIGHUP SIGINT SIGTERM
+
+# Η εντολή `sudo` (SuperUser Do) χρησιμοποιείται για να εκτελέσουμε εντολές
+# με προνόμια υπερχρήστη (superuser):
+ONOMA1=$(whoami)
+ONOMA2=$(sudo whoami)
+echo "Ήμουν ο $ONOMA1, και έπειτα έγινα ο πιο ισχυρός $ONOMA2"
+
+# Διαβάστε την ενσωματωμένη documentation της Bash χρησιμοποιώντας την εντολή
+# `help`:
+help
+help help
+help for
+help return
+help source
+help .
+
+# Διαβάστε τα manpages με την εντολή `man`:
+apropos bash
+man 1 bash
+man bash
+
+# Διαβάστε επίσης την info documentation με την εντολή `info`:
+apropos info | grep '^info.*('
+man info
+info info
+info 5 info
+info bash
+info bash 'Bash Features'
+info bash 6
+info --apropos bash
+```
diff --git a/el-gr/html-gr.html.markdown b/el-gr/html-gr.html.markdown
new file mode 100644
index 00000000..0ca6e326
--- /dev/null
+++ b/el-gr/html-gr.html.markdown
@@ -0,0 +1,193 @@
+---
+language: html
+filename: learnhtml-gr.html
+contributors:
+ - ["Dimitri Kokkonis", "https://github.com/kokkonisd"]
+lang: el-gr
+---
+
+Το ακρώνυμο HTML σημαίνει HyperText Markup Language.
+
+Είναι μια γλώσσα που μας επιτρέπει να δημιουργήσουμε σελίδες για το διαδίκτυο.
+Είναι μια γλώσσα σήμανσης (markup), και μας επιτρέπει να γράψουμε ιστοσελίδες
+χρησιμοποιώντας κώδικα για να υποδείξουμε πώς πρέπει να εμφανίζεται το κείμενο
+και τα δεδομένα στη σελίδα. Στην πραγματικότητα, τα αρχεία HTML είναι απλά
+αρχεία κειμένου.
+
+Τι σημαίνει όμως «γλώσσα σήμανσης»; Είναι μια μέθοδος οργάνωσης των δεδομένων
+της σελίδας, που λειτουργεί μέσω ετικετών (tags) που «ανοίγουν» ή «κλείνουν».
+Αυτή η σήμανση έχει ως σκοπό να δώσει κάποια συγκεκριμένη σημασία στο κείμενο
+που περιβάλλει. Όπως και οι περισσότερες γλώσσες υπολογιστών, η HTML έχει
+πολλές διαφορετικές εκδοχές. Εδώ θα μιλήσουμε για την HTML5.
+
+**ΣΗΜΕΙΩΣΗ :** Μπορείτε να δοκιμάσετε τις ετικέτες και τα στοιχεία που
+παρουσιάζονται εδώ σε ένα σάιτ όπως το [codepen](http://codepen.io/pen/), ούτως
+ώστε να δείτε τα αποτελέσματα που παράγουν, να καταλάβετε πώς δουλεύουν και να
+εξοικιωθείτε με την γλώσσα. Αυτό το άρθρο ασχολείται κυρίως με την σύνταξη της
+HTML και κάποιες χρήσιμες συμβουλές σχετικά με αυτήν.
+
+
+```html
+<!-- Τα σχόλια είναι περικυκλωμένα όπως αυτή η γραμμή! -->
+
+<!--
+ Τα
+ σχόλια
+ μπορούν
+ να
+ επεκταθούν
+ σε
+ πολλαπλές
+ γραμμές!
+-->
+
+<!-- #################### Οι ετικέτες #################### -->
+
+<!--Ορίστε ένα παράδειγμα αρχείου HTML, το οποίο θα αναλύσουμε. -->
+
+
+<!doctype html>
+ <html>
+ <head>
+ <title>Η σελίδα μου</title>
+ </head>
+ <body>
+ <h1>Καλημέρα, κόσμε!</h1>
+ <a href="http://codepen.io/anon/pen/xwjLbZ">
+ Δείτε τι κάνει αυτό
+ </a>
+ <p>Αυτή είναι μια παράγραφος.</p>
+ <p>Αυτή είναι μια άλλη παράγραφος.</p>
+ <ul>
+ <li>Αυτό είναι ένα αντικείμενο μέσα σε μια μη-αριθμημένη λίστα
+ (bullet list)</li>
+ <li>Αυτό είναι ένα άλλο αντικείμενο</li>
+ <li>Και αυτό είναι το τελευταίο αντικείμενο της λίστας</li>
+ </ul>
+ </body>
+ </html>
+
+<!--
+ Ένα αρχείο HTML πάντα ξεκινά υποδεικνύοντας στον περιηγητή πως η σελίδα
+ είναι γραμμένη με HTML.
+-->
+<!doctype html>
+
+<!-- Μετά από αυτό, ξεκινά ανοίγοντας μια ετικέτα <html>. -->
+<html>
+
+<!-- την οποία πρέπει να κλείσουμε στο τέλος της σελίδας γράφοντας </html>. -->
+</html>
+
+<!-- Τίποτα δεν πρέπει να βρίσκεται μετά από αυτη την τελευταία ετικέτα. -->
+
+
+<!-- Ανάμεσα από τις ετικέτες <html> και </html>, βρίσκουμε: -->
+
+<!-- Μια επικεφαλίδα ορισμένη από την ετικέτα <head> (πρέπει να την κλείσουμε
+με την ετικέτα </head>) -->
+<!--
+ Η επικεφαλίδα περιέχει κάποια περιγραφή και επιπρόσθετες πληροφορίες που δεν
+ εμφανίζονται· είναι τα λεγόμενα μεταδεδομένα (metadata).
+-->
+
+<head>
+ <!--
+ Η ετικέτα <title> υποδεικνύει στον περιηγητή τον τίτλο που πρέπει να
+ εμφανιστεί στην μπάρα τίτλου και στο όνομα της καρτέλας.
+ -->
+ <title>Η σελίδα μου</title>
+</head>
+
+<!-- Μετά την ενότητα <head>, βρίσκουμε την ετικέτα <body> -->
+<!-- Μέχρι αυτό το σημείο, τίποτα απ' όσα έχουμε περιγράψει δεν θα εμφανιστούν
+στο παράθυρο του περιηγητή. -->
+<!-- Πρέπει να συμπληρώσουμε το «σώμα» της σελίδας με το περιεχόμενο που
+θέλουμε να εμφανίζεται. -->
+
+<body>
+ <!-- Η ετικέτα h1 δημιουργεί έναν τίτλο/επικεφαλίδα. -->
+ <h1>Καλημέρα, κόσμε!</h1>
+ <!--
+ Υπάρχουν επίσης υπότιτλοι/υποκεφαλίδες, από την πιο σημαντική (h2)
+ μέχρι την πιο μικρή και ειδική (h6).
+ -->
+
+ <!-- Ένας υπερσύνδεσμος προς την διεύθυνση που δίνεται από την παράμετρο
+ href="": -->
+ <a href="http://codepen.io/anon/pen/xwjLbZ">
+ Δείτε τι κάνει αυτό
+ </a>
+
+ <!-- Η ετικέτα <p> μας επιτρέπει να εισάγουμε κείμενο στην σελίδα μας. -->
+ <p>Αυτή είναι μια παράγραφος.</p>
+ <p>Αυτή είναι μια άλλη παράγραφος.</p>
+
+ <!-- Η ετικέτα <ul> δημιουργεί μια μη-αριθμημένη λίστα. -->
+ <!--
+ Για μια αριθμημένη λίστα χρησιμοποιούμε την ετικέτα <ol>, που θα μας
+ δώσει 1. για το πρώτο στοιχείο, 2. για το δεύτερο κτλ.
+ -->
+ <ul>
+ <li>Αυτό είναι ένα αντικείμενο μέσα σε μια μη-αριθμημένη λίστα (bullet
+ list)</li>
+ <li>Αυτό είναι ένα άλλο αντικείμενο</li>
+ <li>Και αυτό είναι το τελευταίο αντικείμενο της λίστας</li>
+ </ul>
+</body>
+
+<!-- Αυτό ήταν όλο, είναι εύκολο να δημιουργήσουμε αρχεία HTML. -->
+
+<!-- Ωστόσο έχουμε την δυνατότητα να επιλέξουμε ανάμεσα σε πολλές ακόμη
+ετικέτες HTML. -->
+
+<!-- Η ετικέτα <img /> χρησιμοποιείται για να εισάγουμε μια εικόνα. -->
+<!--
+ Η πηγή της εικόνας υποδεικνύεται μέσω της παραμέτρου src="".
+ Η πηγή μπορεί να είναι μια διεύθυνση (URL) ή ακόμα και μια τοπική διεύθυνση
+ ενός αρχείου που βρίσκεται στον υπολογιστή μας.
+-->
+<img src="http://i.imgur.com/XWG0O.gif"/>
+
+<!-- Υπάρχει επίσης η δυνατότητα να δημιουργήσουμε πίνακες. -->
+
+<!-- Ανοίγουμε μια ετικέτα <table>. -->
+<table>
+
+ <!-- Η ετικέτα <tr> μας επιτρέπει να δημιουργήσουμε μια γραμμή
+ στον πίνακα. -->
+ <tr>
+
+ <!-- Η ετικέτα <th> μας επιτρέπει να δώσουμε έναν τίτλο σε μια στήλη
+ του πίνακα -->
+ <th>Πρώτος τίτλος</th>
+ <th>Δεύτερος τίτλος</th>
+ </tr>
+
+ <tr>
+
+ <!-- Η ετικέτα <td> μας επιτρέπει να δημιουργήσουμε ένα κελί μέσα στον
+ πίνακα. -->
+ <td>Πρώτη γραμμή, πρώτη στήλη</td>
+ <td>Πρώτη γραμμή, δεύτερη στήλη</td>
+ </tr>
+
+ <tr>
+ <td>Δεύτερη γραμμή, πρώτη στήλη</td>
+ <td>Δεύτερη γραμμή, δεύτερη στήλη</td>
+ </tr>
+</table>
+
+```
+
+## Χρήση
+
+Η HTML γράφεται σε αρχεία με την κατάληξη `.html` ή `.htm`. Ο τύπος MIME της
+HTML είναι
+`text/html`.
+**H HTML ΔΕΝ είναι γλώσσα προγραμματισμού.**
+## Μάθετε περισσότερα
+
+* [βικιπαίδεια](https://el.wikipedia.org/wiki/HTML)
+* [Μάθημα HTML](https://developer.mozilla.org/en-US/docs/Web/HTML)
+* [W3School](http://www.w3schools.com/html/html_intro.asp)
diff --git a/el-gr/json-gr.html.markdown b/el-gr/json-gr.html.markdown
new file mode 100644
index 00000000..6f30d819
--- /dev/null
+++ b/el-gr/json-gr.html.markdown
@@ -0,0 +1,60 @@
+---
+language: json
+filename: json-gr.html.markdown
+contributors:
+ - ["Anna Harren", "https://github.com/iirelu"]
+ - ["Marco Scannadinari", "https://github.com/marcoms"]
+ - ["himanshu", "https://github.com/himanshu81494"]
+ - ["Michael Neth", "https://github.com/infernocloud"]
+ - ["Athanasios Emmanouilidis", "https://github.com/athanasiosem"]
+translators:
+ - ["Athanasios Emmanouilidis", "https://github.com/athanasiosem"]
+lang: el-gr
+---
+
+Το JSON (JavaScript Object Notation) είναι ένα πολύ απλό και ελαφρύ μορφότυπο ανταλλαγής δεδομένων. Όπως αναφέρεται και στην ιστοσελίδα [json.org](http://json.org), το JSON διαβάζεται και γράφεται εύκολα από τους ανθρώπους όπως επίσης αναλύεται και παράγεται εύκολα από τις μηχανές.
+
+Ένα κομμάτι JSON δηλώνει ένα από τα παρακάτω:
+
+* Μια συλλογή από ζευγάρια ονομάτων/τιμών (collection of name/value pairs) (`{ }`). Σε πολλές γλώσσες προγραμματισμού αυτό αντιστοιχεί σε ένα αντικείμενo (object), μία εγγραφή (record), μία δομή (struct), ένα λεξικό (dictionary), ένα πίνακα κατακερματισμού (hash table), μια λίστα αριθμημένη με κλειδιά (keyed list) ή έναν πίνακα συσχέτισης (associative array).
+
+* Μια ταξινομημένη λίστα τιμών (`[ ]`). Σε πολλές γλώσσες προγραμματισμού αυτό αντιστοιχεί σε ένα πίνακα (array), σε ένα διάνυσμα (vector), μία λίστα (list), ή μια ακολουθία (sequence).
+
+Αν και το JSON στην καθαρότερη του μορφή δεν έχει σχόλια (comments), οι περισσότεροι parsers θα δεχτούν σχόλια (comments) του στύλ της γλώσσας C (`//`, `/* */`). Κάποιοι parsers επίσης ανέχονται ένα εξτρά κόμμα στο τέλος (δηλαδή ένα κόμα μετά το τελευταίο στοιχείο ενός πίνακα ή μετά την τελευταία ιδιότητα ενός αντικειμένου) αλλά καλύτερα θα είναι να αποφεύγεται η χρήση του για χάρη της συμβατότητας.
+
+Υποστηριζόμενοι τύποι δεδομένων (data types):
+
+* Συμβολοσειρές (Strings): `"Γεια"`, `"\"Περικοπή.\""`, `"\u0abe"`, `"Νέα γραμμή.\n"`
+* Αριθμοί (Numbers): `23`, `0.11`, `12e10`, `3.141e-10`, `1.23e+4`
+* Αντικείμενα (Objects): `{ "κλειδί": "τιμή" }`
+* Πίνακες (Arrays): `["Τιμή1","Τιμή2","Τιμή3",]`
+* Διάφορα : `true`, `false`, `null`
+
+```json
+{
+ "κλειδί": "τιμή",
+ "κλειδιά": "πρέπει πάντα να περιβάλονται από διπλά quotes",
+ "νούμερα": 0,
+ "συμβολοσειρές": "Γεια, κόσμε. Οι χαρακτήρες unicode επιτρέπονται, καθώς και το \"escaping\".",
+ "διαδικές τιμές": true,
+ "κενό": null,
+ "μεγάλοι αριθμοί": 1.2e+100,
+ "αντικείμενα": {
+ "σχόλια": "Σήμερα έφαγα ένα μήλο.",
+ "πίνακες": [0, 1, 2, 3, "Οι πίνακες μπορούνε να περιλαμβάνουν διαφορετικούς τύπους δεδομένων", 5],
+ "αντικείμενα μέσα σε αντικείμενα": {
+ "σχόλια": "Τα αντικείμενα μπορούνε να εσωκλύουν αντικείμενα."
+ }
+ },
+
+
+ "κενό διάστημα": "Αναγνωρίζεται χωρίς πρόβλημα αλλά καλύτερα να αποφεύγεται η χρήση του.",
+ "αυτό ήταν": "Πλέον γνωρίζετε πως μπορείτε να χρησιμοποιήσετε το JSON."
+}
+```
+
+## Περαιτέρω διάβασμα
+
+* [JSON.org](http://json.org)
+
+* [JSON Tutorial](https://www.youtube.com/watch?v=wI1CWzNtE-M)
diff --git a/elisp.html.markdown b/elisp.html.markdown
index 518ad985..f839dac0 100644
--- a/elisp.html.markdown
+++ b/elisp.html.markdown
@@ -281,7 +281,7 @@ filename: learn-emacs-lisp.el
;; 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:
+;; (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.
@@ -295,7 +295,7 @@ filename: learn-emacs-lisp.el
(mapcar 'hello list-of-names)
(goto-char (point-min))
;; Replace "Hello" by "Bonjour"
- (while (search-forward "Hello" nil 't)
+ (while (search-forward "Hello" nil t)
(replace-match "Bonjour"))
(other-window 1))
@@ -306,7 +306,7 @@ filename: learn-emacs-lisp.el
(defun boldify-names ()
(switch-to-buffer-other-window "*test*")
(goto-char (point-min))
- (while (re-search-forward "Bonjour \\(.+\\)!" nil 't)
+ (while (re-search-forward "Bonjour \\(.+\\)!" nil t)
(add-text-properties (match-beginning 1)
(match-end 1)
(list 'face 'bold)))
diff --git a/elixir.html.markdown b/elixir.html.markdown
index e82509e7..7af29202 100644
--- a/elixir.html.markdown
+++ b/elixir.html.markdown
@@ -452,7 +452,7 @@ Agent.update(my_agent, fn colors -> ["blue" | colors] end)
## References
* [Getting started guide](http://elixir-lang.org/getting-started/introduction.html) from the [Elixir website](http://elixir-lang.org)
-* [Elixir Documentation](http://elixir-lang.org/docs/master/)
+* [Elixir Documentation](https://elixir-lang.org/docs.html)
* ["Programming Elixir"](https://pragprog.com/book/elixir/programming-elixir) by Dave Thomas
* [Elixir Cheat Sheet](http://media.pragprog.com/titles/elixir/ElixirCheat.pdf)
* ["Learn You Some Erlang for Great Good!"](http://learnyousomeerlang.com/) by Fred Hebert
diff --git a/emacs.html.markdown b/emacs.html.markdown
new file mode 100644
index 00000000..ff4d3c03
--- /dev/null
+++ b/emacs.html.markdown
@@ -0,0 +1,320 @@
+---
+category: tool
+tool: emacs
+filename: emacs.txt
+contributors:
+ - ["Joseph Riad", "https://github.com/Joseph-Riad"]
+---
+
+Emacs started its life as ["the extensible, customizable display
+editor"](https://www.gnu.org/software/emacs/emacs-paper.html) and grew
+over the years into a full-blown ecosystem. Many tasks, usually
+relegated to a diverse set of tools can be accomplished from within
+Emacs in a consistent, familiar interface. Examples include directory
+management, viewing PDF documents, editing files over SSH, managing git
+repos,… (the list is quite long). In short, Emacs is yours to make of it
+what you will: the spectrum of users varies from those who use it to
+edit text files to extreme purists who use it to virtually replace their
+operating system.
+
+Emacs is extensible via a specialized dialect of Lisp known as Emacs
+Lisp (Elisp) which has a lot of macros geared towards editing text and
+managing text buffers. Any key (combination) you use in Emacs is bound
+to an Emacs Lisp function and may be remapped to any other function,
+including ones you write
+yourself.
+
+# Key Notation
+
+``` text
+The Emacs manual and the community in general uses a convention to refer to different key combinations used within Emacs. Specifically, Emacs has the notion of a "modifier key" that is pressed along with another key to modify its action.
+
+An example of this notation is "C-c". In this key combination "C" is the modifier and stands for the "Ctrl" key and "c" is the key whose action is being modified (the literal character "c").
+
+The modifier shorthand:
+"C-" --> The "CTRL" key
+"M-" --> The "Meta" key (usually, the "Alt" key)
+"s-" --> The "Super" key (the "Cmd" key on Macs and the "Windows" key on PCs)
+
+There are other, less commonly used modifiers that I will not get into here.
+
+The key combination "C-x C-s" means you press "Ctrl+x" followed by "Ctrl+s"
+
+In addition to the above modifiers, the special keys "Esc", "Return (Enter)" and "Shift" are denoted by "ESC", "RET" and "S", respectively.
+```
+
+# Basic Emacs Concepts
+
+Here, I discuss some basic Emacs concepts and terminology that may be
+confusing to newcomers (especially to people used to Vim terminology)
+
+ - A bunch of text that Emacs is editing is known as a **buffer**
+ - A buffer does not necessarily correspond to an actual file on disk.
+ It may be just a bunch of text in memory.
+ - When a buffer corresponds to a file on disk, we say that the buffer
+ is **visiting** that file.
+ - Emacs typically has many buffers open at once.
+ - The display of Emacs may be split into different **windows** (not to
+ be confused with your operating system's windows: the operating
+ system window for Emacs can have multiple Emacs windows inside it).
+ - An operating system window for Emacs is called an Emacs **frame**.
+ Thus, when the Emacs manual talks about opening a new frame, this
+ essentially means opening a new OS *window* containing an(other)
+ instance of Emacs.
+ - The concepts conventionally known as cutting and pasting are
+ referred to as **killing** and **yanking**, respectively in Emacs
+ parlance.
+ - The current position of the cursor is called the **point** in Emacs.
+ Technically, **point** is defined as the position right before the
+ character where the cursor currently is.
+ - Finally, each buffer may have several **modes** associated with it:
+ a **major mode** and possibly several **minor modes**.
+ - The **major mode** defines the main behavior of Emacs in the
+ currently selected buffer. This can be roughly thought of as the
+ file type. For example, if you're editing a Python file, the major
+ mode is (by default) `python-mode` which causes Emacs to highlight
+ Python syntax and automatically indent and outdent your code blocks
+ as syntactically required by your Python code.
+ - **Minor modes** define subtle changes in behavior and several minor
+ modes may be active at once in the same buffer. An example minor
+ mode is `flyspell-mode` which automatically highlights spelling
+ errors in your
+buffer.
+
+# Navigation Basics
+
+``` text
+The GUI version of Emacs can be navigated with the mouse like you would expect from a conventional GUI text editor.
+
+The aim here is to focus on navigation solely using the keyboard as this enhances productivity immensely.
+
+
+* Line movement
+
+C-n --> Next line
+C-p --> Previous line
+
+* Character movement
+
+C-f --> Go forward one character
+C-b --> Go backward one character
+
+* Word movement
+
+M-f --> Go forward one word
+M-b --> Go backward one word
+
+* Sentence movement
+
+M-a --> Move to the beginning of the sentence
+M-e --> Move to the end of the sentence
+
+* Beginning and end of line
+
+C-a --> Move to the beginning of the line
+C-e --> Move to the end of the line
+
+* Beginning and end of buffer
+
+M-< ("Meta+Shift+,") --> Go to the beginning of the buffer
+M-> ("Meta+Shift+.") --> Go to the end of the buffer
+
+* Screen movement
+
+C-v --> Scroll down by one screen-full (the last two lines of the previous screen are kept as overlap for a smoother transition)
+M-v --> Scroll up by one screen-full (same as above but with the first two lines)
+
+* Centering the screen
+
+C-l --> Move current line to the screen's center
+
+The above key combination actually cycles through different states depending on how many times it's been pressed.
+
+C-l --> Move current line to the screen's center
+C-l C-l --> Move current line to the top of the screen
+C-l C-l C-l --> Restore the position of the current line to where it was before the first C-l was pressed
+
+If you press "C-l" a 4th time, it cycles back to centering the current line.
+
+* Repeating movement commands
+
+Most movement commands take a numerical prefix argument that says "repeat the following command that many times".
+
+Example:
+
+C-u 3 C-p --> Go up 3 lines
+C-u 5 C-f --> Go forward 5 characters
+
+One notable exception are the screen scrolling commands:
+
+C-u 3 C-v --> Scroll downward 3 lines (maintaining the position of the cursor)
+```
+
+Bonus: many of the above navigation commands are the default navigation
+commands in Bash (e.g. pressing "C-b" while entering a Bash command
+takes you back one
+character).
+
+# File editing basics
+
+``` text
+* Quitting Emacs [ Now you can't say you don't know how to quit Emacs :-) ]
+
+C-x C-c --> Quit Emacs and get prompted to save any unsaved files (buffers not visiting a file will simply be discarded unless you're running in client-server mode)
+
+* Saving a buffer
+
+C-x C-s --> Save the current buffer. If not visiting a file, it will prompt you for a file name to use to save the buffer.
+
+* Searching within a buffer
+
+C-s --> Search forwards within the buffer. Search is incremental and case-insensitive by default.
+ Press C-s to move to the next match.
+ If you press "RET", point is moved to the currently highlighted word and the search ends.
+C-r --> Same as C-s except it searches backward
+
+C-_ or C-/ --> Undo the last action. Keep pressing it to move up the undo tree.
+C-? or M-_ --> Redo the previous change
+
+The "undo" and "redo" commands can take prefix numerical arguments to undo or redo that many actions:
+
+C-u 3 C-_ --> Undo the last 3 changes.
+```
+
+# Executing Elisp Functions
+
+``` text
+You can execute any currently loaded Elisp functions (including ones you have written yourself) via "M-x"
+
+M-x RET --> Prompts you for name of function to execute (Tab completion is available).
+
+Example:
+
+M-x RET search-forward-regexp RET --> Prompts you for a regular expression and searches forward in the buffer for it
+```
+
+# Emacs Configuration
+
+Emacs is configured using Elisp. On startup, it looks for a
+configuration file either in `~/.emacs` or `~/.emacs.d/init.el` where
+`~` refers to your home directory. If you're on Windows, consult [this
+article](https://www.gnu.org/software/emacs/manual/html_node/efaq-w32/Location-of-init-file.html)
+for the appropriate location of your configuration file.
+
+# Vim inside Emacs
+
+If you are considering the transition from Vim to Emacs and you're put
+off by the non-modal nature of Emacs editing, there is an Emacs
+extension known as `evil-mode` which lets you have many Vim concepts
+inside Emacs. Here are some things added to Emacs by `evil-mode`:
+
+ - Modal editing: you get normal, insert, visual and block visual modes
+ like Vim. In addition, you get an "Emacs" mode where movement and
+ navigation follow the Emacs bindings.
+ - Same movement keys as Vim in normal mode
+ - Leader key combinations
+ - Pressing ":" in normal mode allows you to execute commands
+ (including system commands)
+
+In my own experience, `evil-mode` helps make the transition seamless and
+allows you to blend the arguably more intuitive and ergonomic
+keybindings of Vim with the unbridled power of Emacs for a truly
+superior editing experience.
+
+# Discoverable Help
+
+Emacs features a pretty powerful help system that allows you to discover
+new functionality all the
+time.
+
+``` text
+Obtaining help on specific topics. Tab completion is available for function and variable names.
+
+C-h f RET --> Prompts you for the name of an elisp function and
+ displays help text on it along with a clickable link
+ to its source code.
+C-h v RET --> Same as above with variables
+
+C-h k RET --> Allows you to enter a key combination and displays the
+ name of the elisp function bound to it.
+
+Searching for help:
+
+C-h a --> Prompts you for a string to search for a command in the
+ help system. Similar to the 'apropos' or 'man -k'
+ commands in Unix systems.
+
+Starting a tutorial:
+
+C-h C-t --> Starts a tutorial designed to familiarize you with
+ basic Emacs functionality.
+```
+
+# Emacs "Killer Apps"
+
+As I hinted above, Emacs functionality goes way beyond being a mere text
+editor. I will list here a couple of Emacs "apps" that are fairly
+powerful and popular and may interest you in and of themselves.
+
+## Org
+
+Technnically, `org-mode`, a major mode for buffer editing that provides
+organizational tools. It is very difficult to succinctly describe what
+Org can do because it's a behemoth of a tool that has many diverse uses
+to different people. I will attempt to describe the main features I use
+briefly.
+
+ - Divide your file into sections and sub-sections for easy outlining
+ and organizing of concepts.
+ - Different headings in the outline are foldable/expandable so that
+ you can focus on what you need to focus on and eliminate
+ distractions.
+ - You can maintain a TODO list within Org
+ - You can compile TODO lists from many files into an agenda
+ - Track the time you spend on each TODO task
+ - Manage tables in plain text (including spreadsheet-like
+ capabilities)
+ - Using the extension `org-babel`, write and execute code blocks in
+ your file. The results are captured and are re-usable within the
+ file itself. Think Jupyter notebook for any language.
+ - Display inline images and LaTeX formulas as images within your file
+ (makes for a great note-taking system and/or personal wiki)
+ - Export your file into many different formats (LaTeX, PDF, html,…)
+
+Org mode is a very powerful tool to add to your productivity arsenal
+and, on a personal note, was the reason that caused me to start using
+Emacs after years of using Vim.
+
+## Magit
+
+This is a frontend to `git` from within Emacs. It features a very
+intuitive and discoverable interface, yet exposes very powerful
+functionality that allows you to manage commits at the chunk level,
+inspect diffs, rebase, cherry-pick, … all from within the comfort of
+your own editor.
+
+# A Word of Advice
+
+If you are considering using Emacs, a common trap that beginning users
+fall into is to copy someone else's configuration file and use it as is.
+I highly recommend against doing this for several reasons:
+
+ - It will discourage you from learning and finding things out for
+ yourself
+ - Someone else's configuration will probably contain many things
+ relevant to them that you won't need or ever use.
+ - It defeats the purpose of having a customizable text editor that can
+ fit your own needs.
+
+What I encourage you to do is to look at other people's configurations
+and seek to understand them and adapt only what makes sense to you. You
+can find out about new features of Emacs through many YouTube videos,
+screencasts or blog posts and then learn for yourself how to add them to
+your configuration and workflow. This way, you grow your configuration
+incrementally while increasing your knowledge of Emacs along the way.
+
+# Additional Resources
+
+ - [The GNU Emacs Manual](https://www.gnu.org/software/emacs/manual/emacs.html)
+ - [Emacs Stack Exchange](https://emacs.stackexchange.com/)
+ - [Emacs Wiki](https://www.emacswiki.org/emacs/EmacsWiki)
diff --git a/es-es/awk-es.html.markdown b/es-es/awk-es.html.markdown
index 0516ea92..8da8f024 100644
--- a/es-es/awk-es.html.markdown
+++ b/es-es/awk-es.html.markdown
@@ -1,5 +1,6 @@
---
-language: awk
+category: tool
+tool: awk
filename: learnawk-es.awk
contributors:
- ["Marshall Mason", "http://github.com/marshallmason"]
diff --git a/es-es/common-lisp-es.html.markdown b/es-es/common-lisp-es.html.markdown
new file mode 100644
index 00000000..526ea621
--- /dev/null
+++ b/es-es/common-lisp-es.html.markdown
@@ -0,0 +1,692 @@
+---
+
+language: "Common Lisp"
+filename: commonlisp-es.lisp
+contributors:
+ - ["Paul Nathan", "https://github.com/pnathan"]
+ - ["Rommel Martinez", "https://ebzzry.io"]
+translators:
+ - ["ivanchoff", "https://github.com/ivanchoff"]
+ - ["Andre Polykanine", "https://github.com/Menelion"]
+lang: es-es
+---
+
+Common Lisp es un lenguaje de proposito general y multiparadigma adecuado para una amplia variedad
+de aplicaciones en la industria. Es frecuentemente referenciado como un lenguaje de programación
+programable.
+
+EL punto de inicio clásico es [Practical Common Lisp](http://www.gigamonkeys.com/book/). Otro libro
+popular y reciente es [Land of Lisp](http://landoflisp.com/). Un nuevo libro acerca de las mejores
+prácticas, [Common Lisp Recipes](http://weitz.de/cl-recipes/), fue publicado recientemente.
+
+```lisp
+
+;;;-----------------------------------------------------------------------------
+;;; 0. Sintaxis
+;;;-----------------------------------------------------------------------------
+
+;;; Forma general
+
+;;; CL tiene dos piezas fundamentales en su sintaxis: ATOM y S-EXPRESSION.
+;;; Típicamente, S-expressions agrupadas son llamadas `forms`.
+
+10 ; un atom; se evalua a sí mismo
+:thing ; otro atom; evaluando el símbolo :thing
+t ; otro atom, denotando true
+(+ 1 2 3 4) ; una s-expression
+'(4 :foo t) ; otra s-expression
+
+
+;;; Comentarios
+
+;;; comentarios de una sola línea empiezan con punto y coma; usa cuatro para
+;;; comentarios a nivel de archivo, tres para descripciones de sesiones, dos
+;;; adentro de definiciones, y una para líneas simples. Por ejemplo,
+
+;;;; life.lisp
+
+;;; Foo bar baz, porque quu quux. Optimizado para máximo krakaboom y umph.
+;;; Requerido por la función LINULUKO.
+
+(defun sentido (vida)
+ "Retorna el sentido de la vida calculado"
+ (let ((meh "abc"))
+ ;; llama krakaboom
+ (loop :for x :across meh
+ :collect x))) ; guarda valores en x, luego lo retorna
+
+;;; Comentarios de bloques, por otro lado, permiten comentarios de forma libre. estos son
+;;; delimitados con #| y |#
+
+#| Este es un comentario de bloque el cual
+ puede abarcar multiples líneas y
+ #|
+ estos pueden ser anidados
+ |#
+|#
+
+
+;;; Entorno
+
+;;; Existe una variedad de implementaciones; La mayoría son conformes a los estándares. SBCL
+;;; es un buen punto de inicio. Bibliotecas de terceros pueden instalarse fácilmente con
+;;; Quicklisp
+
+;;; CL es usualmente desarrollado y un bucle de Lectura-Evaluación-Impresión (REPL), corriendo
+;;; al mismo tiempo. El REPL permite la exploración interactiva del programa mientras este esta
+;;; corriendo
+
+
+;;;-----------------------------------------------------------------------------
+;;; 1. Operadores y tipos de datos primitivos
+;;;-----------------------------------------------------------------------------
+
+;;; Símbolos
+
+'foo ; => FOO Note que el símbolo es pasado a mayúsculas automáticamente.
+
+;;; INTERN manualmente crea un símbolo a partir de una cadena.
+
+(intern "AAAA") ; => AAAA
+(intern "aaa") ; => |aaa|
+
+;;; Números
+
+9999999999999999999999 ; enteros
+#b111 ; binario=> 7
+#o111 ; octal => 73
+#x111 ; hexadecimal => 273
+3.14159s0 ; simple
+3.14159d0 ; double
+1/2 ; proporciones
+#C(1 2) ; números complejos
+
+;;; las funciones son escritas como (f x y z ...) donde f es una función y
+;;; x, y, z, ... son los argumentos.
+
+(+ 1 2) ; => 3
+
+;;; Si deseas crear datos literales use QUOTE para prevenir que estos sean evaluados
+
+(quote (+ 1 2)) ; => (+ 1 2)
+(quote a) ; => A
+
+;;; La notación abreviada para QUOTE es '
+
+'(+ 1 2) ; => (+ 1 2)
+'a ; => A
+
+;;; Operaciones aritméticas básicas
+
+(+ 1 1) ; => 2
+(- 8 1) ; => 7
+(* 10 2) ; => 20
+(expt 2 3) ; => 8
+(mod 5 2) ; => 1
+(/ 35 5) ; => 7
+(/ 1 3) ; => 1/3
+(+ #C(1 2) #C(6 -4)) ; => #C(7 -2)
+
+;;; Boleanos
+
+t ; true; cualquier valor non-NIL es true
+nil ; false; también, la lista vacia: ()
+(not nil) ; => T
+(and 0 t) ; => T
+(or 0 nil) ; => 0
+
+;;; Caracteres
+
+#\A ; => #\A
+#\λ ; => #\GREEK_SMALL_LETTER_LAMDA
+#\u03BB ; => #\GREEK_SMALL_LETTER_LAMDA
+
+;;; Cadenas son arreglos de caracteres de longitud fija
+
+"Hello, world!"
+"Benjamin \"Bugsy\" Siegel" ; la barra invertida es un carácter de escape
+
+;;; Las cadenas pueden ser concatenadas
+
+(concatenate 'string "Hello, " "world!") ; => "Hello, world!"
+
+;;; Una cadena puede ser tratada como una secuencia de caracteres
+
+(elt "Apple" 0) ; => #\A
+
+;;; FORMAT es usado para crear salidas formateadas, va desde simple interpolación de cadenas
+;;; hasta bucles y condicionales. El primer argumento de FORMAT determina donde irá la cadena
+;;; formateada. Si este es NIL, FORMAT simplemente retorna la cadena formateada como un valor;
+;;; si es T, FORMAT imprime a la salida estándar, usualmente la pantalla, luego este retorna NIL.
+
+(format nil "~A, ~A!" "Hello" "world") ; => "Hello, world!"
+(format t "~A, ~A!" "Hello" "world") ; => NIL
+
+
+;;;-----------------------------------------------------------------------------
+;;; 2. Variables
+;;;-----------------------------------------------------------------------------
+
+;;; Puedes crear una variable global (ámbito dinámico) usando DEFVAR y DEFPARAMETER
+;;; el nombre de la variable puede usar cualquier carácter excepto: ()",'`;#|\
+
+;;; La diferencia entre DEFVAR y DEFPARAMETER es que reevaluando una expresión
+;;; DEFVAR no cambia el valor de la variable. DEFPARAMETER, por otro lado sí lo hace.
+
+;;; Por convención, variables de ámbito dinámico tienen "orejeras" en sus nombres.
+
+(defparameter *some-var* 5)
+*some-var* ; => 5
+
+;;; Puedes usar también caracteres unicode.
+(defparameter *AΛB* nil)
+
+;;; Accediendo a una variable sin asignar tienen como resultado el error
+;;; UNBOUND-VARIABLE, sin embargo este es el comportamiento definido. no lo hagas
+
+;;; puedes crear enlaces locales con LET. en el siguiente código, `me` es asignado
+;;; con "dance with you" solo dentro de (let ...). LET siempre retorna el valor
+;;; del último `form`.
+
+(let ((me "dance with you")) me) ; => "dance with you"
+
+
+;;;-----------------------------------------------------------------------------;
+;;; 3. Estructuras y colecciones
+;;;-----------------------------------------------------------------------------;
+
+
+;;; Estructuras
+
+(defstruct dog name breed age)
+(defparameter *rover*
+ (make-dog :name "rover"
+ :breed "collie"
+ :age 5))
+*rover* ; => #S(DOG :NAME "rover" :BREED "collie" :AGE 5)
+(dog-p *rover*) ; => T
+(dog-name *rover*) ; => "rover"
+
+;;; DOG-P, MAKE-DOG, y DOG-NAME son creados automáticamente por DEFSTRUCT
+
+
+;;; Pares
+
+;;; CONS crea pares. CAR y CDR retornan la cabeza y la cola de un CONS-pair
+
+(cons 'SUBJECT 'VERB) ; => '(SUBJECT . VERB)
+(car (cons 'SUBJECT 'VERB)) ; => SUBJECT
+(cdr (cons 'SUBJECT 'VERB)) ; => VERB
+
+
+;;; Listas
+
+;;; Listas son estructuras de datos de listas enlazadas, hechas de pares CONS y terminan con un
+;;; NIL (o '()) para marcar el final de la lista
+
+(cons 1 (cons 2 (cons 3 nil))) ; => '(1 2 3)
+
+;;; LIST es una forma conveniente de crear listas
+
+(list 1 2 3) ; => '(1 2 3)
+
+;;; Cuando el primer argumento de CONS es un atom y el segundo argumento es una lista,
+;;; CONS retorna un nuevo par CONS con el primer argumento como el primer elemento y el
+;;; segundo argumento como el resto del par CONS
+
+(cons 4 '(1 2 3)) ; => '(4 1 2 3)
+
+;;; Use APPEND para unir listas
+
+(append '(1 2) '(3 4)) ; => '(1 2 3 4)
+
+;;; o CONCATENATE
+
+(concatenate 'list '(1 2) '(3 4)) ; => '(1 2 3 4)
+
+;;; las listas son un tipo de datos centrales en CL, por lo tanto hay una gran variedad
+;;; de funcionalidades para ellas, algunos ejemplos son:
+
+(mapcar #'1+ '(1 2 3)) ; => '(2 3 4)
+(mapcar #'+ '(1 2 3) '(10 20 30)) ; => '(11 22 33)
+(remove-if-not #'evenp '(1 2 3 4)) ; => '(2 4)
+(every #'evenp '(1 2 3 4)) ; => NIL
+(some #'oddp '(1 2 3 4)) ; => T
+(butlast '(subject verb object)) ; => (SUBJECT VERB)
+
+
+;;; Vectores
+
+;;; Vectores literales son arreglos de longitud fija
+
+#(1 2 3) ; => #(1 2 3)
+
+;;; Use CONCATENATE para juntar vectores
+
+(concatenate 'vector #(1 2 3) #(4 5 6)) ; => #(1 2 3 4 5 6)
+
+
+;;; Arreglos
+
+;;; Vectores y cadenas son casos especiales de arreglos.
+
+;;; Arreglos bidimensionales
+
+(make-array (list 2 2)) ; => #2A((0 0) (0 0))
+(make-array '(2 2)) ; => #2A((0 0) (0 0))
+(make-array (list 2 2 2)) ; => #3A(((0 0) (0 0)) ((0 0) (0 0)))
+
+;;; Precaución: los valores iniciales por defecto de MAKE-ARRAY son implementaciones definidas
+;;; para definirlos explícitamente:
+
+(make-array '(2) :initial-element 'unset) ; => #(UNSET UNSET)
+
+;;; Para acceder al elemento en 1, 1, 1:
+
+(aref (make-array (list 2 2 2)) 1 1 1) ; => 0
+
+;;; Este valor es definido por implementación:
+;;; NIL en ECL, 0 en SBCL and CCL.
+
+;;; vectores ajustables
+
+;;; los vectores ajustables tienen la misma representación en la impresión como los vectores literales
+;;; de longitud fija.
+
+(defparameter *adjvec* (make-array '(3) :initial-contents '(1 2 3)
+ :adjustable t :fill-pointer t))
+*adjvec* ; => #(1 2 3)
+
+;;; Agregando nuevos elementos
+
+(vector-push-extend 4 *adjvec*) ; => 3
+*adjvec* ; => #(1 2 3 4)
+
+
+;;; Conjuntos, ingenuamente son listas:
+
+(set-difference '(1 2 3 4) '(4 5 6 7)) ; => (3 2 1)
+(intersection '(1 2 3 4) '(4 5 6 7)) ; => 4
+(union '(1 2 3 4) '(4 5 6 7)) ; => (3 2 1 4 5 6 7)
+(adjoin 4 '(1 2 3 4)) ; => (1 2 3 4)
+
+;;; Sin embargo, necesitarás una mejor estructura de datos que listas enlazadas
+;;; cuando trabajes con conjuntos de datos grandes
+
+;;; Los Diccionarios son implementados como tablas hash.
+
+;;; Crear tablas hash
+
+(defparameter *m* (make-hash-table))
+
+;;; definir valor
+
+(setf (gethash 'a *m*) 1)
+
+;;; obtener valor
+
+(gethash 'a *m*) ; => 1, T
+
+;;; las expresiones en CL tienen la facultad de retornar multiples valores.
+
+(values 1 2) ; => 1, 2
+
+;;; los cuales pueden ser asignados con MULTIPLE-VALUE-BIND
+
+(multiple-value-bind (x y)
+ (values 1 2)
+ (list y x))
+
+; => '(2 1)
+
+;;; GETHASH es un ejemplo de una función que retorna multiples valores. El primer
+;;; valor es el valor de la llave en la tabla hash: si la llave no existe retorna NIL.
+
+;;; El segundo valor determina si la llave existe en la tabla hash. si la llave no existe
+;;; en la tabla hash retorna NIL. Este comportamiento permite verificar si el valor de una
+;;; llave es actualmente NIL.
+
+;;; Obteniendo un valor no existente retorna NIL
+
+(gethash 'd *m*) ;=> NIL, NIL
+
+;;; Puedes declarar un valor por defecto para las llaves inexistentes
+
+(gethash 'd *m* :not-found) ; => :NOT-FOUND
+
+;;; Vamos a manejar los multiples valores de retornno en el código.
+
+(multiple-value-bind (a b)
+ (gethash 'd *m*)
+ (list a b))
+; => (NIL NIL)
+
+(multiple-value-bind (a b)
+ (gethash 'a *m*)
+ (list a b))
+; => (1 T)
+
+
+;;;-----------------------------------------------------------------------------
+;;; 3. Funciones
+;;;-----------------------------------------------------------------------------
+
+;;; Use LAMBDA para crear funciones anónimas. las funciones siempre retornan el valor
+;;; de la última expresión. la representación imprimible de una función varia entre
+;;; implementaciones.
+
+(lambda () "Hello World") ; => #<FUNCTION (LAMBDA ()) {1004E7818B}>
+
+;;; Use FUNCALL para llamar funciones anónimas.
+
+(funcall (lambda () "Hello World")) ; => "Hello World"
+(funcall #'+ 1 2 3) ; => 6
+
+;;; Un llamado a FUNCALL es también realizado cuando la expresión lambda es el CAR de
+;;; una lista.
+
+((lambda () "Hello World")) ; => "Hello World"
+((lambda (val) val) "Hello World") ; => "Hello World"
+
+;;; FUNCALL es usado cuando los argumentos son conocidos de antemano.
+;;; de lo contrario use APPLY
+
+(apply #'+ '(1 2 3)) ; => 6
+(apply (lambda () "Hello World") nil) ; => "Hello World"
+
+;;; Para nombrar una funcion use DEFUN
+
+(defun hello-world () "Hello World")
+(hello-world) ; => "Hello World"
+
+;;; Los () en la definición anterior son la lista de argumentos
+
+(defun hello (name) (format nil "Hello, ~A" name))
+(hello "Steve") ; => "Hello, Steve"
+
+;;; las functiones pueden tener argumentos opcionales; por defecto son NIL
+
+(defun hello (name &optional from)
+ (if from
+ (format t "Hello, ~A, from ~A" name from)
+ (format t "Hello, ~A" name)))
+
+(hello "Jim" "Alpacas") ; => Hello, Jim, from Alpacas
+
+;;; Los valores por defecto pueden ser especificados
+
+
+(defun hello (name &optional (from "The world"))
+ (format nil "Hello, ~A, from ~A" name from))
+
+(hello "Steve") ; => Hello, Steve, from The world
+(hello "Steve" "the alpacas") ; => Hello, Steve, from the alpacas
+
+;;; Las funciones también tienen argumentos llaves para permitir argumentos no positionados
+
+(defun generalized-greeter (name &key (from "the world") (honorific "Mx"))
+ (format t "Hello, ~A ~A, from ~A" honorific name from))
+
+(generalized-greeter "Jim")
+; => Hello, Mx Jim, from the world
+
+(generalized-greeter "Jim" :from "the alpacas you met last summer" :honorific "Mr")
+; => Hello, Mr Jim, from the alpacas you met last summer
+
+
+;;;-----------------------------------------------------------------------------
+;;; 4. Igualdad
+;;;-----------------------------------------------------------------------------
+
+;;; CL tiene un sistema sofisticado de igualdad. Una parte es tratada aquí.
+
+;;; Para números use `=`
+(= 3 3.0) ; => T
+(= 2 1) ; => NIL
+
+;;; Para identidad de objetos (aproximadamente) use EQL
+(eql 3 3) ; => T
+(eql 3 3.0) ; => NIL
+(eql (list 3) (list 3)) ; => NIL
+
+;;; para listas, cadenas y bit vectores use EQUAL
+(equal (list 'a 'b) (list 'a 'b)) ; => T
+(equal (list 'a 'b) (list 'b 'a)) ; => NIL
+
+
+;;;-----------------------------------------------------------------------------
+;;; 5. Control de flujo
+;;;-----------------------------------------------------------------------------
+
+;;; Condicionales
+
+(if t ; testar expresión
+ "this is true" ; then expression
+ "this is false") ; else expression
+; => "this is true"
+
+;;; En condicionales, todo valor non-NIL es tratado como true
+
+(member 'Groucho '(Harpo Groucho Zeppo)) ; => '(GROUCHO ZEPPO)
+(if (member 'Groucho '(Harpo Groucho Zeppo))
+ 'yep
+ 'nope)
+; => 'YEP
+
+;;; COND en cadena una serie de pruebas para seleccionar un resultado
+(cond ((> 2 2) (error "wrong!"))
+ ((< 2 2) (error "wrong again!"))
+ (t 'ok)) ; => 'OK
+
+;;; TYPECASE evalua sobre el tipo del valor
+(typecase 1
+ (string :string)
+ (integer :int))
+; => :int
+
+
+;;; Bucles
+
+;;; Recursión
+
+(defun fact (n)
+ (if (< n 2)
+ 1
+ (* n (fact(- n 1)))))
+
+(fact 5) ; => 120
+
+;;; Iteración
+
+(defun fact (n)
+ (loop :for result = 1 :then (* result i)
+ :for i :from 2 :to n
+ :finally (return result)))
+
+(fact 5) ; => 120
+
+(loop :for x :across "abcd" :collect x)
+; => (#\a #\b #\c #\d)
+
+(dolist (i '(1 2 3 4))
+ (format t "~A" i))
+; => 1234
+
+
+;;;-----------------------------------------------------------------------------
+;;; 6. Mutación
+;;;-----------------------------------------------------------------------------
+
+;;; use SETF para asignar un valor nuevo a una variable existente. Esto fue demostrado
+;;; previamente en el ejemplo de la tabla hash.
+
+(let ((variable 10))
+ (setf variable 2))
+; => 2
+
+;;; Un estilo bueno de lisp es minimizar el uso de funciones destructivas y prevenir
+;;; la mutación cuando sea posible.
+
+
+;;;-----------------------------------------------------------------------------
+;;; 7. Clases y objetos
+;;;-----------------------------------------------------------------------------
+
+;;; No más clases de animales, tengamos transportes mecánicos impulsados por el humano
+
+(defclass human-powered-conveyance ()
+ ((velocity
+ :accessor velocity
+ :initarg :velocity)
+ (average-efficiency
+ :accessor average-efficiency
+ :initarg :average-efficiency))
+ (:documentation "A human powered conveyance"))
+
+;;; Los argumentos de DEFCLASS, en orden son:
+;;; 1. nombre de la clase
+;;; 2. lista de superclases
+;;; 3. slot list
+;;; 4. Especificadores opcionales
+
+;;; cuando no hay lista de superclase, la lista vacia indica clase de
+;;; objeto estándar, esto puede ser cambiado, pero no mientras no sepas
+;;; lo que estas haciendo. revisar el arte del protocolo de meta-objetos
+;;; para más información.
+
+(defclass bicycle (human-powered-conveyance)
+ ((wheel-size
+ :accessor wheel-size
+ :initarg :wheel-size
+ :documentation "Diameter of the wheel.")
+ (height
+ :accessor height
+ :initarg :height)))
+
+(defclass recumbent (bicycle)
+ ((chain-type
+ :accessor chain-type
+ :initarg :chain-type)))
+
+(defclass unicycle (human-powered-conveyance) nil)
+
+(defclass canoe (human-powered-conveyance)
+ ((number-of-rowers
+ :accessor number-of-rowers
+ :initarg :number-of-rowers)))
+
+;;; Invocando DESCRIBE en la clase HUMAN-POWERED-CONVEYANCE en REPL obtenemos:
+
+(describe 'human-powered-conveyance)
+
+; COMMON-LISP-USER::HUMAN-POWERED-CONVEYANCE
+; [symbol]
+;
+; HUMAN-POWERED-CONVEYANCE names the standard-class #<STANDARD-CLASS
+; HUMAN-POWERED-CONVEYANCE>:
+; Documentation:
+; A human powered conveyance
+; Direct superclasses: STANDARD-OBJECT
+; Direct subclasses: UNICYCLE, BICYCLE, CANOE
+; Not yet finalized.
+; Direct slots:
+; VELOCITY
+; Readers: VELOCITY
+; Writers: (SETF VELOCITY)
+; AVERAGE-EFFICIENCY
+; Readers: AVERAGE-EFFICIENCY
+; Writers: (SETF AVERAGE-EFFICIENCY)
+
+;;; Tenga en cuenta el comportamiento reflexivo disponible. CL fue diseñado
+;;; para ser un systema interactivo
+
+;;; para definir un método, encontremos la circunferencia de la rueda usando
+;;; la ecuación C = d * pi
+
+(defmethod circumference ((object bicycle))
+ (* pi (wheel-size object)))
+
+;;; PI es definido internamente en CL
+
+;;; Supongamos que descubrimos que el valor de eficiencia del número de remeros
+;;; en una canoa es aproximadamente logarítmico. Esto probablemente debería
+;;; establecerse en el constructor / inicializador.
+
+;;; Para inicializar su instancia después de que CL termine de construirla:
+
+(defmethod initialize-instance :after ((object canoe) &rest args)
+ (setf (average-efficiency object) (log (1+ (number-of-rowers object)))))
+
+;;; luego para construir una instancia y revisar la eficiencia promedio
+
+(average-efficiency (make-instance 'canoe :number-of-rowers 15))
+; => 2.7725887
+
+
+;;;-----------------------------------------------------------------------------
+;;; 8. Macros
+;;;-----------------------------------------------------------------------------
+
+;;; las Macros le permiten extender la sintaxis del lenguaje, CL no viene con
+;;; un bucle WHILE, por lo tanto es facil escribirlo, Si obedecemos nuestros
+;;; instintos de ensamblador, terminamos con:
+
+(defmacro while (condition &body body)
+ "While `condition` is true, `body` is executed.
+`condition` is tested prior to each execution of `body`"
+ (let ((block-name (gensym)) (done (gensym)))
+ `(tagbody
+ ,block-name
+ (unless ,condition
+ (go ,done))
+ (progn
+ ,@body)
+ (go ,block-name)
+ ,done)))
+
+;;; revisemos la versión de alto nivel para esto:
+
+(defmacro while (condition &body body)
+ "While `condition` is true, `body` is executed.
+`condition` is tested prior to each execution of `body`"
+ `(loop while ,condition
+ do
+ (progn
+ ,@body)))
+
+;;; Sin embargo, con un compilador moderno, esto no es necesario; El LOOP se
+;;; compila igualmente bien y es más fácil de leer.
+
+;;; Tenga en cuenta que se utiliza ```, así como `,` y `@`. ``` es un operador
+;;; de tipo de cita conocido como quasiquote; permite el uso de `,` . `,` permite
+;;; variables "entre comillas". @ interpola las listas.
+
+;;; GENSYM crea un símbolo único que garantiza que no existe en ninguna otra parte
+;;; del sistema. Esto se debe a que las macros se expanden en el momento de la compilación
+;;; y las variables declaradas en la macro pueden colisionar con las variables utilizadas
+;;; en un código regular.
+
+;;; Consulte Practical Common Lisp y On Lisp para obtener más información sobre macros.
+```
+
+
+## Otras Lecturas
+
+- [Practical Common Lisp](http://www.gigamonkeys.com/book/)
+- [Common Lisp: A Gentle Introduction to Symbolic Computation](https://www.cs.cmu.edu/~dst/LispBook/book.pdf)
+
+
+## Información extra
+
+- [CLiki](http://www.cliki.net/)
+- [common-lisp.net](https://common-lisp.net/)
+- [Awesome Common Lisp](https://github.com/CodyReichert/awesome-cl)
+- [Lisp Lang](http://lisp-lang.org/)
+
+
+## Creditos
+
+Muchas Gracias a la gente de Scheme por proveer un gran punto de inicio
+el cual puede ser movido fácilmente a Common Lisp
+
+- [Paul Khuong](https://github.com/pkhuong) para un buen repaso.
diff --git a/es-es/dart-es.html.markdown b/es-es/dart-es.html.markdown
new file mode 100644
index 00000000..d0f57b95
--- /dev/null
+++ b/es-es/dart-es.html.markdown
@@ -0,0 +1,529 @@
+---
+language: dart
+contributors:
+ - ["Joao Pedrosa", "https://github.com/jpedrosa/"]
+translators:
+ - ["Jorge Antonio Atempa", "http://www.twitter.com/atempa09"]
+filename: dart-es.md
+lang: es-es
+---
+
+Dart es un recién llegado al ámbito de los lenguajes de programación.
+Toma prestado mucho de otros lenguajes principales, con el objetivo de no desviarse demasiado de
+su hermano JavaScript. Tal como JavaScript, Dart tiene como objetivo una gran integración en el navegador.
+
+La característica más controvertida de Dart debe ser su escritura opcional.
+
+```dart
+import "dart:collection";
+import "dart:math" as DM;
+
+// Bienvenido a Aprende Dart en 15 minutos. http://www.dartlang.org/
+// Este es un tutorial ejecutable. Puedes ejecutarlo con Dart o en
+// el sitio de ¡Try Dart! solo copiando y pegando en http://try.dartlang.org/
+
+// La declaración de función y de método tienen el mismo aspecto.
+// Las funciones pueden estar anidadas.
+// La declaración toma la forma name() {} o name() => expresionEnUnaLinea;
+// La declaración de la función de flecha gorda, tiene un retorno implícito
+// para el resultado de la expresión.
+example1() {
+ nested1() {
+ nested2() => print("example1 anidado 1 anidado 2");
+ nested2();
+ }
+ nested1();
+}
+
+// Las funciones anónimas no incluyen un nombre.
+example2() {
+ nested1(fn) {
+ fn();
+ }
+ nested1(() => print("example2 anidado 1"));
+}
+
+// Cuando se declara un parámetro de función, la declaración puede incluir el
+// número de parámetros que toma la función especificando los nombres de los
+// parámetros que lleva.
+example3() {
+ planA(fn(informSomething)) {
+ fn("example3 plan A");
+ }
+ planB(fn) { // O no declarar el número de parámetros.
+ fn("example3 plan B");
+ }
+ planA((s) => print(s));
+ planB((s) => print(s));
+}
+
+// Las funciones tienen acceso de cierre a variables externas.
+var example4Something = "Example4 anidado 1";
+example4() {
+ nested1(fn(informSomething)) {
+ fn(example4Something);
+ }
+ nested1((s) => print(s));
+}
+
+// La declaración de la clase con un método sayIt, el cual también tiene acceso de cierre
+// a la variable exterior como si fuera una función como se ha visto antes.
+var example5method = "example5 sayIt";
+class Example5Class {
+ sayIt() {
+ print(example5method);
+ }
+}
+example5() {
+ // Crear una instancia anónima de Example5Class y la llamada del método sayIt
+ new Example5Class().sayIt();
+}
+
+// La declaración de clase toma la forma NombreDeClase { [cuerpoDeClase] }.
+// Donde cuerpoDeClase puede incluir métodos de instancia y variables, pero también
+// métodos y variables de clase.
+class Example6Class {
+ var instanceVariable = "Example6 variable de instancia";
+ sayIt() {
+ print(instanceVariable);
+ }
+}
+example6() {
+ new Example6Class().sayIt();
+}
+
+// Los métodos y variables de clase son declarados con términos "static".
+class Example7Class {
+ static var classVariable = "Example7 variable de clase";
+ static sayItFromClass() {
+ print(classVariable);
+ }
+ sayItFromInstance() {
+ print(classVariable);
+ }
+}
+example7() {
+ Example7Class.sayItFromClass();
+ new Example7Class().sayItFromInstance();
+}
+
+// Las literales son geniales, pero hay una restricción para lo que pueden ser las literales
+// fuera de los cuerpos de función/método. Literales en el ámbito exterior de clase
+// o fuera de clase tienen que ser constantes. Las cadenas de caracteres y los números
+// son constantes por defecto. Pero los arreglos y mapas no lo son.
+// Ellos pueden hacerse constante anteponiendo en la declaración el término "const".
+var example8Array = const ["Example8 arreglo constante"],
+ example8Map = const {"algunaKey": "Example8 mapa constante"};
+example8() {
+ print(example8Array[0]);
+ print(example8Map["algunaKey"]);
+}
+
+// Los bucles en Dart toman la forma estándar para for () {} o ciclos while () {} ,
+// ligeramente más moderno for (.. in ..) {}, o llamadas funcionales con muchas
+// características soportadas, comenzando con forEach.
+var example9Array = const ["a", "b"];
+example9() {
+ for (var i = 0; i < example9Array.length; i++) {
+ print("example9 ciclo for '${example9Array[i]}'");
+ }
+ var i = 0;
+ while (i < example9Array.length) {
+ print("example9 ciclo while '${example9Array[i]}'");
+ i++;
+ }
+ for (var e in example9Array) {
+ print("example9 ciclo for-in '${e}'");
+ }
+ example9Array.forEach((e) => print("example9 ciclo forEach '${e}'"));
+}
+
+// Para recorrer los caracteres de una cadena o para extraer una subcadena.
+var example10String = "ab";
+example10() {
+ for (var i = 0; i < example10String.length; i++) {
+ print("example10 Recorrido de caracteres en la cadena '${example10String[i]}'");
+ }
+ for (var i = 0; i < example10String.length; i++) {
+ print("example10 ciclo de subcadena '${example10String.substring(i, i + 1)}'");
+ }
+}
+
+// Formato de números Int y double son soportados.
+example11() {
+ var i = 1 + 320, d = 3.2 + 0.01;
+ print("example11 int ${i}");
+ print("example11 double ${d}");
+}
+
+// DateTime ofrece aritmética de fecha/hora.
+example12() {
+ var now = new DateTime.now();
+ print("example12 ahora '${now}'");
+ now = now.add(new Duration(days: 1));
+ print("example12 manana '${now}'");
+}
+
+// Expresiones regulares son soportadas.
+example13() {
+ var s1 = "alguna cadena", s2 = "alguna", re = new RegExp("^s.+?g\$");
+ match(s) {
+ if (re.hasMatch(s)) {
+ print("example13 regexp embona '${s}'");
+ } else {
+ print("example13 regexp no embona '${s}'");
+ }
+ }
+ match(s1);
+ match(s2);
+}
+
+// Las expresiones booleanas admiten conversiones implícitas y tipos dinámicos.
+example14() {
+ var a = true;
+ if (a) {
+ print("true, a is $a");
+ }
+ a = null;
+ if (a) {
+ print("true, a es $a");
+ } else {
+ print("false, a es $a"); // corre aquí
+ }
+
+ // el tipado dinámico null puede convertirse a bool
+ var b; // b es de tipo dinámico
+ b = "abc";
+ try {
+ if (b) {
+ print("true, b es $b");
+ } else {
+ print("false, b es $b");
+ }
+ } catch (e) {
+ print("error, b es $b"); // esto podría ser ejecutado pero consiguió error
+ }
+ b = null;
+ if (b) {
+ print("true, b es $b");
+ } else {
+ print("false, b es $b"); // corre aquí
+ }
+
+ // tipado estático null no puede ser convertido a bool
+ var c = "abc";
+ c = null;
+ // compilación fallida
+ // if (c) {
+ // print("true, c is $c");
+ // } else {
+ // print("false, c is $c");
+ // }
+}
+
+// try/catch/finally y throw son utilizados para el manejo de excepciones.
+// throw toma cualquier objeto como parámetro;
+example15() {
+ try {
+ try {
+ throw "Algun error inesperado.";
+ } catch (e) {
+ print("example15 una excepcion: '${e}'");
+ throw e; // Re-throw
+ }
+ } catch (e) {
+ print("example15 atrapa la excepcion que ha sido relanzada: '${e}'");
+ } finally {
+ print("example15 aún ejecuta finally");
+ }
+}
+
+// Para ser eficiente cuando creas una cadena larga dinámicamente, usa
+// StringBuffer. O podrías unir un arreglo de cadena de caracteres.
+example16() {
+ var sb = new StringBuffer(), a = ["a", "b", "c", "d"], e;
+ for (e in a) { sb.write(e); }
+ print("example16 cadena de caracteres dinamica creada con "
+ "StringBuffer '${sb.toString()}'");
+ print("example16 union de arreglo de cadena de caracteres '${a.join()}'");
+}
+
+// Las cadenas de caracteres pueden ser concatenadas contando solo
+// con literales una después de la otra sin algún otro operador necesario.
+example17() {
+ print("example17 "
+ "concatenar "
+ "cadenas "
+ "asi");
+}
+
+// Las cadenas de caracteres utilizan comilla simple o comillas dobles como delimitadores
+// sin ninguna diferencia entre ambas. Esto proporciona flexibilidad que puede ser efectiva
+// para evitar la necesidad de 'escapar' el contenido. Por ejemplo,
+// las dobles comillas de los atributos HTML.
+example18() {
+ print('Example18 <a href="etc">'
+ "Don't can't I'm Etc"
+ '</a>');
+}
+
+// Las cadenas de caracteres con triple comilla simple o triple comillas dobles
+// dividen múltiples lineas e incluyen como delimitador el salto de línea.
+example19() {
+ print('''Example19 <a href="etc">
+Example19 Don't can't I'm Etc
+Example19 </a>''');
+}
+
+// Las cadenas de caracteres cuentan con una extraordinaria característica
+// para la interpolación de caracteres utilizando el operador $
+// Con $ { [expresion] }, devolvemos la expresion interpolada.
+// $ seguido por el nombre de una variable interpola el contenido de dicha variable.
+// $ puede ser escapado con \$ para solo agregarlo a la cadena.
+example20() {
+ var s1 = "'\${s}'", s2 = "'\$s'";
+ print("Example20 \$ interpolation ${s1} or $s2 works.");
+}
+
+// Hasta ahora no hemos declarado ningún tipo de dato y los programas
+// han funcionado bien. De hecho, los tipos no se toman en cuenta durante
+// el tiempo de ejecución.
+// Los tipos incluso pueden estar equivocados y al programa todavía se le dará
+// el beneficio de la duda y se ejecutará como si los tipos no importaran.
+// Hay un parámetro de tiempo de ejecución que comprueba los errores de tipo que es
+// el modo de verificación, el cuál es útil durante el tiempo de desarrollo,
+// pero que también es más lento debido a la comprobación adicional y, por lo tanto
+// se evita durante el tiempo de ejecución de la implementación.
+class Example21 {
+ List<String> _names;
+ Example21() {
+ _names = ["a", "b"];
+ }
+ List<String> get names => _names;
+ set names(List<String> list) {
+ _names = list;
+ }
+ int get length => _names.length;
+ void add(String name) {
+ _names.add(name);
+ }
+}
+void example21() {
+ Example21 o = new Example21();
+ o.add("c");
+ print("example21 nombres '${o.names}' y longitud '${o.length}'");
+ o.names = ["d", "e"];
+ print("example21 nombres '${o.names}' y longitud '${o.length}'");
+}
+
+// La herencia de clases toma la forma NombreDeClase extends OtraClase {}.
+class Example22A {
+ var _name = "¡Algun Nombre!";
+ get name => _name;
+}
+class Example22B extends Example22A {}
+example22() {
+ var o = new Example22B();
+ print("example22 herencia de clase '${o.name}'");
+}
+
+// La mezcla de clases también esta disponible y toman la forma de
+// NombreDeClase extends AlgunaClase with OtraClase {}.
+// Es necesario extender de alguna clase para poder mezclar con otra.
+// La clase de plantilla de mixin no puede en este momento tener un constructor.
+// Mixin se utiliza principalmente para compartir métodos con clases distantes,
+// por lo que la herencia única no interfiere con el código reutilizable.
+// Mixins se colocan despues de la palabra "with" durante la declaración de la clase.
+class Example23A {}
+class Example23Utils {
+ addTwo(n1, n2) {
+ return n1 + n2;
+ }
+}
+class Example23B extends Example23A with Example23Utils {
+ addThree(n1, n2, n3) {
+ return addTwo(n1, n2) + n3;
+ }
+}
+example23() {
+ var o = new Example23B(), r1 = o.addThree(1, 2, 3),
+ r2 = o.addTwo(1, 2);
+ print("Example23 addThree(1, 2, 3) results in '${r1}'");
+ print("Example23 addTwo(1, 2) results in '${r2}'");
+}
+
+// El método constructor de la clase utiliza el mismo nombre de la clase
+// y toma la forma de AlgunaClase() : super() {}, donde la parte ": super()"
+// es opcional y es utilizado para delegar parametros constantes
+// al método constructor de la clase padre o super clase.
+class Example24A {
+ var _value;
+ Example24A({value: "algunValor"}) {
+ _value = value;
+ }
+ get value => _value;
+}
+class Example24B extends Example24A {
+ Example24B({value: "algunOtroValor"}) : super(value: value);
+}
+example24() {
+ var o1 = new Example24B(),
+ o2 = new Example24B(value: "aunMas");
+ print("example24 llama al método super desde el constructor '${o1.value}'");
+ print("example24 llama al método super desde el constructor '${o2.value}'");
+}
+
+// Hay un atajo para configurar los parámetros del constructor en el caso de clases más simples.
+// Simplemente use el prefijo this.nombreParametro y establecerá el parámetro
+// en una variable de instancia del mismo nombre.
+class Example25 {
+ var value, anotherValue;
+ Example25({this.value, this.anotherValue});
+}
+example25() {
+ var o = new Example25(value: "a", anotherValue: "b");
+ print("example25 atajo para el constructor '${o.value}' y "
+ "'${o.anotherValue}'");
+}
+
+// Los parámetros con nombre están disponibles cuando se declaran entre {}.
+// El orden de los parámetros puede ser opcional cuando se declara entre {}.
+// Los parámetros pueden hacerse opcionales cuando se declaran entre [].
+example26() {
+ var _name, _surname, _email;
+ setConfig1({name, surname}) {
+ _name = name;
+ _surname = surname;
+ }
+ setConfig2(name, [surname, email]) {
+ _name = name;
+ _surname = surname;
+ _email = email;
+ }
+ setConfig1(surname: "Doe", name: "John");
+ print("example26 name '${_name}', surname '${_surname}', "
+ "email '${_email}'");
+ setConfig2("Mary", "Jane");
+ print("example26 name '${_name}', surname '${_surname}', "
+ "email '${_email}'");
+}
+
+// Las variables declaradas con final solo se pueden establecer una vez.
+// En el caso de las clases, las variables de instancia final se pueden establecer
+// a través de la constante del parámetro constructor.
+class Example27 {
+ final color1, color2;
+ // Un poco de flexibilidad para establecer variables de instancia finales con la sintaxis
+ // que sigue a :
+ Example27({this.color1, color2}) : color2 = color2;
+}
+example27() {
+ final color = "orange", o = new Example27(color1: "lilac", color2: "white");
+ print("example27 color es '${color}'");
+ print("example27 color es '${o.color1}' y '${o.color2}'");
+}
+
+// Para importar una librería utiliza la palabra reservada import "rutaLibrería" o si es una biblioteca central,
+// import "dart:NombreLibrería". También está el "pub" administrador de paquetes con
+// su propia convensión import "package:NombrePaquete".
+// Ve import "dart:collection"; al inicio. Las importaciones deben venir antes
+// de la delcaración de algún otro código. IterableBase proviene de dart:collection.
+class Example28 extends IterableBase {
+ var names;
+ Example28() {
+ names = ["a", "b"];
+ }
+ get iterator => names.iterator;
+}
+example28() {
+ var o = new Example28();
+ o.forEach((name) => print("example28 '${name}'"));
+}
+
+// Para el control de flujo tenemos:
+// * estandard switch
+// * if-else if-else y el operador ternario ..?..:..
+// * closures y funciones anonimas
+// * sentencias break, continue y return
+example29() {
+ var v = true ? 30 : 60;
+ switch (v) {
+ case 30:
+ print("example29 sentencia switch");
+ break;
+ }
+ if (v < 30) {
+ } else if (v > 30) {
+ } else {
+ print("example29 sentencia if-else");
+ }
+ callItForMe(fn()) {
+ return fn();
+ }
+ rand() {
+ v = new DM.Random().nextInt(50);
+ return v;
+ }
+ while (true) {
+ print("example29 callItForMe(rand) '${callItForMe(rand)}'");
+ if (v != 30) {
+ break;
+ } else {
+ continue;
+ }
+ // Nunca llega aquí.
+ }
+}
+
+// La sentencia int.parse, convierte de tipo double a int, o simplemente mantener int cuando se dividen los números
+// utilizando ~/ como operación. Vamos a jugar un juego de adivinanzas también.
+example30() {
+ var gn, tooHigh = false,
+ n, n2 = (2.0).toInt(), top = int.parse("123") ~/ n2, bottom = 0;
+ top = top ~/ 6;
+ gn = new DM.Random().nextInt(top + 1); // +1 porque nextInt top es exclusivo
+ print("example30 Adivina un número entre 0 y ${top}");
+ guessNumber(i) {
+ if (n == gn) {
+ print("example30 ¡Adivinaste correctamente! El número es ${gn}");
+ } else {
+ tooHigh = n > gn;
+ print("example30 Número ${n} es demasiado "
+ "${tooHigh ? 'high' : 'low'}. Intenta nuevamente");
+ }
+ return n == gn;
+ }
+ n = (top - bottom) ~/ 2;
+ while (!guessNumber(n)) {
+ if (tooHigh) {
+ top = n - 1;
+ } else {
+ bottom = n + 1;
+ }
+ n = bottom + ((top - bottom) ~/ 2);
+ }
+}
+
+// Los programas tienen un solo punto de entrada en la función principal.
+// No se espera que se ejecute nada en el ámbito externo antes de que un programa
+// comience a funcionar con su función principal.
+// Esto ayuda con una carga más rápida e incluso con una carga lenta
+// de lo que necesita el programa para iniciar.
+main() {
+ print("Learn Dart in 15 minutes!");
+ [example1, example2, example3, example4, example5, example6, example7,
+ example8, example9, example10, example11, example12, example13, example14,
+ example15, example16, example17, example18, example19, example20,
+ example21, example22, example23, example24, example25, example26,
+ example27, example28, example29, example30
+ ].forEach((ef) => ef());
+}
+
+```
+
+## Lecturas adicionales
+
+Dart tiene un sitio web muy completo. Cubre referencias de API, tutoriales, artículos y más, incluyendo una
+útil sección en línea Try Dart.
+[https://www.dartlang.org](https://www.dartlang.org)
+[https://try.dartlang.org](https://try.dartlang.org)
diff --git a/es-es/kotlin-es.html.markdown b/es-es/kotlin-es.html.markdown
index 045f92d1..80d7a4bb 100644
--- a/es-es/kotlin-es.html.markdown
+++ b/es-es/kotlin-es.html.markdown
@@ -2,6 +2,7 @@
language: kotlin
contributors:
- ["S Webber", "https://github.com/s-webber"]
+- ["Aitor Escolar", "https://github.com/aiescola"]
translators:
- ["Ivan Alburquerque", "https://github.com/AlburIvan"]
lang: es-es
@@ -40,6 +41,12 @@ fun main(args: Array<String>) {
    Podemos declarar explícitamente el tipo de una variable así:
*/
val foo: Int = 7
+
+ /*
+ A diferencia de JavaScript, aunque el tipo se infiera, es tipado, por lo que no se puede cambiar el tipo a posteriori
+ */
+ var fooInt = 14 // Se infiere tipo Int
+ fooInt = "Cadena" // ERROR en tiempo de compilación: Type mismatch
/*
Las cadenas pueden ser representadas de la misma manera que Java.
@@ -84,7 +91,6 @@ fun main(args: Array<String>) {
println(fooNullable?.length) // => null
println(fooNullable?.length ?: -1) // => -1
-
/*
Las funciones pueden ser declaras usando la palabra clave "fun".
Los argumentos de las funciones son especificados entre corchetes despues del nombre de la función.
@@ -122,6 +128,40 @@ fun main(args: Array<String>) {
fun even(x: Int) = x % 2 == 0
println(even(6)) // => true
println(even(7)) // => false
+
+ /*
+ Kotlin permite el uso de lambdas, o funciones anónimas
+ */
+
+ // Sin lambda:
+ interface MyListener {
+ fun onClick(foo: Foo)
+ }
+
+ fun listenSomething(listener: MyListener) {
+ listener.onClick(Foo())
+ }
+
+ listenSomething(object: MyListener {
+ override fun onClick(foo: Foo) {
+ //...
+ }
+ })
+
+ // Con lambda:
+ fun listenSomethingLambda(listener: (Foo) -> Unit) {
+ listener(Foo())
+ }
+
+ listenSomethingLambda {
+ //Se recibe foo
+ }
+
+ // el operador typealias permite, entre otras cosas, simplificar las expresiones con lambdas
+ typealias MyLambdaListener = (Foo) -> Unit
+ fun listenSomethingLambda(listener: MyLambdaListener) {
+ listener(Foo())
+ }
// Las funciones pueden tomar funciones como argumentos y
// retornar funciones.
@@ -219,6 +259,11 @@ fun main(args: Array<String>) {
val fooMap = mapOf("a" to 8, "b" to 7, "c" to 9)
// Se puede acceder a los valores del mapa por su llave.
println(fooMap["a"]) // => 8
+
+ // Tanto Map como cualquier colección iterable, tienen la función de extensión forEach
+ fooMap.forEach {
+ println("${it.key} ${it.value}")
+ }
/*
Las secuencias representan colecciones evaluadas diferidamente.
@@ -245,7 +290,7 @@ fun main(args: Array<String>) {
val y = fibonacciSequence().take(10).toList()
println(y) // => [1, 1, 2, 3, 5, 8, 13, 21, 34, 55]
- // Kotlin provee funciones de Orden-Mayor para trabajar con colecciones.
+ // Kotlin provee funciones de orden superior para trabajar con colecciones.
val z = (1..9).map {it * 3}
.filter {it < 20}
.groupBy {it % 2 == 0}
@@ -305,17 +350,11 @@ fun main(args: Array<String>) {
ese tipo sin convertido de forma explícita.
*/
fun smartCastExample(x: Any) : Boolean {
- if (x is Boolean) {
- // x es automaticamente convertido a Boolean
- return x
- } else if (x is Int) {
- // x es automaticamente convertido a Int
- return x > 0
- } else if (x is String) {
- // x es automaticamente convertido a String
- return x.isNotEmpty()
- } else {
- return false
+ return when (x) {
+ is Boolean -> x // x es automaticamente convertido a Boolean
+ is Int -> x > 0 // x es automaticamente convertido a Int
+ is String -> x.isNotEmpty() // x es automaticamente convertido a String
+ else -> false
}
}
println(smartCastExample("Hola, mundo!")) // => true
@@ -345,7 +384,8 @@ enum class EnumExample {
/*
La palabra clave "object" se puede utilizar para crear objetos únicos.
No podemos asignarlo a una variable, pero podemos hacer referencia a ella por su nombre.
-Esto es similar a los objetos únicos de Scala
+Esto es similar a los objetos únicos de Scala.
+En la mayoría de ocasiones, los objetos únicos se usan como alternativa a los Singleton.
*/
object ObjectExample {
fun hello() : String {
diff --git a/es-es/python-es.html.markdown b/es-es/python-es.html.markdown
index a27203d1..2b8f498a 100644
--- a/es-es/python-es.html.markdown
+++ b/es-es/python-es.html.markdown
@@ -467,7 +467,7 @@ Humano.roncar() #=> "*roncar*"
# Puedes importar módulos
import math
-print math.sqrt(16) #=> 4
+print math.sqrt(16) #=> 4.0
# Puedes obtener funciones específicas desde un módulo
from math import ceil, floor
diff --git a/es-es/pythonstatcomp-es.html.markdown b/es-es/pythonstatcomp-es.html.markdown
index 0130b72a..b3d2f0ff 100644
--- a/es-es/pythonstatcomp-es.html.markdown
+++ b/es-es/pythonstatcomp-es.html.markdown
@@ -1,5 +1,6 @@
---
-language: Statistical computing with Python
+category: tool
+tool: Statistical Computing with Python
contributors:
- ["e99n09", "https://github.com/e99n09"]
filename: pythonstatcomp-es.py
diff --git a/es-es/scala-es.html.markdown b/es-es/scala-es.html.markdown
new file mode 100644
index 00000000..2dcb9e7f
--- /dev/null
+++ b/es-es/scala-es.html.markdown
@@ -0,0 +1,741 @@
+---
+language: Scala
+filename: learnscala-es.scala
+contributors:
+ - ["George Petrov", "http://github.com/petrovg"]
+ - ["Dominic Bou-Samra", "http://dbousamra.github.com"]
+ - ["Geoff Liu", "http://geoffliu.me"]
+ - ["Ha-Duong Nguyen", "http://reference-error.org"]
+translators:
+ - ["Pablo Arranz Ropero", "http://arranzropablo.com"]
+lang: es-es
+---
+
+Scala - El lenguaje escalable
+
+```scala
+
+/////////////////////////////////////////////////
+// 0. Básicos
+/////////////////////////////////////////////////
+/*
+ Configurar Scala:
+
+ 1) Descarga Scala - http://www.scala-lang.org/downloads
+ 2) Unzip/untar a tu carpeta elegida y pon la subcarpeta bin en tu variable de entorno `PATH`
+*/
+
+/*
+ Prueba REPL
+
+ Scala tiene una herramienta llamada REPL (Read-Eval-Print Loop, en español: Bucle de lectura-evaluación-impresión) que es analogo a interpretes de la linea de comandos en muchos otros lenguajes.
+ Puedes escribir cualquier expresión en Scala y el resultado será evaluado e impreso.
+
+ REPL es una herramienta muy práctica para testear y verificar código.
+ Puedes usarla mientras lees este tutorial para explorar conceptos por tu cuenta.
+*/
+
+// Inicia Scala REPL ejecutando `scala` en tu terminal. Deberías ver:
+$ scala
+scala>
+
+// Por defecto cada expresión que escribes es guardada como un nuevo valor numerado:
+scala> 2 + 2
+res0: Int = 4
+
+// Los valores por defecto pueden ser reusados. Fíjate en el tipo del valor mostrado en el resultado...
+scala> res0 + 2
+res1: Int = 6
+
+// Scala es un lenguaje fuertemente tipado. Puedes usar REPL para comprobar el tipo sin evaluar una expresión.
+scala> :type (true, 2.0)
+(Boolean, Double)
+
+// Las sesiones REPL pueden ser guardadas
+scala> :save /sites/repl-test.scala
+
+// Se pueden cargar archivos en REPL
+scala> :load /sites/repl-test.scala
+Loading /sites/repl-test.scala...
+res2: Int = 4
+res3: Int = 6
+
+// Puedes buscar en tu historial reciente
+scala> :h?
+1 2 + 2
+2 res0 + 2
+3 :save /sites/repl-test.scala
+4 :load /sites/repl-test.scala
+5 :h?
+
+// Ahora que sabes como jugar, aprendamos un poco de Scala...
+
+/////////////////////////////////////////////////
+// 1. Básicos
+/////////////////////////////////////////////////
+
+// Los comentarios de una linea comienzan con dos barras inclinadas
+
+/*
+ Los comentarios de varias lineas, como ya has visto arriba, se hacen de esta manera.
+*/
+
+// Así imprimimos forzando una nueva linea en la siguiente impresión
+println("Hola mundo!")
+println(10)
+// Hola mundo!
+// 10
+
+// Así imprimimos sin forzar una nueva linea en la siguiente impresión
+print("Hola mundo")
+print(10)
+// Hola mundo10
+
+// Para declarar valores usamos var o val.
+// Valores decalrados con val son inmutables, mientras que los declarados con var son mutables.
+// La inmutabilidad es algo bueno.
+val x = 10 // x es 10
+x = 20 // error: reassignment to val
+var y = 10
+y = 20 // y es 20
+
+/*
+ Scala es un lenguaje tipado estáticamente, aunque se puede ver en las expresiones anteriores que no hemos especificado un tipo.
+ Esto es debido a una funcionalidad del lenguaje llamada inferencia. En la mayoría de los casos, el compilador de Scala puede adivinar cual es el tipo de una variable, así que no hace falta escribirlo siempre.
+ Podemos declarar explicitamente el tipo de una variable de la siguiente manera:
+*/
+val z: Int = 10
+val a: Double = 1.0
+
+// Observa la conversión automática de Int a Double, el resultado será 10.0, no 10
+val b: Double = 10
+
+// Valores Booleanos
+true
+false
+
+// Operaciones Booleanas
+!true // false
+!false // true
+true == false // false
+10 > 5 // true
+
+// Las operaciones matemáticas se realizan como siempre
+1 + 1 // 2
+2 - 1 // 1
+5 * 3 // 15
+6 / 2 // 3
+6 / 4 // 1
+6.0 / 4 // 1.5
+6 / 4.0 // 1.5
+
+
+// Evaluar una expresión en REPL te da el tipo y valor del resultado
+
+1 + 7
+
+/* La linea superior tienen como resultado:
+
+ scala> 1 + 7
+ res29: Int = 8
+
+ Esto quiere decir que el resultado de evaluar 1 + 7 es un objeto de tipo Int con valor 8
+
+ Observa que "res29" es un nombre de variable secuencialmente generado para almacenar los resultados de las expresiones escritas, la salida que observes puede diferir en este sentido.
+*/
+
+"Las cadenas en Scala están rodeadas por comillas dobles"
+'a' // Un caracter en Scala
+// 'Las cadenas con comillas simples no existen' <= Esto causa un error
+
+// Las cadenas tienen los los típicos metodos de Java definidos
+"hello world".length
+"hello world".substring(2, 6)
+"hello world".replace("C", "3")
+
+// También tienen algunos métodos extra de Scala. Ver: scala.collection.immutable.StringOps
+"hello world".take(5)
+"hello world".drop(5)
+
+// Interpolación de cadenas: Observa el prefijo "s"
+val n = 45
+s"Tengo $n manzanas" // => "Tengo 45 manzanas"
+
+// Es posible colocar expresiones dentro de cadenas interpoladas
+val a = Array(11, 9, 6)
+s"Mi segunda hija tiene ${a(0) - a(2)} años." // => "Mi segunda hija tiene 5 años."
+s"Hemos doblado la cantidad de ${n / 2.0} manzanas." // => "Hemos doblado la cantidad de 22.5 manzanas."
+s"Potencia de 2: ${math.pow(2, 2)}" // => "Potencia de 2: 4"
+
+// Podemos formatear cadenas interpoladas con el prefijo "f"
+f"Potencia de 5: ${math.pow(5, 2)}%1.0f" // "Potencia de 5: 25"
+f"Raiz cuadrada de 122: ${math.sqrt(122)}%1.4f" // "Raiz cuadrada de 122: 11.0454"
+
+// Las cadenas puras ignoran caracteres especiales.
+raw"Nueva linea: \n. Retorno: \r." // => "Nueva linea: \n. Retorno: \r."
+
+// Algunos caracteres necesitn ser escapados, por ejemplo unas comillas dobles dentro de una cadena:
+"Se quedaron fuera de \"Rose and Crown\"" // => "Se quedaron fuera de "Rose and Crown""
+
+// Las triples comillas dobles dejan que las cadenas se expandan por multiples filas y contengan comillas dobles o simples
+val html = """<form id="daform">
+ <p>Press belo', Joe</p>
+ <input type="submit">
+ </form>"""
+
+
+/////////////////////////////////////////////////
+// 2. Funciones
+/////////////////////////////////////////////////
+
+// Las funciones se definen de la siguiente manera:
+//
+// def nombreFuncion(argumentos...): TipoRetorno = { cuerpo... }
+//
+// Si estás acostumbrado a lenguajes más tradicionales, observa la omisión de la palabra return.
+// En Scala, la última expresión en el bloque de función es el valor de retorno.
+def sumaDeCuadrados(x: Int, y: Int): Int = {
+ val x2 = x * x
+ val y2 = y * y
+ x2 + y2
+}
+
+// Los { } pueden omitirse si el cuerpo de la función es una única expresión:
+def sumaDeCuadradosCorta(x: Int, y: Int): Int = x * x + y * y
+
+// La sintaxis para llamar funciones es familiar:
+sumaDeCuadrados(3, 4) // => 25
+
+// Puedes usar los nombres de los parámetros para llamarlos en orden diferente
+def restar(x: Int, y: Int): Int = x - y
+
+restar(10, 3) // => 7
+restar(y=10, x=3) // => -7
+
+// En la mayoría de los casos (siendo las funciones recursivas la excepción más notable),
+// el tipo de retorno de la función puede ser omitido, y la misma inferencia de tipos que vimos con las variables
+// funcionará con los valores de retorno de las funciones:
+def sq(x: Int) = x * x // El compilador puede adivinar que el tipo de retorno es Int
+
+// Las funciones pueden tener parametros por defecto:
+def sumarConDefecto(x: Int, y: Int = 5) = x + y
+sumarConDefecto(1, 2) // => 3
+sumarConDefecto(1) // => 6
+
+
+// Las funciones anónimas se escriben así:
+(x: Int) => x * x
+
+// Al contrario que los defs, incluso el tipo de entrada de las funciones anónimas puede ser omitido si
+// el contexto lo deja claro. Observa el tipo "Int => Int" que significa que es una función
+// que recibe Int y retorna Int.
+val sq: Int => Int = x => x * x
+
+// Las funciones anónimas pueden ser llamadas como las demás:
+sq(10) // => 100
+
+// Si cada argumento en tu función anónima es usado solo una vez,
+// Scala te da una manera incluso más corta de definirlos.
+// Estas funciones anónimas son extremadamente comunes,
+// como será obvio en la sección de estructuras de datos.
+val sumarUno: Int => Int = _ + 1
+val sumaRara: (Int, Int) => Int = (_ * 2 + _ * 3)
+
+sumarUno(5) // => 6
+sumaRara(2, 4) // => 16
+
+
+// La palabra return existe en Scala, pero solo retorna desde la función más interna que la rodea.
+// ADVERTENCIA: Usar return en Scala puede inducir a errores y debe ser evitado
+// No tiene efecto en funciones anónimas. Por ejemplo:
+def foo(x: Int): Int = {
+ val funcAnon: Int => Int = { z =>
+ if (z > 5)
+ return z // Esta línea hace que z sea el valor de retorno de foo!
+ else
+ z + 2 // Esta línea es el valor de retorno de funcAnon
+ }
+ anonFunc(x) // Esta línea es el valor de retorno de foo
+}
+
+
+/////////////////////////////////////////////////
+// 3. Control del flujo
+/////////////////////////////////////////////////
+
+1 to 5
+val r = 1 to 5
+r.foreach(println)
+
+r foreach println
+// Nota: Scala es un lenguaje muy permisivo cuando se trata de puntos y parentesis - estudia las
+// reglas separadamente. Esto ayuda a escribir DSLs y APIs que se lean en lenguaje natural.
+
+// Por qué `println` no necesita parámetros aquí?
+// Presta atención a las funciones de primera clase en la sección de Programación Funcional más abajo!
+(5 to 1 by -1) foreach (println)
+
+// Un bucle while
+var i = 0
+while (i < 10) { println("i " + i); i += 1 }
+
+while (i < 10) { println("i " + i); i += 1 } // Si, de nuevo. Qué ocurrió? Por qué?
+
+i // Muestra el valor de i. Observa que while es un loop en el sentido clásico -
+ // se ejecuta secuencialmente mientras cambia la variable del bucle. while es muy
+ // rápido, pero los combinadores y comprensiones anteriores son más sencillos
+ // de entender y paralelizar
+
+// Un bucle do-while
+i = 0
+do {
+ println("i es aún menor que 10")
+ i += 1
+} while (i < 10)
+
+// La recursion es la manera idiomática de repetir una acción en Scala (como en la mayoría de
+// lenguajes funcionales).
+// Las funciones recursivas necesitan un tipo de retorno explicito, el compilador no puede inferirlo.
+// En Scala tenemos Unit, que es análogo al tipo de retorno `void` en Java
+def enseñaNumerosEnUnRango(a: Int, b: Int): Unit = {
+ print(a)
+ if (a < b)
+ enseñaNumerosEnUnRango(a + 1, b)
+}
+enseñaNumerosEnUnRango(1, 14)
+
+
+// Condicionales
+
+val x = 10
+
+if (x == 1) println("yeah")
+if (x == 10) println("yeah")
+if (x == 11) println("yeah")
+if (x == 11) println("yeah") else println("nay")
+
+println(if (x == 10) "yeah" else "nope")
+val text = if (x == 10) "yeah" else "nope"
+
+
+/////////////////////////////////////////////////
+// 4. Estructuras de datos
+/////////////////////////////////////////////////
+
+val a = Array(1, 2, 3, 5, 8, 13)
+a(0) // Int = 1
+a(3) // Int = 5
+a(21) // Lanza una excepción
+
+val m = Map("fork" -> "tenedor", "spoon" -> "cuchara", "knife" -> "cuchillo")
+m("fork") // java.lang.String = tenedor
+m("spoon") // java.lang.String = cuchara
+m("bottle") // Lanza una excepción
+
+val mapaSeguro = m.withDefaultValue("no lo se")
+mapaSeguro("bottle") // java.lang.String = no lo se
+
+val s = Set(1, 3, 7)
+s(0) // Boolean = false
+s(1) // Boolean = true
+
+/* Hecha un vistazo a la documentación de Map aquí -
+ * http://www.scala-lang.org/api/current/index.html#scala.collection.immutable.Map
+ * y asegúrate de que puedes leerla
+ */
+
+
+// Tuplas
+
+(1, 2)
+
+(4, 3, 2)
+
+(1, 2, "three")
+
+(a, 2, "three")
+
+// Por qué tener esto?
+val dividirEnteros = (x: Int, y: Int) => (x / y, x % y)
+
+// La función dividirEnteros te da el resultado y el resto
+dividirEnteros(10, 3) // (Int, Int) = (3,1)
+
+// Para acceder a los elementos de una tupla, usa _._n donde n es el indice (comenzando por 1)
+// del elemento
+val d = dividirEnteros(10, 3) // (Int, Int) = (3,1)
+
+d._1 // Int = 3
+d._2 // Int = 1
+
+// Alternativamente puedes asignar multiples variables desde una tupla, lo que
+// resulta más conveniente y legible en muchos casos.
+val (div, mod) = dividirEnteros(10, 3)
+
+div // Int = 3
+mod // Int = 1
+
+
+/////////////////////////////////////////////////
+// 5. Programación Orientada a Objetos
+/////////////////////////////////////////////////
+
+/*
+ Nota: Todo lo que hemos hecho hasta ahora en este tutorial han sido
+ simples expresiones (valores, funciones, etc). Estas expresiones son validas
+ para hacer pruebas rapidas en el interprete de la linea de comandos,
+ pero no pueden existir por si solas en un archivo de Scala. Por ejemplo,
+ no puedes tener simplemente "val x = 5" en un archivo Scala. En lugar de eso,
+ las únicas construcciones de alto nivel en Scala son:
+
+ - Objetos
+ - Clases
+ - Case clases
+ - Traits
+
+ Y ahora explicaremos lo que son estas.
+*/
+
+// Las clases son similares a las clases de otros lenguajes. Los argumentos del constructor
+// son declarados despues del nombre de la clase, y la inicialización se hace en el cuerpo de la clase.
+class Perro(r: String) {
+ // Código del constructor aquí
+ var raza: String = r
+
+ // Define un método llamado ladrar, que devuelva un String
+ def ladrar = "Woof, woof!"
+
+ // Los valores y métodos son asumidos como públicos.
+ // Las palabras "protected" y "private" también son válidas.
+ private def dormir(horas: Int) =
+ println(s"Estoy durmiendo $horas horas")
+
+ // Los métodos abstractos son simplemente métodos sin cuerpo.
+ // Si descomentamos la linea de debajo, la clase Perro necesitaría ser abstracta:
+ // abstract class Perro(...) { ... }
+ // def perseguir(algo: String): String
+}
+
+val miperro = new Dog("greyhound")
+println(mydog.raza) // => "greyhound"
+println(mydog.ladrar) // => "Woof, woof!"
+
+
+// La palabra "object" crea un tipo y una instancia singleton de ese tipo.
+// Es común que las clases en Scala tengan un "companion object", de manera que
+// el comportamiento por instancia es controlado por las clases y el comportamiento
+// relacionado a todas las instancias de esa clase es controlado por el objeto
+// La relación es similar a los métodos de las clases con los métodos estáticos
+// en otros lenguajes. Observa que los objetos y clases pueden tener el mismo nombre.
+object Perro {
+ def todasLasRazasConocidas = List("pitbull", "shepherd", "retriever")
+ def crearPerro(raza: String) = new Dog(breed)
+}
+
+
+// Case clases son clases que tienen funcionalidad extra añadida. Una pregunta
+// común para los principiantes en Scala es cuando usar case clases y cuando usar
+// clases. La linea no está bien definida, pero en general, las clases tienden a
+// enfocarse en la encapsulación, polimorfismo y comportamiento. Los valores en
+// estas clases tienden a ser privados, y solo se exponen los métodos.
+// El propósito principal de las case clases es tener datos inmutables.
+// A menudo tienen pocos métodos, y los métodos raramente tienen efectos secundarios.
+case class Persona(nombre: String, telefono: String)
+
+// Para crear instancia nuevas, observa que las case clases no necesitan "new"
+val george = Persona("George", "1234")
+val kate = Persona("Kate", "4567")
+
+// Con las case clases tienes unas pocas ventajas, como el acceso a los campos:
+george.telefono // => "1234"
+
+// Para la igualdad de campos no necesitas sobreescribir el método equals
+Persona("George", "1234") == Persona("Kate", "1236") // => false
+
+// Manera fácil de copiar
+// otroGeorge == Persona("George", "9876")
+val otroGeorge = george.copy(telefono = "9876")
+
+// Y muchas otras. Las case clases también tienen comparación de patrones, que veremos más abajo.
+
+// Traits
+// De manera similar a las interfaces Java, los traits definen un tipo de objeto y métodos.
+// Scala permite la implementación parcial de dichos métodos.
+// No se permiten parámetros de constructor. Los traits pueden heredar de otros traits o
+// clases sin parámetros.
+
+trait Perro {
+ def raza: String
+ def color: String
+ def ladra: Boolean = true
+ def muerde: Boolean
+}
+class SanBernardo extends Perro {
+ val raza = "San Bernardo"
+ val color = "marrón"
+ def muerde = false
+}
+
+scala> b
+res0: SanBernardo = SanBernardo@3e57cd70
+scala> b.raza
+res1: String = San Bernardo
+scala> b.ladra
+res2: Boolean = true
+scala> b.muerde
+res3: Boolean = false
+
+// Un trait tambien puede ser usado mezclado con otros traits.
+// La clase extiende el primer trait, pero la palabra "with"
+// puede añadir traits adicionales.
+
+trait Ladra {
+ def ladra: String = "Guau"
+}
+trait Perro {
+ def raza: String
+ def color: String
+}
+class SanBernardo extends Perro with Ladra {
+ val raza = "San Bernardo"
+ val color = "marrón"
+}
+
+scala> val b = new SanBernardo
+b: SanBernardo = SanBernardo@7b69c6ba
+scala> b.ladra
+res0: String = Guau
+
+
+/////////////////////////////////////////////////
+// 6. Comparación de patrones
+/////////////////////////////////////////////////
+
+// La comparación de patrones es una poderosa función de Scala.
+// Ahora veremos como comparar patrones en una case clase.
+// Nota: A diferencia de otros lenguajes, Scala "cases" no necesitan
+// "break", porque no ejecuta los "case" posteriores.
+
+def comparaPersona(persona: Persona): String = persona match {
+ // Aqui especificas los patrones:
+ case Persona("George", telefono) => "Hemos encontrado a George! Su número es " + telefono
+ case Persona("Kate", telefono) => "Hemos encontrado a Kate! Su número es " + telefono
+ case Persona(nombre, telefono) => "Hemos encontrado alguien : " + nombre + ", teléfono : " + telefono
+}
+
+// Las expresiones regulares también están incorporadas.
+// Creas una expresión regular con el método `r` en una cadena:
+val email = "(.*)@(.*)".r
+
+// La comparación de patrones puede parecerse al bloque switch en la familia de lenguajes de C,
+// pero aquí es mucho más poderosa. En Scala, puedes hacer más comparaciones:
+def comparaTodo(obj: Any): String = obj match {
+ // Puedes comparar valores:
+ case "Hola mundo" => "Tengo la cadena Hola mundo"
+
+ // Puedes comparar tipos:
+ case x: Double => "Tengo un double: " + x
+
+ // Puedes especificar condiciones:
+ case x: Int if x > 10000 => "Tengo un número muy grande!"
+
+ // Puedes comparar case clases como antes:
+ case Persona(nombre, telefono) => s"Tengo la información de contacto de $nombre!"
+
+ // Puedes comparar expresiones regulares:
+ case email(nombre, dominio) => s"Tengo la dirección de correo $nombre@$dominio"
+
+ // Puedes comparar tuplas:
+ case (a: Int, b: Double, c: String) => s"Tengo la tupla: $a, $b, $c"
+
+ // Puedes comparar estructuras:
+ case List(1, b, c) => s"Tengo un alista con tres elementos que empieza con 1: 1, $b, $c"
+
+ // Puedes anidar patrones:
+ case List(List((1, 2, "YAY"))) => "Tengo una lista de listas de tuplas"
+
+ // Comparar cualquier case (default) si todos los anteriores no han coincido
+ case _ => "Tengo un objeto desconocido"
+}
+
+// De hecho puedes comparar un patrón con cualquier objeto con el método "unapply".
+// Esta función es tan poderosa que Scala te deja definir funciones enteras como patrones:
+val funcPatron: Person => String = {
+ case Persona("George", telefono) => s"Teléfono de George: $telefono"
+ case Persona(nombre, telefono) => s"Teléfono de una persona aleatoria: $telefono"
+}
+
+
+/////////////////////////////////////////////////
+// 7. Programación funcional
+/////////////////////////////////////////////////
+
+// Scala permite a los métodos y funciones devolver o
+// recibir como parámetros otras funciones o métodos
+
+val suma10: Int => Int = _ + 10 // Una función que recibe y devuelve un Int
+List(1, 2, 3) map suma10 // List(11, 12, 13) - suma10 es aplicado a cada elemento
+
+// Las funciones anónimas pueden ser usadas en vez de funciones con nombre:
+List(1, 2, 3) map (x => x + 10)
+
+// Y la barra baja puede ser usada si solo hay un argumento en la función anónima.
+// Se usa como la variable.
+List(1, 2, 3) map (_ + 10)
+
+// Si el bloque anónimo Y la función que estás usando usan los dos un argumento,
+// puedes incluso omitir la barra baja.
+List("Dom", "Bob", "Natalia") foreach println
+
+
+// Combinadores
+// Usando s de arriba:
+// val s = Set(1, 3, 7)
+
+s.map(sq)
+
+val sCuadrado = s. map(sq)
+
+sSquared.filter(_ < 10)
+
+sSquared.reduce (_+_)
+
+// La función filter toma un predicado (una función A -> Boolean) y
+// selecciona todos los elementos que satisfacen el predicado.
+List(1, 2, 3) filter (_ > 2) // List(3)
+case class Persona(nombre: String, edad: Int)
+List(
+ Persona(nombre = "Dom", edad = 23),
+ Persona(nombre = "Bob", edad = 30)
+).filter(_.edad > 25) // List(Persona("Bob", 30))
+
+
+// Ciertas colecciones (como List) en Scala tienen un método `foreach`,
+// que toma como argumento un tipo que devuelva Unit (un método void)
+val unaListaDeNumeros = List(1, 2, 3, 4, 10, 20, 100)
+unaListaDeNumeros foreach (x => println(x))
+unaListaDeNumeros foreach println
+
+// Para comprensiones
+
+for { n <- s } yield sq(n)
+
+val nCuadrado2 = for { n <- s } yield sq(n)
+
+for { n <- nSquared2 if n < 10 } yield n
+
+for { n <- s; nSquared = n * n if nSquared < 10} yield nSquared
+
+/* Nota: Esos no son bucles. La semántica de un bucle es repetir, mientras que un for de comprension define una relación entre dos conjuntos de datos.*/
+
+
+/////////////////////////////////////////////////
+// 8. Implicitos
+/////////////////////////////////////////////////
+
+/* ATENCIÓN ATENCIÓN: Los implicitos son un conjunto de poderosas características de Scala
+ * y es fácil abusar de ellos. Si eres principiante en Scala deberías resistir la tentación
+ * de usarlos hasta que entiendas no solo como funcionan, sino también las mejores prácticas
+ * con ellos. Nosotros solo incluiremos esta sección en el tutorial porque son tan comunes
+ * en las librerias de Scala que es imposible hacer algo significativo sin usar una librería
+ * que tenga implicitos. Esto es para que entiendas como funcionan los implicitos, no para
+ * que definas los tuyos propios.
+ */
+
+// Cualquier valor (val, funciones, objetos, etc) puede ser declarado como implicito usando
+// la palabra "implicit". Observa que usamos la clase Perro de la sección 5.
+implicit val miEnteroImplicito = 100
+implicit def miFunciónImplicita(raza: String) = new Perro("Golden " + raza)
+
+// Por si misma, la palabra implicit no cambia el comportamiento de un valor,
+// así que estos valores pueden ser usados como siempre.
+miEnteroImplicito + 2 // => 102
+miFunciónImplicita("Pitbull").raza // => "Golden Pitbull"
+
+// La diferencia es que estos valores ahora pueden ser usados cuando otra pieza de código
+// necesite un valor implicito. Una situación así puede darse con argumentos implicitos de función:
+def enviaSaludos(aQuien: String)(implicit cuantos: Int) =
+ s"Hola $aQuien, $cuantos saludos a ti y a los tuyos!"
+
+// Si proporcionamos un valor para "cuantos", la función se comporta como siempre
+enviaSaludos("John")(1000) // => "Hola John, 1000 saludos a ti y a los tuyos!"
+
+// Pero si omitimos el parámetro implicito, un valor implicito del mismo tipo es usado,
+// en este caso, "miEnteroImplicito":
+enviaSaludos("Jane") // => "Hello Jane, 100 blessings to you and yours!"
+
+// Los parámetros de función implicit nos permiten simular clases tipo en otros lenguajes funcionales.
+// Es usado tan a menudo que tiene su propio atajo. Las dos siguientes lineas significan lo mismo:
+// def foo[T](implicit c: C[T]) = ...
+// def foo[T : C] = ...
+
+
+// Otra situación en la que el compilador busca un implicit es si tienes
+// obj.método(...)
+// pero "obj" no tiene "método" como un método. En este caso, si hay una conversión
+// implicita de tipo A => B, donde A es el tipo de obj y B tiene un método llamado
+// "método", esa conversión es aplicada. Así que teniendo miFunciónImplicita, podemos decir:
+"Retriever".raza // => "Golden Retriever"
+"Sheperd".ladra // => "Woof, woof!"
+
+// Aquí la cadena es convertida primero a Perro usando nuestra función miFunciónImplicita,
+// y entonces el método apropiado es llamado. Esta es una herramienta extremadamente poderosa
+// pero de nuevo, no puede usarse con ligereza. De hecho, cuando definiste la función implicita,
+// tu compilador debería haber mostrado una advertencia, diciendo que no deberías hacer esto
+// a no ser que realmente sepas lo que estás haciendo.
+
+/////////////////////////////////////////////////
+// 9. Misc
+/////////////////////////////////////////////////
+
+// Importando cosas
+import scala.collection.immutable.List
+
+// Importando todos los "sub paquetes"
+import scala.collection.immutable._
+
+// Importando multiples clases en una línea
+import scala.collection.immutable.{List, Map}
+
+// Renombrar un import usando '=>'
+import scala.collection.immutable.{List => ImmutableList}
+
+// Importar todas las clases, excepto algunas. La siguiente linea excluye Map y Set:
+import scala.collection.immutable.{Map => _, Set => _, _}
+
+// Las clases de Java pueden ser importadas también con sintaxis de Scala:
+import java.swing.{JFrame, JWindow}
+
+// El punto de entrada de tus programas está definido en un fichero scala usando un object,
+// con un solo método, main:
+object Application {
+ def main(args: Array[String]): Unit = {
+ // Aquí va tu código.
+ }
+}
+
+// Los ficheros pueden contener multiples clases y objetos. Compila con scalac
+
+
+// Salida y entrada
+
+// Leer un fichero línea por línea
+import scala.io.Source
+for(line <- Source.fromFile("miarchivo.txt").getLines())
+ println(line)
+
+// Para escribir un archivo usa el PrintWriter de Java
+val writer = new PrintWriter("miarchivo.txt")
+writer.write("Escribiendo linea por linea" + util.Properties.lineSeparator)
+writer.write("Otra linea" + util.Properties.lineSeparator)
+writer.close()
+
+```
+
+## Más recursos
+
+* [Scala para los impacientes](http://horstmann.com/scala/)
+* [Escuela de Scala en Twitter](http://twitter.github.io/scala_school/)
+* [La documentación de Scala](http://docs.scala-lang.org/)
+* [Prueba Scala en tu navegador](http://scalatutorials.com/tour/)
+* Unete al [grupo de usuarios de Scala](https://groups.google.com/forum/#!forum/scala-user)
diff --git a/es-es/visualbasic-es.html.markdown b/es-es/visualbasic-es.html.markdown
index ca00626b..c677c20f 100644
--- a/es-es/visualbasic-es.html.markdown
+++ b/es-es/visualbasic-es.html.markdown
@@ -4,8 +4,6 @@ contributors:
- ["Brian Martin", "http://brianmartin.biz"]
translators:
- ["Adolfo Jayme Barrientos", "https://github.com/fitojb"]
-author: Brian Martin
-author_url: https://github.com/fitojb
filename: learnvisualbasic-es.vb
lang: es-es
---
diff --git a/fr-fr/awk-fr.html.markdown b/fr-fr/awk-fr.html.markdown
new file mode 100644
index 00000000..75c48811
--- /dev/null
+++ b/fr-fr/awk-fr.html.markdown
@@ -0,0 +1,377 @@
+---
+category: tool
+tool: awk
+filename: learnawk-fr.awk
+contributors:
+ - ["Marshall Mason", "http://github.com/marshallmason"]
+translators:
+ - ["GannonTdW", "https://github.com/GannonTdW"]
+lang: fr-fr
+
+---
+
+AWK est un outil standard présent dans chaque système UNIX conforme aux normes POSIX.
+C’est un outil en ligne de commande qui ressemble au Perl et qui est excellent dans les tâches de traitement de fichiers texte.
+Vous pouvez l’appeler à partir d’un script shell, ou l’utiliser comme un langage de script autonome.
+
+Pourquoi utiliser AWK au lieu du langage Perl ?
+Principalement, car AWK fait partie d'UNIX et est donc présent par défaut sur une très grande partie des systèmes d'exploitation UNIX et Linux.
+AWK est aussi plus facile à lire que le langage Perl ; et est l'outil idéal pour ce qui concerne le traitement de texte simple. Notamment le traitement de ceux qui necéssitent de lire des fichiers ligne par ligne ; chaque ligne comportant des champs séparés par des délimiteur.
+
+
+```awk
+#!/usr/bin/awk -f
+
+# Les commentaires commencent par un #
+
+
+# les programmes AWK consistent en une collection de règles et d'actions
+règle1 { action; }
+règle2 { action; }
+
+# AWK lit et analyse automatiquement chaque ligne de chaque fichier fourni.
+# Chaque ligne est divisée par un délimiteur FS qui est par défaut l'espace (plusieurs espaces ou une tabulation comptent pour un espace). Ce délimiteur peut être changer grâce à l'option -F ou être renseigné au début d'un bloc (exemple: FS = " ").
+
+# BEGIN est une règle spécifique exécutée au début du programme. C'est à cet endroit que vous mettrez tout le code à exécuter avant de traiter les fichiers texte. Si vous ne disposez pas de fichiers texte, considérez BEGIN comme le point d’entrée principal du script.
+# A l'opposé de BEGIN, il existe la règle END. Cette règle est présente après chaque fin de fichier (EOF : End Of File).
+
+BEGIN {
+
+ # Les variables sont globales. Pas besoin de les déclarer.
+ count = 0;
+
+ # les opérateurs sont identiques au langage C et aux langages similaires (exemple: C#, C++)
+ a = count + 1; # addition
+ b = count - 1; # soustraction
+ c = count * 1; # multiplication
+ d = count / 1; # division entière
+ e = count % 1; # modulo, reste de la division entière
+ f = count ^ 1; # exponentiel
+
+ a += 1;
+ b -= 1;
+ c *= 1;
+ d /= 1;
+ e %= 1;
+ f ^= 1;
+
+ # Incrémenter et décrémenter par un
+ a++;
+ b--;
+
+ # En tant qu'opérateur préfixé, c'est la valeur incrémentée qui est retournée
+ ++a;
+ --b;
+
+ # Instruction de contrôle
+ if (conteur == 0)
+ print "Nombre de départ 0";
+ else
+ print "Hein?";
+
+ # Vous pouvez aussi utiliser l'opérateur ternaire
+ print (compteur == 0) ? "Nombre de départ 0" : "Hein?";
+
+ # Les blocs sont composés d'une multitude de lignes entre accolades
+ while (a < 10) {
+ print "La concaténation de chaînes de caractères" " se fait avec des séries de chaînes " " séparées par des espaces";
+ print a;
+
+ a++;
+ }
+
+ for (i = 0; i < 10; i++)
+ print "le bon vieux for pour les boucles";
+
+ # Les opérateurs de comparaison sont standard
+ # a < b # plus petit que
+ # a <= b # plus petit ou égale à
+ # a != b # non égale
+ # a == b # égale
+ # a > b # Plus grand que
+ # a >= b # Plus grand ou égale à
+
+ # Les opérateurs logiques sont
+ # a && b # ET
+ # a || b # OU
+
+ # En plus, il y a les expressions régulières
+ if ("foo" ~ "^fo+$")
+ print "Fooey!";
+ if ("boo" !~ "^fo+$")
+ print "Boo!";
+
+ # Les Tableaux
+ arr[0] = "foo";
+ arr[1] = "bar";
+
+ # Vous pouvez aussi initialiser un tableau avec la fonction split()
+
+ n = split("foo:bar:baz", arr, ":");
+
+ # Il y a aussi les tableaux associatifs
+ assoc["foo"] = "bar";
+ assoc["bar"] = "baz";
+
+ # et les tableaux multi-dimentions, avec certaines limitations que l'on ne mentionnera pas ici
+ multidim[0,0] = "foo";
+ multidim[0,1] = "bar";
+ multidim[1,0] = "baz";
+ multidim[1,1] = "boo";
+
+ # Vous pouvez tester l'appartenance à un tableau
+ if ("foo" in assoc)
+ print "Fooey!";
+
+ # Vous pouvez aussi utilisez l'opérateur 'in' pour parcourir les clés d'un tableau
+ for (key in assoc)
+ print assoc[key];
+
+ # La ligne de commande est dans un tableau spécifique appelé ARGV
+ for (argnum in ARGV)
+ print ARGV[argnum];
+
+ # Vous pouvez supprimer des éléments d'un tableau
+ # C'est utile pour empêcher AWK de supposer que certains arguments soient des fichiers à traiter.
+ delete ARGV[1];
+
+ # Le nombre d'arguments de la ligne de commande est dans une variable appellée ARGC
+ print ARGC;
+
+ # AWK inclue trois catégories de fonction.
+ # On les examinera plus tard
+
+ return_value = arithmetic_functions(a, b, c);
+ string_functions();
+ io_functions();
+}
+
+# Voici comment définir une fonction
+function arithmetic_functions(a, b, c, d) {
+
+ # La partie la plus ennuieuse de AWK est probablement l’absence de variables locales.
+ # Tout est global. Pour les scripts courts, c'est très utile, mais pour les scripts plus longs,
+ # cela peut poser problème.
+
+ # Il y a cepandant une solution de contournement (enfin ... une bidouille).
+ # Les arguments d'une fonction sont locaux à cette fonction.
+ # Et AWK vous permet de définir plus d'arguments à la fonction que nécessaire.
+ # Il suffit donc de mettre une variable locale dans la déclaration de fonction,
+ # comme ci-dessus. La convention veut que vous mettiez quelques espaces supplémentaires
+ # pour faire la distinction entre les paramètres réels et les variables locales.
+ # Dans cet exemple, a, b et c sont des paramètres réels,
+ # alors que d est simplement une variable locale.
+
+ # Maintenant, les fonctions arithmétiques
+
+ # La plupart des implémentations de AWK ont des fonctions trigonométriques standards
+ localvar = sin(a);
+ localvar = cos(a);
+ localvar = atan2(b, a); # arc tangente de b / a
+
+ # Les exponentiels et logarithmes décimaux sont aussi là
+ localvar = exp(a);
+ localvar = log(a);
+
+ # Les racines carrées
+ localvar = sqrt(a);
+
+ # Tronquer un nombre décimal en nombre entier
+ localvar = int(5.34); # localvar => 5
+
+ # Les nombres aléatoires
+ srand();
+ # L'argument de la fonction srand() est la valeur de départ pour générer
+ # les nombres aléatoires . Par défaut, il utilise l'heure du système
+
+ localvar = rand(); # Nombre aléatoire entre 0 et 1.
+
+ # Maintenant on retourne la valeur
+ return localvar;
+}
+
+function string_functions( localvar, arr) {
+
+ # AWK a plusieurs fonctions pour le traitement des chaînes de caractères,
+ # dont beaucoup reposent sur des expressions régulières.
+
+ # Chercher et remplacer, la première occurence (sub) ou toutes les occurences (gsub)
+ # Les deux renvoient le nombre de correspondances remplacées
+ localvar = "fooooobar";
+ sub("fo+", "Meet me at the ", localvar); # localvar => "Meet me at the bar"
+ gsub("e+", ".", localvar); # localvar => "m..t m. at th. bar"
+
+ # Rechercher une chaîne de caractères qui correspond à une expression régulière
+ # index() fait la même chose, mais n'autorise pas les expressions régulières
+ match(localvar, "t"); # => 4, puisque 't' est le quatrième caractère
+
+ # Séparer par un délimiteur
+ n = split("foo-bar-baz", arr, "-"); # a[1] = "foo"; a[2] = "bar"; a[3] = "baz"; n = 3
+
+ # Autre astuces utiles
+ sprintf("%s %d %d %d", "Testing", 1, 2, 3); # => "Testing 1 2 3"
+ substr("foobar", 2, 3); # => "oob"
+ substr("foobar", 4); # => "bar"
+ length("foo"); # => 3
+ tolower("FOO"); # => "foo"
+ toupper("foo"); # => "FOO"
+}
+
+function io_functions( localvar) {
+
+ # Vous avez déjà vu print
+ print "Hello world";
+
+ # Mais il y a aussi printf
+ printf("%s %d %d %d\n", "Testing", 1, 2, 3);
+
+ # AWK n'a pas de descripteur de fichier en soi. Il ouvrira automatiquement
+ # un descripteur de fichier lorsque vous utilisez quelque chose qui en a besoin.
+ # La chaîne de caractères que vous avez utilisée pour cela peut être traitée
+ # comme un descripteur de fichier à des fins d'entrée / sortie.
+
+ outfile = "/tmp/foobar.txt";
+
+ print "foobar" > outfile;
+
+ # Maintenant, la chaîne de caractères "outfile" est un descripteur de fichier.
+ # Vous pouvez le fermer
+ close(outfile);
+
+ # Voici comment exécuter quelque chose dans le shell
+ system("echo foobar"); # => affiche foobar
+
+ # Lire quelque chose depuis l'entrée standard et la stocker dans une variable locale
+ getline localvar;
+
+ # Lire quelque chose à partir d'un pipe (encore une fois, utilisez une chaine de caractère
+ # que vous fermerez proprement)
+ "echo foobar" | getline localvar # localvar => "foobar"
+ close("echo foobar")
+
+ # Lire une ligne d'un fichier et la stocker dans une variable locale
+ infile = "/tmp/foobar.txt";
+ getline localvar < infile;
+ close(infile);
+}
+
+# Comme dit au début, AWK consiste en une collection de règles et d'actions.
+# Vous connaissez déjà les règles BEGIN et END. Les autres règles ne sont utilisées que si vous traitez
+# des lignes à partir de fichiers ou l'entrée standard (stdin).
+# Quand vous passez des arguments à AWK, ils sont considérés comme des noms de fichiers à traiter.
+# AWK les traitera tous dans l'ordre. Voyez les comme dans à une boucle implicite,
+# parcourant les lignes de ces fichiers.
+# Ces règles et ces actions ressemblent à des instructions switch dans la boucle.
+
+/^fo+bar$/ {
+
+ # Cette action sera exécutée pour chaque ligne qui correspond à l'expression régulière,
+ # /^fo+bar$/, et sera ignorée pour toute ligne qui n'y correspond pas.
+ # Imprimons simplement la ligne:
+
+ print;
+
+ # Pas d'argument ! C'est parce que print a un défaut : $0.
+ # $0 est le nom de la ligne en cours de traitement. Il est créé automatiquement.
+
+ # Vous devinez probablement qu'il existe d'autres variables $.
+ # Chaque ligne est divisée implicitement avant que chaque action soit exécutée, comme
+ # le fait le shell. Et, comme le shell, chaque champ est accessible avec un signe dollar
+
+ # Ceci affichera les deuxième et quatrième champs de la ligne.
+ print $2, $4;
+
+ # AWK défini automatiquement beaucoup d'autres variables qui peuvent vous aider
+ # à inspecter et traiter chaque ligne. La plus importante est NF
+
+ # Affiche le nombre de champs de la ligne
+ print NF;
+
+ # Afficher le dernier champ de la ligne
+ print $NF;
+}
+
+# Chaque règle est en réalité un test conditionel.
+
+a > 0 {
+ # Ceci s’exécutera une fois pour chaque ligne, tant que le test est positif
+}
+
+# Les expressions régulières sont également des tests conditionels.
+#Si le test de l'expression régulières n'est pas vrais alors le bloc n'est pas executé
+$0 /^fobar/ {
+ print "la ligne commance par fobar"
+}
+
+# Dans le cas où vous voulez tester votre chaine de caractères sur la ligne en cours de traitement
+# $0 est optionnelle.
+
+/^[a-zA-Z0-9]$/ {
+ print "La ligne courante ne contient que des caractères alphanumériques.";
+}
+
+
+# AWK peut parcourir un fichier texte ligne par ligne et exécuter des actions en fonction de règles établies
+# Cela est si courant sous UNIX qu'AWK est un langage de script.
+
+# Ce qui suit est un exemple rapide d'un petit script, pour lequel AWK est parfait.
+# Le script lit un nom à partir de l'entrée standard, puis affiche l'âge moyen de toutes les
+# personnes portant ce prénom.
+# Supposons que vous fournissiez comme argument le nom d'un fichier comportant ces données:
+#
+# Bob Jones 32
+# Jane Doe 22
+# Steve Stevens 83
+# Bob Smith 29
+# Bob Barker 72
+#
+# Le script est le suivant :
+
+BEGIN {
+
+ # Premièrement, on demande à l'utilisateur le prénom voulu
+ print "Pour quel prénom vouldriez vous savoir l'age moyen ?";
+
+ # On récupère la ligne à partir de l'entrée standard, pas de la ligne de commande
+ getline name < "/dev/stdin";
+}
+
+# Maintenant, pour chaque ligne dont le premier champ est le prénom donné
+$1 == name {
+
+ # Ici, nous avons accès à un certain nombre de variables utiles déjà préchargées :
+ # $0 est la ligne entière
+ # $3 est le troisième champ. Ici il correspond à l'age qui nous intéresse
+ # NF est le nombre de champs et vaut 3
+ # NR est le nombre d'enregistrements (lignes) vus jusqu'à présent
+ # FILENAME est le nom du fichier en cours de traitement
+ # FS est séparateur de champs, ici c'est " " (un espace)
+ # ...etc. Et beaucoup d'autre que vous pouvez connaître dans le manuel de man.
+ # Pour cela exécutez "man awk" dans votre terminal
+
+ # Garder une trace du total accumulé et du nombre de lignes correspondant.
+ sum += $3;
+ nlines++;
+}
+
+# Un autre motif spécial est END. Il fonctionnera après le traitement de tous
+# les fichiers texte. Contrairement à BEGIN, il ne fonctionne que si vous lui
+# donnez une entrée à traiter. Il sera exécuté une fois que tous les fichiers
+# auront été lus et traités conformément aux règles et aux actions que vous
+# avez fournies. Le but est généralement de produire un rapport final
+# ou de faire quelque chose avec l'ensemble des données que vous avez
+# accumulées au cours du script.
+
+
+END {
+ if (nlines)
+ print "L'age moyen pour le prénom " name " est " sum / nlines;
+}
+
+```
+Pour plus d'informations :
+
+* [Awk tutorial](http://www.grymoire.com/Unix/Awk.html)
+* [Awk man page](https://linux.die.net/man/1/awk)
+* [The GNU Awk User's Guide](https://www.gnu.org/software/gawk/manual/gawk.html) GNU Awk est dans la majorité des systèmes Linux.
+* [AWK one-liner collection](http://tuxgraphics.org/~guido/scripts/awk-one-liner.html)
diff --git a/fr-fr/erlang-fr.html.markdown b/fr-fr/erlang-fr.html.markdown
index 55453c56..1073d6ad 100644
--- a/fr-fr/erlang-fr.html.markdown
+++ b/fr-fr/erlang-fr.html.markdown
@@ -28,7 +28,7 @@ lang: fr-fr
%% 1. Variables et filtrage par motif
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-(L'équivalent anglais de *filtrage par motif* est *pattern patching*.)
+(L'équivalent anglais de *filtrage par motif* est *pattern matching*.)
Nb = 42. % Chaque nom de variable doit commencer par une lettre majuscule.
@@ -64,7 +64,7 @@ Point = {point, 10, 45}.
{point, X, Y} = Point. % X = 10, Y = 45
% On peut utiliser `_` comme caractère joker pour les variables qui ne nous
-% intéressent pas. Le symbol `_` est appelé variable muette. Contrairement
+% intéressent pas. Le symbole `_` est appelé variable muette. Contrairement
% aux variables normales, de multiples apparitions de `_` dans un même motif
% ne lient pas nécessairement à la même valeur.
Personne = {personne, {nom, {prenom, joe}, {famille, armstrong}},
diff --git a/fr-fr/make-fr.html.markdown b/fr-fr/make-fr.html.markdown
index 48d24549..7b4864b5 100644
--- a/fr-fr/make-fr.html.markdown
+++ b/fr-fr/make-fr.html.markdown
@@ -1,5 +1,6 @@
---
-language: make
+category: tool
+tool: make
contributors:
- ["Robert Steed", "https://github.com/robochat"]
translators:
diff --git a/fr-fr/markdown-fr.html.markdown b/fr-fr/markdown-fr.html.markdown
index b3b7de85..26c2546a 100644
--- a/fr-fr/markdown-fr.html.markdown
+++ b/fr-fr/markdown-fr.html.markdown
@@ -350,7 +350,7 @@ ne sont pas tres agréable d'utilisation. Mais si vous en avez besoin :
```md
| Col1 | Col2 | Col3 |
| :----------- | :------: | ------------: |
-| Alignement Gauche | Centé | Alignement Droite |
+| Alignement Gauche | Centré | Alignement Droite |
| bla | bla | bla |
```
diff --git a/fr-fr/python-fr.html.markdown b/fr-fr/python-fr.html.markdown
index d78291be..0ae410de 100644
--- a/fr-fr/python-fr.html.markdown
+++ b/fr-fr/python-fr.html.markdown
@@ -444,7 +444,7 @@ Human.grunt() #=> "*grunt*"
# On peut importer des modules
import math
-print math.sqrt(16) #=> 4
+print math.sqrt(16) #=> 4.0
# Et récupérer des fonctions spécifiques d'un module
from math import ceil, floor
diff --git a/fsharp.html.markdown b/fsharp.html.markdown
index 59461eed..24044d76 100644
--- a/fsharp.html.markdown
+++ b/fsharp.html.markdown
@@ -194,7 +194,7 @@ module ListExamples =
| [] -> printfn "the list is empty"
| [first] -> printfn "the list has one element %A " first
| [first; second] -> printfn "list is %A and %A" first second
- | _ -> printfn "the list has more than two elements"
+ | first :: _ -> printfn "the list has more than two elements, first element %A" first
listMatcher [1; 2; 3; 4]
listMatcher [1; 2]
diff --git a/haxe.html.markdown b/haxe.html.markdown
index afb9d1a3..a31728e1 100644
--- a/haxe.html.markdown
+++ b/haxe.html.markdown
@@ -7,17 +7,18 @@ contributors:
---
Haxe is a web-oriented language that provides platform support for C++, C#,
-Swf/ActionScript, Javascript, Java, and Neko byte code (also written by the
-Haxe author). Note that this guide is for Haxe version 3. Some of the guide
-may be applicable to older versions, but it is recommended to use other
-references.
+Swf/ActionScript, Javascript, Java, PHP, Python, Lua, HashLink, and Neko byte code
+(the latter two being also written by the Haxe author). Note that this guide is for
+Haxe version 3. Some of the guide may be applicable to older versions, but it is
+recommended to use other references.
```csharp
/*
Welcome to Learn Haxe 3 in 15 minutes. http://www.haxe.org
This is an executable tutorial. You can compile and run it using the haxe
compiler, while in the same directory as LearnHaxe.hx:
- $> haxe -main LearnHaxe3 -x out
+
+ $ haxe -main LearnHaxe3 --interp
Look for the slash-star marks surrounding these paragraphs. We are inside
a "Multiline comment". We can leave some notes here that will get ignored
@@ -26,16 +27,14 @@ references.
Multiline comments are also used to generate javadoc-style documentation for
haxedoc. They will be used for haxedoc if they immediately precede a class,
class function, or class variable.
-
*/
-// Double slashes like this will give a single-line comment
-
+// Double slashes like this will give a single-line comment.
/*
This is your first actual haxe code coming up, it's declaring an empty
- package. A package isn't necessary, but it's useful if you want to create a
- namespace for your code (e.g. org.yourapp.ClassName).
+ package. A package isn't necessary, but it's useful if you want to create
+ a namespace for your code (e.g. org.yourapp.ClassName).
Omitting package declaration is the same as declaring an empty package.
*/
@@ -47,8 +46,9 @@ package; // empty package, no namespace.
must be lower case while module names are capitalized. A module contain one
or more types whose names are also capitalized.
- E.g, the class "org.yourapp.Foo" should have the folder structure org/module/Foo.hx,
- as accessible from the compiler's working directory or class path.
+ E.g, the class "org.yourapp.Foo" should have the folder structure
+ org/module/Foo.hx, as accessible from the compiler's working directory or
+ class path.
If you import code from other files, it must be declared before the rest of
the code. Haxe provides a lot of common default classes to get you started:
@@ -64,34 +64,27 @@ import Lambda.array;
// you can also use "*" to import all static fields
import Math.*;
-/*
- You can also import classes in a special way, enabling them to extend the
- functionality of other classes like a "mixin". More on 'using' later.
- */
+// You can also import classes in a special way, enabling them to extend the
+// functionality of other classes like a "mixin". More on 'using' later.
using StringTools;
-/*
- Typedefs are like variables... for types. They must be declared before any
- code. More on this later.
- */
+// Typedefs are like variables... for types. They must be declared before any
+// code. More on this later.
typedef FooString = String;
// Typedefs can also reference "structural" types, more on that later as well.
typedef FooObject = { foo: String };
-/*
- Here's the class definition. It's the main class for the file, since it has
- the same name (LearnHaxe3).
- */
-class LearnHaxe3{
+// Here's the class definition. It's the main class for the file, since it has
+// the same name (LearnHaxe3).
+class LearnHaxe3 {
/*
If you want certain code to run automatically, you need to put it in
a static main function, and specify the class in the compiler arguments.
In this case, we've specified the "LearnHaxe3" class in the compiler
arguments above.
*/
- static function main(){
-
+ static function main() {
/*
Trace is the default method of printing haxe expressions to the
screen. Different targets will have different methods of
@@ -103,17 +96,13 @@ class LearnHaxe3{
*/
trace("Hello World, with trace()!");
- /*
- Trace can handle any type of value or object. It will try to print
- a representation of the expression as best it can. You can also
- concatenate strings with the "+" operator:
- */
- trace( " Integer: " + 10 + " Float: " + 3.14 + " Boolean: " + true);
+ // Trace can handle any type of value or object. It will try to print
+ // a representation of the expression as best it can. You can also
+ // concatenate strings with the "+" operator:
+ trace("Integer: " + 10 + " Float: " + 3.14 + " Boolean: " + true);
- /*
- In Haxe, it's required to separate expressions in the same block with
- semicolons. But, you can put two expressions on one line:
- */
+ // In Haxe, it's required to separate expressions in the same block with
+ // semicolons. But, you can put two expressions on one line:
trace('two expressions..'); trace('one line');
@@ -122,14 +111,11 @@ class LearnHaxe3{
//////////////////////////////////////////////////////////////////
trace("***Types & Variables***");
- /*
- You can save values and references to data structures using the
- "var" keyword:
- */
+ // You can save values and references to data structures using the
+ // "var" keyword:
var an_integer:Int = 1;
trace(an_integer + " is the value for an_integer");
-
/*
Haxe is statically typed, so "an_integer" is declared to have an
"Int" type, and the rest of the expression assigns the value "1" to
@@ -150,46 +136,36 @@ class LearnHaxe3{
Haxe uses platform precision for Int and Float sizes. It also
uses the platform behavior for overflow.
(Other numeric types and behavior are possible using special
- libraries)
- */
-
- /*
+ libraries.)
+
In addition to simple values like Integers, Floats, and Booleans,
Haxe provides standard library implementations for common data
structures like strings, arrays, lists, and maps:
*/
- var a_string = "some" + 'string'; // strings can have double or single quotes
+ // Strings can have double or single quotes.
+ var a_string = "some" + 'string';
trace(a_string + " is the value for a_string");
- /*
- Strings can be "interpolated" by inserting variables into specific
- positions. The string must be single quoted, and the variable must
- be preceded with "$". Expressions can be enclosed in ${...}.
- */
+ // Strings can be "interpolated" by inserting variables into specific
+ // positions. The string must be single quoted, and the variable must
+ // be preceded with "$". Expressions can be enclosed in ${...}.
var x = 1;
var an_interpolated_string = 'the value of x is $x';
var another_interpolated_string = 'the value of x + 1 is ${x + 1}';
- /*
- Strings are immutable, instance methods will return a copy of
- parts or all of the string.
- (See also the StringBuf class).
- */
+ // Strings are immutable, instance methods will return a copy of
+ // parts or all of the string. (See also the StringBuf class).
var a_sub_string = a_string.substr(0,4);
trace(a_sub_string + " is the value for a_sub_string");
- /*
- Regexes are also supported, but there's not enough space to go into
- much detail.
- */
+ // Regexes are also supported, but there's not enough space here to go
+ // into much detail.
var re = ~/foobar/;
trace(re.match('foo') + " is the value for (~/foobar/.match('foo')))");
- /*
- Arrays are zero-indexed, dynamic, and mutable. Missing values are
- defined as null.
- */
+ // Arrays are zero-indexed, dynamic, and mutable. Missing values are
+ // defined as null.
var a = new Array<String>(); // an array that contains Strings
a[0] = 'foo';
trace(a.length + " is the value for a.length");
@@ -197,20 +173,17 @@ class LearnHaxe3{
trace(a.length + " is the value for a.length (after modification)");
trace(a[3] + " is the value for a[3]"); //null
- /*
- Arrays are *generic*, so you can indicate which values they contain
- with a type parameter:
- */
+ // Arrays are *generic*, so you can indicate which values they contain
+ // with a type parameter:
var a2 = new Array<Int>(); // an array of Ints
var a3 = new Array<Array<String>>(); // an Array of Arrays (of Strings).
- /*
- Maps are simple key/value data structures. The key and the value
- can be of any type.
- */
- var m = new Map<String, Int>(); // The keys are strings, the values are Ints.
+ // Maps are simple key/value data structures. The key and the value
+ // can be of any type.
+ // Here, the keys are strings, and the values are Ints:
+ var m = new Map<String, Int>();
m.set('foo', 4);
- // You can also use array notation;
+ // You can also use array notation:
m['bar'] = 5;
trace(m.exists('bar') + " is the value for m.exists('bar')");
trace(m.get('bar') + " is the value for m.get('bar')");
@@ -219,19 +192,15 @@ class LearnHaxe3{
var m2 = ['foo' => 4, 'baz' => 6]; // Alternative map syntax
trace(m2 + " is the value for m2");
- /*
- Remember, you can use type inference. The Haxe compiler will
- decide the type of the variable the first time you pass an
- argument that sets a type parameter.
- */
+ // Remember, you can use type inference. The Haxe compiler will
+ // decide the type of the variable the first time you pass an
+ // argument that sets a type parameter.
var m3 = new Map();
m3.set(6, 'baz'); // m3 is now a Map<Int,String>
trace(m3 + " is the value for m3");
- /*
- Haxe has some more common datastructures in the haxe.ds module, such as
- List, Stack, and BalancedTree
- */
+ // Haxe has some more common datastructures in the haxe.ds module, such
+ // as List, Stack, and BalancedTree.
//////////////////////////////////////////////////////////////////
@@ -243,11 +212,11 @@ class LearnHaxe3{
trace((4 + 3) + " is the value for (4 + 3)");
trace((5 - 1) + " is the value for (5 - 1)");
trace((2 * 4) + " is the value for (2 * 4)");
- trace((8 / 3) + " is the value for (8 / 3) (division always produces Floats)");
+ // Division always produces Floats.
+ trace((8 / 3) + " is the value for (8 / 3) (a Float)");
trace((12 % 4) + " is the value for (12 % 4)");
-
- //basic comparison
+ // basic comparison
trace((3 == 2) + " is the value for 3 == 2");
trace((3 != 2) + " is the value for 3 != 2");
trace((3 > 2) + " is the value for 3 > 2");
@@ -257,22 +226,23 @@ class LearnHaxe3{
// standard bitwise operators
/*
- ~ Unary bitwise complement
- << Signed left shift
- >> Signed right shift
- >>> Unsigned right shift
- & Bitwise AND
- ^ Bitwise exclusive OR
- | Bitwise inclusive OR
+ ~ Unary bitwise complement
+ << Signed left shift
+ >> Signed right shift
+ >>> Unsigned right shift
+ & Bitwise AND
+ ^ Bitwise exclusive OR
+ | Bitwise inclusive OR
*/
- //increments
+ // increments
var i = 0;
trace("Increments and decrements");
- trace(i++); //i = 1. Post-Incrementation
- trace(++i); //i = 2. Pre-Incrementation
- trace(i--); //i = 1. Post-Decrementation
- trace(--i); //i = 0. Pre-Decrementation
+ trace(i++); // i = 1. Post-Increment
+ trace(++i); // i = 2. Pre-Increment
+ trace(i--); // i = 1. Post-Decrement
+ trace(--i); // i = 0. Pre-Decrement
+
//////////////////////////////////////////////////////////////////
// Control Structures
@@ -281,21 +251,19 @@ class LearnHaxe3{
// if statements
var j = 10;
- if (j == 10){
+ if (j == 10) {
trace("this is printed");
- } else if (j > 10){
+ } else if (j > 10) {
trace("not greater than 10, so not printed");
} else {
trace("also not printed.");
}
// there is also a "ternary" if:
- (j == 10) ? trace("equals 10") : trace("not equals 10");
+ (j == 10) ? trace("equals 10") : trace("not equals 10");
- /*
- Finally, there is another form of control structures that operates
- at compile time: conditional compilation.
- */
+ // Finally, there is another form of control structure that operates
+ // at compile time: conditional compilation.
#if neko
trace('hello from neko');
#elseif js
@@ -303,43 +271,40 @@ class LearnHaxe3{
#else
trace('hello from another platform!');
#end
- /*
- The compiled code will change depending on the platform target.
- Since we're compiling for neko (-x or -neko), we only get the neko
- greeting.
- */
+
+ // The compiled code will change depending on the platform target.
+ // Since we're compiling for neko (-x or -neko), we only get the neko
+ // greeting.
trace("Looping and Iteration");
// while loop
var k = 0;
- while(k < 100){
+ while (k < 100) {
// trace(counter); // will print out numbers 0-99
k++;
}
// do-while loop
var l = 0;
- do{
+ do {
trace("do statement always runs at least once");
} while (l > 0);
// for loop
- /*
- There is no c-style for loop in Haxe, because they are prone
- to error, and not necessary. Instead, Haxe has a much simpler
- and safer version that uses Iterators (more on those later).
- */
- var m = [1,2,3];
- for (val in m){
+ // There is no c-style for loop in Haxe, because they are prone
+ // to error, and not necessary. Instead, Haxe has a much simpler
+ // and safer version that uses Iterators (more on those later).
+ var m = [1, 2, 3];
+ for (val in m) {
trace(val + " is the value for val in the m array");
}
// Note that you can iterate on an index using a range
// (more on ranges later as well)
var n = ['foo', 'bar', 'baz'];
- for (val in 0...n.length){
+ for (val in 0...n.length) {
trace(val + " is the value for val (an index for n)");
}
@@ -354,8 +319,11 @@ class LearnHaxe3{
var modified_n = [for (val in n) val += '!'];
trace(modified_n + " is the value for modified_n");
- var filtered_and_modified_n = [for (val in n) if (val != "foo") val += "!"];
- trace(filtered_and_modified_n + " is the value for filtered_and_modified_n");
+ var filtered_and_modified_n
+ = [for (val in n) if (val != "foo") val += "!"];
+ trace(filtered_and_modified_n
+ + " is the value for filtered_and_modified_n");
+
//////////////////////////////////////////////////////////////////
// Switch Statements (Value Type)
@@ -366,33 +334,32 @@ class LearnHaxe3{
Switch statements in Haxe are very powerful. In addition to working
on basic values like strings and ints, they can also work on the
generalized algebraic data types in enums (more on enums later).
- Here's some basic value examples for now:
+ Here are some basic value examples for now:
*/
var my_dog_name = "fido";
var favorite_thing = "";
- switch(my_dog_name){
+ switch(my_dog_name) {
case "fido" : favorite_thing = "bone";
case "rex" : favorite_thing = "shoe";
case "spot" : favorite_thing = "tennis ball";
default : favorite_thing = "some unknown treat";
- // case _ : favorite_thing = "some unknown treat"; // same as default
+ // same as default:
+ // case _ : favorite_thing = "some unknown treat";
}
- // The "_" case above is a "wildcard" value
- // that will match anything.
+ // The "_" case above is a "wildcard" value that will match anything.
trace("My dog's name is " + my_dog_name
+ ", and his favorite thing is a: "
+ favorite_thing);
+
//////////////////////////////////////////////////////////////////
// Expression Statements
//////////////////////////////////////////////////////////////////
trace("***EXPRESSION STATEMENTS***");
- /*
- Haxe control statements are very powerful because every statement
- is also an expression, consider:
- */
+ // Haxe control statements are very powerful because every statement
+ // is also an expression, consider:
// if statements
var k = if (true) 10 else 20;
@@ -410,6 +377,7 @@ class LearnHaxe3{
+ ", and his other favorite thing is a: "
+ other_favorite_thing);
+
//////////////////////////////////////////////////////////////////
// Converting Value Types
//////////////////////////////////////////////////////////////////
@@ -418,14 +386,14 @@ class LearnHaxe3{
// You can convert strings to ints fairly easily.
// string to integer
- Std.parseInt("0"); // returns 0
- Std.parseFloat("0.4"); // returns 0.4;
+ Std.parseInt("0"); // returns 0
+ Std.parseFloat("0.4"); // returns 0.4
// integer to string
- Std.string(0); // returns "0";
+ Std.string(0); // returns "0"
// concatenation with strings will auto-convert to string.
- 0 + ""; // returns "0";
- true + ""; // returns "true";
+ 0 + ""; // returns "0"
+ true + ""; // returns "true"
// See documentation for parsing in Std for more details.
@@ -434,14 +402,13 @@ class LearnHaxe3{
//////////////////////////////////////////////////////////////////
/*
-
As mentioned before, Haxe is a statically typed language. All in
all, static typing is a wonderful thing. It enables
precise autocompletions, and can be used to thoroughly check the
correctness of a program. Plus, the Haxe compiler is super fast.
- *HOWEVER*, there are times when you just wish the compiler would let
- something slide, and not throw a type error in a given case.
+ *HOWEVER*, there are times when you just wish the compiler would
+ let something slide, and not throw a type error in a given case.
To do this, Haxe has two separate keywords. The first is the
"Dynamic" type:
@@ -456,11 +423,10 @@ class LearnHaxe3{
The other more extreme option is the "untyped" keyword:
*/
-
- untyped {
- var x:Int = 'foo'; // this can't be right!
- var y:String = 4; // madness!
- }
+ untyped {
+ var x:Int = 'foo'; // This can't be right!
+ var y:String = 4; // Madness!
+ }
/*
The untyped keyword operates on entire *blocks* of code, skipping
@@ -474,74 +440,66 @@ class LearnHaxe3{
of the type models work should you resort to "Dynamic" or "untyped".
*/
+
//////////////////////////////////////////////////////////////////
// Basic Object Oriented Programming
//////////////////////////////////////////////////////////////////
trace("***BASIC OBJECT ORIENTED PROGRAMMING***");
-
- /*
- Create an instance of FooClass. The classes for this are at the
- end of the file.
- */
+ // Create an instance of FooClass. The classes for this are at the
+ // end of the file.
var foo_instance = new FooClass(3);
// read the public variable normally
- trace(foo_instance.public_any + " is the value for foo_instance.public_any");
+ trace(foo_instance.public_any
+ + " is the value for foo_instance.public_any");
// we can read this variable
- trace(foo_instance.public_read + " is the value for foo_instance.public_read");
- // but not write it
- // foo_instance.public_read = 4; // this will throw an error if uncommented:
+ trace(foo_instance.public_read
+ + " is the value for foo_instance.public_read");
+ // but not write it; this will throw an error if uncommented:
+ // foo_instance.public_read = 4;
// trace(foo_instance.public_write); // as will this.
- // calls the toString method:
+ // Calls the toString method:
trace(foo_instance + " is the value for foo_instance");
// same thing:
- trace(foo_instance.toString() + " is the value for foo_instance.toString()");
-
+ trace(foo_instance.toString()
+ + " is the value for foo_instance.toString()");
- /*
- The foo_instance has the "FooClass" type, while acceptBarInstance
- has the BarClass type. However, since FooClass extends BarClass, it
- is accepted.
- */
+ // The foo_instance has the "FooClass" type, while acceptBarInstance
+ // has the BarClass type. However, since FooClass extends BarClass, it
+ // is accepted.
BarClass.acceptBarInstance(foo_instance);
- /*
- The classes below have some more advanced examples, the "example()"
- method will just run them here.
- */
+ // The classes below have some more advanced examples, the "example()"
+ // method will just run them here.
SimpleEnumTest.example();
ComplexEnumTest.example();
TypedefsAndStructuralTypes.example();
UsingExample.example();
-
}
-
}
-/*
- This is the "child class" of the main LearnHaxe3 Class
- */
-class FooClass extends BarClass implements BarInterface{
+// This is the "child class" of the main LearnHaxe3 Class.
+class FooClass extends BarClass implements BarInterface {
public var public_any:Int; // public variables are accessible anywhere
public var public_read (default, null): Int; // enable only public read
public var public_write (null, default): Int; // or only public write
- public var property (get, set): Int; // use this style to enable getters/setters
+ // Use this style to enable getters/setters:
+ public var property (get, set): Int;
// private variables are not available outside the class.
// see @:allow for ways around this.
var _private:Int; // variables are private if they are not marked public
// a public constructor
- public function new(arg:Int){
+ public function new(arg:Int) {
// call the constructor of the parent object, since we extended BarClass:
super();
this.public_any = 0;
this._private = arg;
-
}
// getter for _private
@@ -555,47 +513,40 @@ class FooClass extends BarClass implements BarInterface{
return val;
}
- // special function that is called whenever an instance is cast to a string.
- public function toString(){
+ // Special function that is called whenever an instance is cast to a string.
+ public function toString() {
return _private + " with toString() method!";
}
// this class needs to have this function defined, since it implements
// the BarInterface interface.
- public function baseFunction(x: Int) : String{
+ public function baseFunction(x: Int) : String {
// convert the int to string automatically
return x + " was passed into baseFunction!";
}
}
-/*
- A simple class to extend
-*/
+// A simple class to extend.
class BarClass {
var base_variable:Int;
- public function new(){
+ public function new() {
base_variable = 4;
}
- public static function acceptBarInstance(b:BarClass){
- }
+ public static function acceptBarInstance(b:BarClass) {}
}
-/*
- A simple interface to implement
-*/
-interface BarInterface{
+// A simple interface to implement
+interface BarInterface {
public function baseFunction(x:Int):String;
}
+
//////////////////////////////////////////////////////////////////
// Enums and Switch Statements
//////////////////////////////////////////////////////////////////
-/*
- Enums in Haxe are very powerful. In their simplest form, enums
- are a type with a limited number of states:
- */
-
+// Enums in Haxe are very powerful. In their simplest form, enums
+// are a type with a limited number of states:
enum SimpleEnum {
Foo;
Bar;
@@ -603,12 +554,12 @@ enum SimpleEnum {
}
// Here's a class that uses it:
-
-class SimpleEnumTest{
- public static function example(){
- var e_explicit:SimpleEnum = SimpleEnum.Foo; // you can specify the "full" name
+class SimpleEnumTest {
+ public static function example() {
+ // You can specify the "full" name,
+ var e_explicit:SimpleEnum = SimpleEnum.Foo;
var e = Foo; // but inference will work as well.
- switch(e){
+ switch(e) {
case Foo: trace("e was Foo");
case Bar: trace("e was Bar");
case Baz: trace("e was Baz"); // comment this line to throw an error.
@@ -621,18 +572,16 @@ class SimpleEnumTest{
You can also specify a default for enum switches as well:
*/
- switch(e){
+ switch(e) {
case Foo: trace("e was Foo again");
default : trace("default works here too");
}
}
}
-/*
- Enums go much further than simple states, we can also enumerate
- *constructors*, but we'll need a more complex enum example
- */
-enum ComplexEnum{
+// Enums go much further than simple states, we can also enumerate
+// *constructors*, but we'll need a more complex enum example.
+enum ComplexEnum {
IntEnum(i:Int);
MultiEnum(i:Int, j:String, k:Float);
SimpleEnumEnum(s:SimpleEnum);
@@ -641,14 +590,12 @@ enum ComplexEnum{
// Note: The enum above can include *other* enums as well, including itself!
// Note: This is what's called *Algebraic data type* in some other languages.
-class ComplexEnumTest{
- public static function example(){
+class ComplexEnumTest {
+ public static function example() {
var e1:ComplexEnum = IntEnum(4); // specifying the enum parameter
- /*
- Now we can switch on the enum, as well as extract any parameters
- it might of had.
- */
- switch(e1){
+ // Now we can switch on the enum, as well as extract any parameters
+ // it might have had.
+ switch(e1) {
case IntEnum(x) : trace('$x was the parameter passed to e1');
default: trace("Shouldn't be printed");
}
@@ -662,34 +609,28 @@ class ComplexEnumTest{
// enums all the way down
var e3 = ComplexEnumEnum(ComplexEnumEnum(MultiEnum(4, 'hi', 4.3)));
- switch(e3){
- // You can look for certain nested enums by specifying them explicitly:
+ switch(e3) {
+ // You can look for certain nested enums by specifying them
+ // explicitly:
case ComplexEnumEnum(ComplexEnumEnum(MultiEnum(i,j,k))) : {
trace('$i, $j, and $k were passed into this nested monster');
}
default: trace("Shouldn't be printed");
}
- /*
- Check out "generalized algebraic data types" (GADT) for more details
- on why these are so great.
- */
+ // Check out "generalized algebraic data types" (GADT) for more details
+ // on why these are so great.
}
}
class TypedefsAndStructuralTypes {
- public static function example(){
- /*
- Here we're going to use typedef types, instead of base types.
- At the top we've declared the type "FooString" to mean a "String" type.
- */
+ public static function example() {
+ // Here we're going to use typedef types, instead of base types.
+ // At the top we've declared the type "FooString" to mean a "String" type.
var t1:FooString = "some string";
- /*
- We can use typedefs for "structural types" as well. These types are
- defined by their field structure, not by class inheritance. Here's
- an anonymous object with a String field named "foo":
- */
-
+ // We can use typedefs for "structural types" as well. These types are
+ // defined by their field structure, not by class inheritance. Here's
+ // an anonymous object with a String field named "foo":
var anon_obj = { foo: 'hi' };
/*
@@ -699,8 +640,7 @@ class TypedefsAndStructuralTypes {
that structure, we can use it anywhere that a "FooObject" type is
expected.
*/
-
- var f = function(fo:FooObject){
+ var f = function(fo:FooObject) {
trace('$fo was passed in to this function');
}
f(anon_obj); // call the FooObject signature function with anon_obj.
@@ -712,9 +652,7 @@ class TypedefsAndStructuralTypes {
?optionalString: String,
requiredInt: Int
}
- */
- /*
Typedefs work well with conditional compilation. For instance,
we could have included this at the top of the file:
@@ -728,15 +666,14 @@ class TypedefsAndStructuralTypes {
typedef Surface = java.awt.geom.GeneralPath;
#end
- That would give us a single "Surface" type to work with across
- all of those platforms.
+ That would give us a single "Surface" type to work with across
+ all of those platforms.
*/
}
}
class UsingExample {
public static function example() {
-
/*
The "using" import keyword is a special type of class import that
alters the behavior of any static methods in the class.
diff --git a/html.html.markdown b/html.html.markdown
index 4d225aca..b8212776 100644
--- a/html.html.markdown
+++ b/html.html.markdown
@@ -5,6 +5,7 @@ contributors:
- ["Christophe THOMAS", "https://github.com/WinChris"]
translators:
- ["Robert Steed", "https://github.com/robochat"]
+ - ["Dimitri Kokkonis", "https://github.com/kokkonisd"]
---
HTML stands for HyperText Markup Language.
@@ -167,7 +168,7 @@ useful tips.
HTML is written in files ending with `.html` or `.htm`. The mime type is
`text/html`.
-
+**HTML is NOT a programming language**
## To Learn More
* [wikipedia](https://en.wikipedia.org/wiki/HTML)
diff --git a/hu-hu/python-hu.html.markdown b/hu-hu/python-hu.html.markdown
index 9b55f8e2..01f1c414 100644
--- a/hu-hu/python-hu.html.markdown
+++ b/hu-hu/python-hu.html.markdown
@@ -656,7 +656,7 @@ i.age # => AttributeError hibát dob
# Modulokat így lehet importálni
import math
-print math.sqrt(16) # => 4
+print math.sqrt(16) # => 4.0
# Lehetséges csak bizonyos függvényeket importálni egy modulból
from math import ceil, floor
diff --git a/it-it/javascript-it.html.markdown b/it-it/javascript-it.html.markdown
new file mode 100644
index 00000000..68bf6287
--- /dev/null
+++ b/it-it/javascript-it.html.markdown
@@ -0,0 +1,617 @@
+---
+language: javascript
+contributors:
+ - ["Adam Brenecki", "http://adam.brenecki.id.au"]
+ - ["Ariel Krakowski", "http://www.learneroo.com"]
+translators:
+ - ["vinniec", "https://github.com/vinniec"]
+filename: javascript-it.js
+lang: it-it
+---
+
+JavaScript è stato creato da Netscape di Brendan Eich nel 1995. È stato originariamente pensato come un semplice linguaggio di scripting per i siti web, complementare all'uso di java per applicazioni più complesse ma la sua stretta integrazione con le pagine Web e il supporto integrato con esse ha causato il suo divenire più comune di Java per i frontend web.
+
+Tuttavia JavaScript non è semplicemente limitato ai web browser: Node.js è un progetto che fornisce una runtime standalone dell'engine JavaScript V8 per Google Chrome, sta diventando sempre più popolare.
+
+JavaScript ha una sintassi C-like, quindi se usate linguaggi come C o Java, molta della sintassi di base sarà già familiare. A dispetto di questo, e a dispetto del nome similare, il modello a oggetti di JavaScript è significativamente diverso da quello di Java.
+
+```js
+// I commenti a singola linea iniziano con due slash.
+/* I commenti multilinea cominciano con uno slash e un asterisco,
+ e terminano con un asterisco e uno slash */
+
+// Le istruzioni possono essere terminate con ;
+doStuff();
+
+// ... ma non devono esserci per forza, i punti e virgola vengono automaticamente inseriti
+// dove c'è un newline, ad eccezione di alcuni casi.
+doStuff()
+
+// Poiché questi casi possono causare risultati inaspettati, noi continueremo ad usare
+// i punti e virgola in questa guida.
+
+///////////////////////////////////
+// 1. Numeri, Stringe e Operatori
+
+// JavaScript ha un tipo numero (che è a 64-bit IEEE 754 double).
+// Double ha una mantissa di 52-bit che è abbastanza per memorizzare interi
+// fino a 9x10¹⁵ per essere precisi.
+3; // = 3
+1.5; // = 1.5
+
+// Alcuni lavori aritmetici di base come ci si può aspettare.
+1 + 1; // = 2
+0.1 + 0.2; // = 0.30000000000000004
+8 - 1; // = 7
+10 * 2; // = 20
+35 / 5; // = 7
+
+// inclusa la divisione con la virgola.
+5 / 2; // = 2.5
+
+// E il modulo.
+10 % 2; // = 0
+30 % 4; // = 2
+18.5 % 7; // = 4.5
+
+// Anche le operazioni binarie funzionano; quando effettuate una operazione binaria il vostro numero decimale
+// è convertito in un intero con segno *fino a* 32 bit..
+1 << 2; // = 4
+
+// Le precedenza è subordinata dalle parentesi.
+(1 + 3) * 2; // = 8
+
+// Ci sono tre valori speciali che non sono numeri reali:
+Infinity; // ad esempio il risultato di 1/0
+-Infinity; // ad esempio il risultato di -1/0
+NaN; // ad esempio il risultato di 0/0, sta per 'Not a Number'
+
+// Ci sono anche i tipi booleani.
+true;
+false;
+
+// Le stringe sono create con ' oppure ".
+'abc';
+"Hello, world";
+
+// La negazione usa il ! simbolo
+!true; // = false
+!false; // = true
+
+// L'uguaglianza è ===
+1 === 1; // = true
+2 === 1; // = false
+
+// L'inuguaglianza è !==
+1 !== 1; // = false
+2 !== 1; // = true
+
+// Altre comparazioni
+1 < 10; // = true
+1 > 10; // = false
+2 <= 2; // = true
+2 >= 2; // = true
+
+// Le stringhe si concatenano con il +
+"Hello " + "world!"; // = "Hello world!"
+
+// ... che funziona con qualcosa in più delle semplici stringhe
+"1, 2, " + 3; // = "1, 2, 3"
+"Hello " + ["world", "!"]; // = "Hello world,!"
+
+// e sono comparate con < e >
+"a" < "b"; // = true
+
+// La comparazione con conversione implicita si fa con il doppio uguale...
+"5" == 5; // = true
+null == undefined; // = true
+
+// ...ammenoché non si usi ===
+"5" === 5; // = false
+null === undefined; // = false
+
+// ...che può provocare strani comportamenti...
+13 + !0; // 14
+"13" + !0; // '13true'
+
+// Si può accedere ai caratteri di una stringa con `charAt`
+"This is a string".charAt(0); // = 'T'
+
+// ...o usando le `substring` per ottenere una parte.
+"Hello world".substring(0, 5); // = "Hello"
+
+// `length` è una proprietà, quindi non usate le ().
+"Hello".length; // = 5
+
+// Ci sono anche `null` e `undefined`.
+null; // usato per indicato deliberatamente un non-valore
+undefined; // usato per indicare un valore che attualmente non è presente (sebbene
+ // `undefined` sia un valore a sua stessa volta)
+
+// false, null, undefined, NaN, 0 e "" sono falsi; tutto il resto è vero.
+// Notare che 0 è falso e "0" è vero, nonostante 0 == "0".
+
+///////////////////////////////////
+// 2. Variabili, Array e Oggetti
+
+// Le variabili sono dichiarate con la parola chiave `var`. JavaScript è tipato
+// dinamicamente, quindi non serve specificare il tipo. L'assegnamento usa un carattere `=`
+// singolo.
+var someVar = 5;
+
+// Se si toglie la parola chiave var non si otterrà un errore...
+someOtherVar = 10;
+
+// ...ma la tua variabile sarà creata con visibilità globale e non
+// nel blocco dove la si è definita.
+
+// Le variabili dichiarate senza essere definite vengono impostate come undefined.
+var someThirdVar; // = undefined
+
+// Se si vuole dichiarare una coppia di variabili, lo si può fare usando una virgola
+// come separatore
+var someFourthVar = 2, someFifthVar = 4;
+
+// C'è una scorciatoia per effettuare operazioni matematiche sulle variabili:
+someVar += 5; // equivalente di someVar = someVar + 5; someVar vale 10 ora
+someVar *= 10; // ora someVar è 100
+
+// e un ulteriore scorciatoia per aggiungere o sottrarre 1
+someVar++; // ora someVar è 101
+someVar--; // di nuovo 100
+
+// Gli array sono liste ordinati di valori, di qualsiasi tipo.
+var myArray = ["Hello", 45, true];
+
+// Si può accedere ai loro membri usando la sintassi sottoscritta con le parentesi quadra.
+// Gli indici degli array iniziano a zero.
+myArray[1]; // = 45
+
+// Gli Array sono mutabili e di dimensione variabile.
+myArray.push("World");
+myArray.length; // = 4
+
+// Aggiungere/Modificare in un indice preciso
+myArray[3] = "Hello";
+
+// Aggiungere e rimovere un elemento dall'inizio o dalla fine di un array
+myArray.unshift(3); // Aggiungere come primo elemento
+someVar = myArray.shift(); // Rimuovere il primo elemento e restituirlo
+myArray.push(3); // Aggiungere come ultimo elemento
+someVar = myArray.pop(); // Rimuovere l'ultimo elemento e restituirlo
+
+// Unire tutti gli elementi di un array con un punto e virgola
+var myArray0 = [32,false,"js",12,56,90];
+myArray0.join(";") // = "32;false;js;12;56;90"
+
+// Ottenere un subarray di elementi dall'indice 1 (incluso) al 4 (escluso)
+myArray0.slice(1,4); // = [false,"js",12]
+
+// Rimuovere 4 elementi partendo dall'indice 2 e inserirci delle stringhe
+// "hi","wr" e "ld"; restituiscono i subarray rimossi
+myArray0.splice(2,4,"hi","wr","ld"); // = ["js",12,56,90]
+// myArray0 === [32,false,"hi","wr","ld"]
+
+// Gli oggetti di JavaScript sono equivalenti ai "dizionari" o "mappe" in altri
+// linguaggi: una collezione non ordinata di coppie di chiave-valore.
+var myObj = {key1: "Hello", key2: "World"};
+
+// Le chiavi sono stringhe, ma non è necessario quotarle se sono identificatori
+// JavaScript validi. I valori possono essere di ogni tipo.
+var myObj = {myKey: "myValue", "my other key": 4};
+
+// Gli attributi degli oggetti possono essere acceduti usando la sintassi "subscript",
+myObj["my other key"]; // = 4
+
+// ... o usando la notazione puntata fornendo una chiave che sia un identificatore valido.
+myObj.myKey; // = "myValue"
+
+// Gli oggetti sono mutabilil; i valori possono essere cambiati e nuove chiavi possono essere aggiunte.
+myObj.myThirdKey = true;
+
+// se si prova ad accedere ad un valore che non è stato ancora impostato, si otterrà undefined.
+myObj.myFourthKey; // = undefined
+
+///////////////////////////////////
+// 3. Strutture logiche e di controllo.
+
+// La struttura `if` funziona come ci si aspetta.
+var count = 1;
+if (count == 3){
+ // eseguito se count vale 3
+} else if (count == 4){
+ // eseguito se count vale 4
+} else {
+ // eseguito se count non è né 3 e né 4
+}
+
+// Così come il `while`.
+while (true){
+ // Un ciclo infinito!
+}
+
+// I cicli do-while sono come i cicli while ad eccezione che loro iterano almeno una volta.
+var input;
+do {
+ input = getInput();
+} while (!isValid(input));
+
+// Il ciclo `for` è lo stesso di C e di Java:
+// inizializzazione, condizione di proseguimento; iterazione.
+for (var i = 0; i < 5; i++){
+ // verrà eseguito 5 volte
+}
+
+// Uscire forzatamente da un un ciclo etichettato è simile a java:
+outer:
+for (var i = 0; i < 10; i++) {
+ for (var j = 0; j < 10; j++) {
+ if (i == 5 && j ==5) {
+ break outer;
+ // esce fuori dal ciclo outer invece che solo da quello più interno
+ }
+ }
+}
+
+// L'istruzione for/in permette l'iterazione sulle proprietà di un oggetto.
+var description = "";
+var person = {fname:"Paul", lname:"Ken", age:18};
+for (var x in person){
+ description += person[x] + " ";
+} // description = 'Paul Ken 18 '
+
+// L'istruzione for/of permette l'iterazione su oggetti iterabili (inclusi i built-in String,
+// Array, es. gli argomenti Array-like o gli oggetti NodeList, TypedArray, Map e Set,
+// e gli iterabili decisi dall'utente).
+var myPets = "";
+var pets = ["cat", "dog", "hamster", "hedgehog"];
+for (var pet of pets){
+ myPets += pet + " ";
+} // myPets = 'cat dog hamster hedgehog '
+
+// && è la congiunzione logica, || è la disgiunione logica
+if (house.size == "big" && house.colour == "blue"){
+ house.contains = "bear";
+}
+if (colour == "red" || colour == "blue"){
+ // i colori sono sia rossi che blu
+}
+
+// && e || "short circuit", utili per impostare i valori di default.
+var name = otherName || "default";
+
+// L'istruzione `switch` controlla l'uguaglianza con `===`.
+// Usare 'break' dopo ogni caso
+// oppure i casi dopo quello corretto verranno eseguiti comunque.
+grade = 'B';
+switch (grade) {
+ case 'A':
+ console.log("Great job");
+ break;
+ case 'B':
+ console.log("OK job");
+ break;
+ case 'C':
+ console.log("You can do better");
+ break;
+ default:
+ console.log("Oy vey");
+ break;
+}
+
+
+///////////////////////////////////
+// 4. Funzioni, Visibilità e Closure
+
+// Le funzioni di JavaScript sono dichiarate con la parolachiave `function`.
+function myFunction(thing){
+ return thing.toUpperCase();
+}
+myFunction("foo"); // = "FOO"
+
+// Nota che il valore da restituire deve iniziare nella stessa riga della
+// keyword `return`, altrimenti verrà sempre restituito `undefined` per via due to
+// dell'inserimento automatico dei punti e virgola. Fare attenzione a questo quando si usa lo stile Allman.
+function myFunction(){
+ return // <- punto e virgola automaticamente inserito qui
+ {thisIsAn: 'object literal'};
+}
+myFunction(); // = undefined
+
+// Le funzioni di JavaScript sono oggetti di prima classe, quindi possono essere riassegnate
+// a diversi nomi di variabili e passate ad altre funzioni come argomenti - per esempio,
+// mentre si fornisce un gestore di eventi:
+function myFunction(){
+ // questo codice sarà chiamato in 5 secondi
+}
+setTimeout(myFunction, 5000);
+// Nota: setTimeout non è parte del linguaggio JS, ma è fornito dai browser
+// e da Node.js.
+
+// Un altra funzione fornita dai browser è setInterval
+function myFunction(){
+ // questo codice verrà chiamato ogni 5 secondi
+}
+setInterval(myFunction, 5000);
+
+// Gli oggetti funzione non devono essere dichiarati con un nome - potete scrivere
+// la definizione di una funzione anonima direttamente come argomento di un'altra.
+setTimeout(function(){
+ // questo codice sarà chiamato in 5 secondi
+}, 5000);
+
+// In JavaScript le funzioni hanno una propria visibilità; le funzioni hanno
+// il loro scope ma gli altri blocchi no.
+if (true){
+ var i = 5;
+}
+i; // = 5 - non è undefined come ci si potrebbe aspettare in un linguaggio con una propria visibilità per blocco
+
+// Questo ha portato ad un pattern comune di "esecuzione immediata di funzioni
+// anonime", che previene alle variabili temporanee di finire nella
+// visibilità globale.
+(function(){
+ var temporary = 5;
+ // Noi possiamo accedere alla visibilità globale assegnando all' "oggetto globale", che
+ // in un browser web è sempre `windows`. L'oggetto globale potrebbe avere
+ // nomi differenti in ambienti diverso dal browser come Node.js.
+ window.permanent = 10;
+})();
+temporary; // solleva ReferenceError
+permanent; // = 10
+
+// Una delle più potenti caratteristiche di javascript sono le closure. Se una funzione è
+// definita dentro un'altra funzione, la funzione interna ha accesso a le variabili
+// della funzione esterna, anche dopo essere uscita dalla funzione esterna.
+function sayHelloInFiveSeconds(name){
+ var prompt = "Hello, " + name + "!";
+ // Le funzioni interne sono messe nella visibilità locale in modo predefinito, anche se vengono
+ // dichiarate con `var`.
+ function inner(){
+ alert(prompt);
+ }
+ setTimeout(inner, 5000);
+ // setTimeout è asincrono, quindi la funzione sayHelloInFiveSeconds
+ // esce immediatamente e setTimeout chiamera inner successivamente. Tuttavia,
+ // poiché inner è "chiuso prima" di sayHelloInFiveSeconds, inner ha ancora
+ // accesso alla variabile `prompt` quando viene finalmente richiamato.
+}
+sayHelloInFiveSeconds("Adam"); // aprirà un popup con "Hello, Adam!" in 5s
+
+///////////////////////////////////
+// 5. Di più sugli oggetti, costruttori e prototipi.
+
+// Gli oggetti possono contenere funzioni.
+var myObj = {
+ myFunc: function(){
+ return "Hello world!";
+ }
+};
+myObj.myFunc(); // = "Hello world!"
+
+// Quando una funzione contenuta in un oggetto viene chiamata, essa può accedere a questo oggetto
+// possono farlo usando la parola chiave `this`.
+myObj = {
+ myString: "Hello world!",
+ myFunc: function(){
+ return this.myString;
+ }
+};
+myObj.myFunc(); // = "Hello world!"
+
+// Questo ha a che fare con come la funzione è chiamata, non con dove
+// è definita. Quindi, la nostra funzione non funziona se non è chiamata
+// nel contesto dell'oggetto.
+var myFunc = myObj.myFunc;
+myFunc(); // = undefined
+
+// Al contrario, una funzione può essere assegnata ad un oggetto e poi accedere ad esso
+// attraverso `this`, anche se non è stata inserita durante la definizione.
+var myOtherFunc = function(){
+ return this.myString.toUpperCase();
+};
+myObj.myOtherFunc = myOtherFunc;
+myObj.myOtherFunc(); // = "HELLO WORLD!"
+
+// Possiamo anche specificare un contesto per una funzione da eseguire quando la invochiamo
+// usando `call` o `apply`.
+
+
+var anotherFunc = function(s){
+ return this.myString + s;
+};
+anotherFunc.call(myObj, " And Hello Moon!"); // = "Hello World! And Hello Moon!"
+
+// La funzione `apply` è quasi identica, ma prende un array come lista
+// di argomenti.
+
+anotherFunc.apply(myObj, [" And Hello Sun!"]); // = "Hello World! And Hello Sun!"
+
+// Questo è utile quanso si lavora con una funzione che accetta una sequenza di
+// argomenti e si vuole passare un array.
+
+Math.min(42, 6, 27); // = 6
+Math.min([42, 6, 27]); // = NaN (uh-oh!)
+Math.min.apply(Math, [42, 6, 27]); // = 6
+
+// Ma, `call` e `apply` sono solo temporanei. Quando vogliamo incollarli, possiamo
+// usare `bind`
+
+var boundFunc = anotherFunc.bind(myObj);
+boundFunc(" And Hello Saturn!"); // = "Hello World! And Hello Saturn!"
+
+// `bind` può essere anche usato per applicare parzialmente (curry) una funzione.
+
+var product = function(a, b){ return a * b; };
+var doubler = product.bind(this, 2);
+doubler(8); // = 16
+
+// Quando si chiama una funzione con la parola chiave `new`, un nuovo oggetto viene creato
+// e reso disponibile alla funzione attraverso la parola chiave `this`. Le funzioni progettate per essere
+// invocate in questo modo sono chiamate costruttrici.
+
+var MyConstructor = function(){
+ this.myNumber = 5;
+};
+myNewObj = new MyConstructor(); // = {myNumber: 5}
+myNewObj.myNumber; // = 5
+
+// Diversamente dalla molti degli altri linguaggi orientati agli oggetti, Javascript non ha
+// il concetto di 'istanze' create sull'impronta di una 'classe'; invece Javascript
+// combina l'instanziamento e l'ereditarietà in un singolo concetto: il 'prototipo'.
+
+// Ogni oggetto Javascript ha un 'prototipo'. Quando si cerca di accedere a una proprietà
+// su un oggetto che non la contiene, l'interprete
+// guarderà i suoi prototipi.
+
+// Alcune implementazioni di JS faranno accedere al propotipo di un oggetto con la proprietà
+// magica `__proto__`: Anche se questo è utile per spiegare i prototipi, non è
+// parte dello standard; capiremo più avanti come usare i prototipi in modo standard.
+var myObj = {
+ myString: "Hello world!"
+};
+var myPrototype = {
+ meaningOfLife: 42,
+ myFunc: function(){
+ return this.myString.toLowerCase();
+ }
+};
+
+myObj.__proto__ = myPrototype;
+myObj.meaningOfLife; // = 42
+
+// Questo funziona anche per le funzioni.
+myObj.myFunc(); // = "hello world!"
+
+// Ovviamente, se la proprietà non è nel prototipo, il prototipo
+// del prototipo viene ricercato, e così via.
+myPrototype.__proto__ = {
+ myBoolean: true
+};
+myObj.myBoolean; // = true
+
+// Non c'è nessuna copia coinvolta qui; ogni oggetto mantiene una referenza al suo
+// prototipo. Questo significa che possiamo modificare il prototipo e i nostri cambiamenti
+// si rifletteranno da ogni parte.
+myPrototype.meaningOfLife = 43;
+myObj.meaningOfLife; // = 43
+
+// L'istruzione for/in permette di iterare sulle proprietà di un oggetto,
+// risalendo la catena dei prototipi finché non trova un prototipo null.
+for (var x in myObj){
+ console.log(myObj[x]);
+}
+///stampa:
+// Hello world!
+// 43
+// [Function: myFunc]
+// true
+
+// Per considerare solamente le proprietà inserite nell'oggetto stesso
+// e non i loro prototipi, usare il check `hasOwnProperty()`.
+for (var x in myObj){
+ if (myObj.hasOwnProperty(x)){
+ console.log(myObj[x]);
+ }
+}
+///stampa:
+// Hello world!
+
+// Abbiamo menzionato che `__proto__` non è standard, e non c'è nessun modo standard per
+// cambiare il prototipo di un oggetto esistente. Tuttavia, ci sono due strade per
+// creare un nuovo oggetto con un dato prototipo.
+
+// La prima è Object.create, che è una recente aggiunta a JS, e che quindi
+// non è disponibile ancora in tutte le implementazioni.
+var myObj = Object.create(myPrototype);
+myObj.meaningOfLife; // = 43
+
+// La seconda strada, che funziona ovunque, ha a che fare con i costruttori.
+// I costruttori hanno una proprietà chiamata prototype. Questo *non* è il prototipo del
+// costruttore della stessa funzione; invece è il prototipo del nuovo oggetto
+// che gli viene conferito alla creazione con quel costruttore e la parola chiave new.
+MyConstructor.prototype = {
+ myNumber: 5,
+ getMyNumber: function(){
+ return this.myNumber;
+ }
+};
+var myNewObj2 = new MyConstructor();
+myNewObj2.getMyNumber(); // = 5
+myNewObj2.myNumber = 6;
+myNewObj2.getMyNumber(); // = 6
+
+// I tipi built-in come stringhe e numeri hanno anche costruttori che creano
+// oggetti wrapper equivalenti.
+var myNumber = 12;
+var myNumberObj = new Number(12);
+myNumber == myNumberObj; // = true
+
+// Eccezione, loro non sono esattamente equivalenti.
+typeof myNumber; // = 'number'
+typeof myNumberObj; // = 'object'
+myNumber === myNumberObj; // = false
+if (0){
+ // Questo codice non verrà eseguito perchè 0 è falso.
+}
+if (new Number(0)){
+ // Questo codice verrà eseguito poiché i numeri wrappati sono oggetti e gli oggetti
+ // sono sempre veri.
+}
+
+// Tuttavia, gli oggetti wrapper e i regolari built-in condividono un prototipo, quindi
+// si possono aggiungere funzionalità ad una stringa, per esempio.
+String.prototype.firstCharacter = function(){
+ return this.charAt(0);
+};
+"abc".firstCharacter(); // = "a"
+
+// Questa caratteristica viene spesso usata nel "polyfilling", che implementa nuovi
+// aspetti in un vecchio sottoinsieme di JavaScript, in modo che si possano
+// usare in vecchi ambienti come browser non aggiornati.
+
+// Per esempio, abbiamo menzionato che Object.create non è disponibile in tutte le
+// implementazioni, ma possiamo ancora usarlo con questo polyfill:
+if (Object.create === undefined){ // non lo sovrascrive se esiste già
+ Object.create = function(proto){
+ // crea un costruttore temporaneo con il giusto prototipo
+ var Constructor = function(){};
+ Constructor.prototype = proto;
+ // quindi lo usa per creare un nuovo, propriamente-prototipato oggetto
+ return new Constructor();
+ };
+}
+```
+
+## Approfondimenti
+
+Il [Mozilla Developer Networ][1] fornisce una documentazione eccellente su come Javascript è utilizzato nei browsers. In più è un wiki, quindi si può imparare di più aiutando gli altri condividendo la propria conoscenza.
+
+MDN's [A re-introduction to JavaScript][2] copre molti dei concetti qui trattati in maggiore dettaglio. Questa guida ha deliberatamente coperto solamente il linguaggio JavaScript; se volete sapere di più su come usare JavaScript in una pagina web, iniziate leggendo il [Document Object Model][3].
+
+[Learn Javascript by Example and with Challenges][4] è una variante di questo referenziario con integrate delle sfide.
+
+[Javascript Garden][5] è una guida approfondita di tutte le parti controintuitive del linguaggio.
+
+[JavaScript: The Definitive Guide][6] è una guida classica e referenziario.
+
+[Eloqunt Javascript][8] di Marijn Haverbeke è un ottimo libro/ebook JS con terminale annesso
+
+[Javascript: The Right Way][10] è una guida dedicata all'introduzione dei nuovi sviluppatori a JavaScript e come aiuto agli sviluppatori esperti per imparare di più sulle best practice.
+
+[Javascript:info][11] è un moderno tutorial su javascript che copre le basi (linguaggio principale e lavorazione con un browser) come anche argomenti avanzati con spiegazioni concise.
+
+
+In aggiunta ai contributori di questo articolo, alcuni contenuti sono adattati dal Louie Dinh's Python tutorial su questo sito, e da [JS Tutorial][7] sul Mozilla Developer Network.
+
+
+[1]: https://developer.mozilla.org/en-US/docs/Web/JavaScript
+[2]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/A_re-introduction_to_JavaScript
+[3]: https://developer.mozilla.org/en-US/docs/Using_the_W3C_DOM_Level_1_Core
+[4]: http://www.learneroo.com/modules/64/nodes/350
+[5]: http://bonsaiden.github.io/JavaScript-Garden/
+[6]: http://www.amazon.com/gp/product/0596805527/
+[7]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/A_re-introduction_to_JavaScript
+[8]: http://eloquentjavascript.net/
+[10]: http://jstherightway.org/
+[11]: https://javascript.info/
diff --git a/it-it/logtalk-it.html.markdown b/it-it/logtalk-it.html.markdown
index 7f1e9eeb..5cc53e6f 100644
--- a/it-it/logtalk-it.html.markdown
+++ b/it-it/logtalk-it.html.markdown
@@ -43,7 +43,7 @@ Un oggetto incapsula le dichiarazioni e le definizioni dei predicati. Gli oggett
:- end_object.
```
-# Compilazione dei file sorgenti
+# Compilazione e il caricamento dei file sorgenti
Supponendo che il codice di cui sopra per l'oggetto `list` venga salvato in un file` list.lgt`, esso può essere compilato e caricato utilizzando il predicato predefiniti `logtalk_load/1` o la sua abbreviazione `{}/1`, con il percorso del file come argomento (l'estensione può essere omessa):
@@ -52,6 +52,9 @@ Supponendo che il codice di cui sopra per l'oggetto `list` venga salvato in un f
yes
```
+In generale, le entità potrebbero avere dipendenze sulle entità definite in altri file di origine (ad esempio le entità di biblioteca). Per caricare un file e tutte le sue dipendenze, la soluzione consigliata consiste nel definire un file _loader_ che carica tutti i file necessari per un'applicazione. Un file loader è semplicemente un file di origine, in genere denominato `loader.lgt`, che effettua chiamate ai predicati built-in `logtalk_load/1-2`, di solito
+da una direttiva `initialization/1` per la portabilità e conformità agli standard. Caricatore file vengono forniti per tutte le librerie, strumenti ed esempi.
+
# Inviare un messaggio ad un oggetto
L'operatore infisso `::/2` è usato per inviare messaggi ad un oggetto. Analogamente al Prolog, è possibile fare backtracking per le soluzioni alternative:
diff --git a/it-it/pyqt-it.html.markdown b/it-it/pyqt-it.html.markdown
index 855a0c75..7238dd7b 100644
--- a/it-it/pyqt-it.html.markdown
+++ b/it-it/pyqt-it.html.markdown
@@ -1,7 +1,7 @@
---
category: tool
tool: PyQT
-filename: learnpyqt.py
+filename: learnpyqt-it.py
contributors:
- ["Nathan Hughes", "https://github.com/sirsharpest"]
translators:
diff --git a/it-it/python-it.html.markdown b/it-it/python-it.html.markdown
index e81d1676..794e7a70 100644
--- a/it-it/python-it.html.markdown
+++ b/it-it/python-it.html.markdown
@@ -640,7 +640,7 @@ i.age # => Emette un AttributeError
# Puoi importare moduli
import math
-print math.sqrt(16) # => 4
+print math.sqrt(16) # => 4.0
# Puoi ottenere specifiche funzione da un modulo
from math import ceil, floor
diff --git a/it-it/qt-it.html.markdown b/it-it/qt-it.html.markdown
index 4543818f..d7469f67 100644
--- a/it-it/qt-it.html.markdown
+++ b/it-it/qt-it.html.markdown
@@ -2,7 +2,7 @@
category: tool
tool: Qt Framework
language: c++
-filename: learnqt.cpp
+filename: learnqt-it.cpp
contributors:
- ["Aleksey Kholovchuk", "https://github.com/vortexxx192"]
translators:
diff --git a/it-it/rust-it.html.markdown b/it-it/rust-it.html.markdown
index 6b379f93..e4b7c33f 100644
--- a/it-it/rust-it.html.markdown
+++ b/it-it/rust-it.html.markdown
@@ -130,14 +130,14 @@ fn main() {
/////////////
// Strutture
- struct Point {
+ struct Punto {
x: i32,
y: i32,
}
let origine: Punto = Punto { x: 0, y: 0 };
- // Ana struct con campi senza nome, chiamata ‘tuple struct’
+ // Una struct con campi senza nome, chiamata ‘tuple struct’
struct Punto2(i32, i32);
let origine2 = Punto2(0, 0);
diff --git a/ja-jp/asciidoc.html.markdown b/ja-jp/asciidoc.html.markdown
new file mode 100644
index 00000000..7347589a
--- /dev/null
+++ b/ja-jp/asciidoc.html.markdown
@@ -0,0 +1,135 @@
+---
+language: asciidoc
+contributors:
+ - ["Ryan Mavilia", "http://unoriginality.rocks/"]
+ - ["Abel Salgado Romero", "https://twitter.com/abelsromero"]
+translators:
+ - ["Ryota Kayanuma", "https://github.com/PicoSushi"]
+filename: asciidoc-ja.md
+lang: ja-jp
+---
+
+AsciiDocはMarkdownに似たマークアップ言語で、書籍の執筆からブログを書くことまでなんでも使うことができます。2002年、Stuart RackhamによりAsciiDocは作成され、シンプルでありつつも沢山のカスタマイズを可能にしています。
+
+文書のヘッダー
+
+ヘッダーはオプションで、空行を含むことはできません。本文から1行以上の改行を開ける必要があります。
+
+タイトルのみの例
+
+```
+= 文章タイトル
+
+文書の最初の行
+```
+
+タイトルと著者
+
+```
+= 文書タイトル
+文書 太郎 <first.last@learnxinyminutes.com>
+
+文書の開始
+```
+
+複数の著者
+
+```
+= 文書タイトル
+John Doe <john@go.com>; Jane Doe<jane@yo.com>; Black Beard <beardy@pirate.com>
+
+複数の著者による文書の始まり。
+```
+
+版(著者の行を必要とします)
+
+```
+= 第一版のタイトル
+芋男 <chip@crunchy.com>
+v1.0, 2016-01-13
+
+このポテトについての文書は面白いです。
+```
+
+段落
+
+```
+段落は特別なことは不要です。
+
+空行を段落の間に入れることで、段落を分けることができます。
+
+折り返しをしたい場合、+
+を書くことで折り返せます!
+```
+
+文書の整形
+
+```
+_アンダースコアで斜体になります。_
+*アスタリスクで太字になります。*
+*_組み合わせると楽しい_*
+`バッククォートで固定幅になります。`
+`*太字の固定幅*`
+```
+
+節タイトル
+
+```
+= Level 0 (文書のヘッダーにのみ使用してください)
+
+== Level 1 <h2>
+
+=== Level 2 <h3>
+
+==== Level 3 <h4>
+
+===== Level 4 <h5>
+
+```
+
+リスト
+
+箇条書きリストを作るには、アスタリスクを使用してください。
+
+```
+* foo
+* bar
+* baz
+```
+
+番号付きリストを作るには、ピリオドを使用してください。
+
+```
+. item 1
+. item 2
+. item 3
+```
+
+リストはアスタリスクやピリオドを追加することで5段階まで入れ子にできます。
+
+```
+* foo 1
+** foo 2
+*** foo 3
+**** foo 4
+***** foo 5
+
+. foo 1
+.. foo 2
+... foo 3
+.... foo 4
+..... foo 5
+```
+
+## 補足資料
+
+AsciiDocの文書を処理するツールは2種類あります。
+
+1. [AsciiDoc](http://asciidoc.org/): オリジナルのPython実装で、Linuxで利用可能です。現在は開発されておらず、メンテナンスのみの状態です。
+2. [Asciidoctor](http://asciidoctor.org/): Rubyによる別実装で、JavaやJavascriptでも利用可能です。AsciiDocに新しい機能や出力形式を追加するため、現在活発に開発されています。
+
+以下のリンクは `AsciiDoctor` 実装関連のものです。
+
+* [Markdown - AsciiDoc syntax comparison](http://asciidoctor.org/docs/user-manual/#comparison-by-example): Common MarkdownとAsciidocの要素を並べて比較しています。
+* [Getting started](http://asciidoctor.org/docs/#get-started-with-asciidoctor): インストールから簡潔な文書を作るための簡単なガイドです。
+* [Asciidoctor User Manual](http://asciidoctor.org/docs/user-manual/): 文法のリファレンス、例、描画ツール、その他を含む完全なドキュメントです。
diff --git a/ja-jp/python3-jp.html.markdown b/ja-jp/python3-jp.html.markdown
index 3b1a0d73..b9731411 100644
--- a/ja-jp/python3-jp.html.markdown
+++ b/ja-jp/python3-jp.html.markdown
@@ -6,13 +6,16 @@ contributors:
- ["Andre Polykanine", "https://github.com/Oire"]
- ["Zachary Ferguson", "http://github.com/zfergus2"]
- ["evuez", "http://github.com/evuez"]
+ - ["Rommel Martinez", "https://ebzzry.io"]
+ - ["Roberto Fernandez Diaz", "https://github.com/robertofd1995"]
translators:
- ["kakakaya", "https://github.com/kakakaya"]
+ - ["Ryota Kayanuma", "https://github.com/PicoSushi"]
filename: learnpython3-jp.py
lang: ja-jp
---
-90年代の初め、Guido Van RossumによってPythonは作成されました。現在となっては、最も有名な言語の1つです。
+90年代の初め、Guido van RossumによってPythonは作成されました。現在となっては、最も有名な言語の1つです。
私は構文の明快さによって、Pythonと恋に落ちました。
以下は基本的に実行可能な疑似コードです。
@@ -21,12 +24,11 @@ lang: ja-jp
Note: この記事はPython 3に内容を絞っています。もし古いPython 2.7を学習したいなら、 [こちら](http://learnxinyminutes.com/docs/python/) をご確認下さい。
```python
-
# 1行のコメントは番号記号(#)から始まります。
""" 複数行の文字は、"を3つ繋げることで
書くことができます。
- また、これはコメントとしてもよく使われます。
+ また、これはドキュメントとしてもよく使われます。
"""
####################################################
@@ -44,8 +46,8 @@ Note: この記事はPython 3に内容を絞っています。もし古いPython
# 整数除算の結果は、正負に関わらず小数の切り捨てが行われます。
5 // 3 # => 1
-5.0 // 3.0 # => 1.0 # 浮動小数点でも同様に動作します。
-5 // 3 # => -2
+5.0 // 3.0 # => 1.0 # 浮動小数点でも同様に動作します。
-5.0 // 3.0 # => -2.0
# 除算の結果は常に浮動小数点になります。
@@ -55,7 +57,7 @@ Note: この記事はPython 3に内容を絞っています。もし古いPython
7 % 3 # => 1
# 冪乗 (x**y, x の y 乗)
-2**4 # => 16
+2**3 # => 8
# 括弧により、計算の順番を優先させられます。
(1 + 3) * 2 # => 8
@@ -69,16 +71,28 @@ not True # => False
not False # => True
# ブール演算
-# 注意: "and" と "or" は小文字です
+# 注意: "and" と "or" は小文字です。
True and False # => False
False or True # => True
-# 整数でブール演算をするときのメモ
-0 and 2 # => 0
--5 or 0 # => -5
+# TrueとFalseは実際には1と0になるキーワードです。
+True + True # => 2
+True * 8 # => 8
+False - 5 # => -5
+
+# 比較演算子はTrueとFalseを数値として扱います。
0 == False # => True
-2 == True # => False
1 == True # => True
+2 == True # => False
+-5 != True # => True
+
+# bool論理演算子を整数に対して使うことで整数を真偽値に変換して評価できますが、キャストされていない値が
+# bool(int)とビット演算子(& や |)を混同しないようにうにしましょう。
+bool(0) # => False
+bool(4) # => True
+bool(-6) # => True
+0 and 2 # => 0
+-5 or 0 # => -5
# 値が等しいか確認するには ==
1 == 1 # => True
@@ -94,7 +108,11 @@ False or True # => True
2 <= 2 # => True
2 >= 2 # => True
-# 比較は連結させられます!
+# 値がある範囲の中にあるか調べる方法
+1 < 2 and 2 < 3 # => True
+2 < 3 and 3 < 2 # => False
+
+# 連結させるともっと見やすくなります。
1 < 2 < 3 # => True
2 < 3 < 2 # => False
@@ -115,7 +133,7 @@ b == a # => True, a と b が参照するオブジェクトの値
# 文字列も加算をすることができます!でも、あまり行わないように。
"Hello " + "world!" # => "Hello world!"
-# '+' を使わなくても連結はできます。
+# '+' を使わなくても文字列リテラル(変数ではないもの)の連結ができます。
"Hello " "world!" # => "Hello world!"
# 文字列は文字のリストであるかのように扱うことができます。
@@ -138,6 +156,12 @@ len("This is a string") # => 16
# 旧式のフォーマット方法を使うこともできます。
"%s can be %s the %s way" % ("Strings", "interpolated", "old") # => "Strings can be interpolated the old way"
+# Python3.6以上では、f-stringsやフォーマット文字列を使ってフォーマットすることもできます。
+name = "Reiko"
+f"She said her name is {name}." # => "She said her name is Reiko"
+
+# 基本的に、任意のPythonの文を中括弧に書くことができ、それは評価されて出力されます。
+f"{name} is {len(name)} characters long."
# None はオブジェクトです(大文字からです!)
None # => None
@@ -170,7 +194,7 @@ print("Hello, World", end="!") # => Hello, World!
input_string_var = input("Enter some data: ") # 入力を文字列として返します
# Note: Python の初期のバージョンでは、 input() は raw_input() という名前で存在します。
-# 変数に代入する前に宣言する必要はありません。
+# Pythonでは変数の宣言は存在せず、代入のみです。
# 慣例的に、小文字でアンダースコア区切り ( lower_case_with_underscores ) の変数が使われます。
some_var = 5
some_var # => 5
@@ -207,10 +231,11 @@ li[-1] # => 3
li[4] # IndexError が発生します
# スライス構文により範囲を参照できます。
+# 開始部分のインデックスに対応する部分は含まれますが、終了部分のインデックスに対応する部分は含まれません。
li[1:3] # => [2, 4]
-# 先端を取り除く
+# 先端を取り除いたリスト
li[2:] # => [4, 3]
-# 末尾を取り除く
+# 末尾を取り除いたリスト
li[:3] # => [1, 2, 4]
# 1つ飛ばしで選択する
li[::2] # =>[1, 4]
@@ -272,7 +297,7 @@ a, b, c = (1, 2, 3) # a, b, c にはそれぞれ 1, 2, 3 が代入
# 拡張記法もあります。
a, *b, c = (1, 2, 3, 4) # a は 1 、 b は [2, 3] 、c は4 になります。
# 括弧を作成しなくてもデフォルトでタプルが作成されます。
-d, e, f = 4, 5, 6
+d, e, f = 4, 5, 6 # 4、5、6がそれぞれd、 e、 fに代入されます。
# 2つの変数を交換するのがどれほど簡単か見てみましょう。
e, d = d, e # d は 5 、 e は e になります。
@@ -293,14 +318,17 @@ filled_dict["one"] # => 1
# "keys()"により、全てのキーを反復可能な形式で取り出せます。
# これをリストにするために、"list()"で囲んでいます。これについては後程解説します。
-# Note: 辞書のキーの順番は考慮されていません。実行した結果がこれと異なる場合があります。
-list(filled_dict.keys()) # => ["three", "two", "one"]
+# Note: Python3.7未満では、辞書のキーの順番は考慮されていません。実行した結果がこれと異なる場合があります。
+# しかし、Python3.7以降ではキーの挿入順を保つようになりました。
+list(filled_dict.keys()) # => ["three", "two", "one"] in Python <3.7
+list(filled_dict.keys()) # => ["one", "two", "three"] in Python 3.7+
+
# "values()"により、全ての値を反復可能な形式で取り出せます。
# 前と同じように、これをリストにするために、"list()"で囲んでいます。
# Note: 辞書の値の順番は考慮されていません。実行した結果がこれと異なる場合があります。
-list(filled_dict.values()) # => [3, 2, 1]
-
+list(filled_dict.values()) # => [3, 2, 1] in Python <3.7
+list(filled_dict.values()) # => [1, 2, 3] in Python 3.7+
# "in" により、辞書のキーが存在するか確認できます。
"one" in filled_dict # => True
@@ -322,7 +350,7 @@ filled_dict.setdefault("five", 6) # filled_dict["five"] は 5 のままです
# 辞書にマップを追加する
filled_dict.update({"four": 4}) # => {"one": 1, "two": 2, "three": 3, "four": 4}
-# filled_dict["four"] = 4 # 辞書に追加する別の方法
+filled_dict["four"] = 4 # 辞書に追加する別の方法
# del により辞書からキーを削除できます。
del filled_dict["one"] # "one" キーを辞書から削除します。
@@ -341,11 +369,11 @@ some_set = {1, 1, 2, 2, 3, 4} # some_set is now {1, 2, 3, 4}
invalid_set = {[1], 1} # => list はハッシュ化できないので、 TypeError が送出されます。
valid_set = {(1,), 1}
-# 新しい値を集合にセットできます。
-filled_set = some_set
-
# 集合に新しい要素を追加できます。
+filled_set = some_set
filled_set.add(5) # filled_set は {1, 2, 3, 4, 5} になりました。
+# 集合は重複した要素を持ちません。
+filled_set.add(5) # 以前の{1, 2, 3, 4, 5}のままです。
# & により、集合同士の共通部分が得られます。
other_set = {3, 4, 5, 6}
@@ -378,7 +406,8 @@ filled_set | other_set # => {1, 2, 3, 4, 5, 6}
# まずは変数を作りましょう。
some_var = 5
-# これはif文です。インデントがPythonでは特徴的ですね!
+# これはif文です。Pythonではインデントが特徴的ですね!
+# 規約ではタブではなく4つのスペースでインデントすることが推奨されています。
# 以下の例では"some_var is smaller than 10"と出力されます。
if some_var > 10:
print("some_var is totally bigger than 10.")
@@ -541,9 +570,9 @@ all_the_args(1, 2, a=3, b=4) prints:
# * を使ってタプルを展開したり、 ** を使って辞書を展開できます。
args = (1, 2, 3, 4)
kwargs = {"a": 3, "b": 4}
-all_the_args(*args) # foo(1, 2, 3, 4) に対応します。
-all_the_args(**kwargs) # foo(a=3, b=4) に対応します。
-all_the_args(*args, **kwargs) # foo(1, 2, 3, 4, a=3, b=4) に対応します。
+all_the_args(*args) # all_the_args(1, 2, 3, 4) と等しいです。
+all_the_args(**kwargs) # all_the_args(a=3, b=4) と等しいです。
+all_the_args(*args, **kwargs) # all_the_args(1, 2, 3, 4, a=3, b=4) と等しいです。
# タプルで複数の値を返す
@@ -646,7 +675,7 @@ dir(math)
# 6. クラス
####################################################
-# クラスを作成するために、"class"という演算子を使います。
+# クラスを作成するために、class文を使います。
class Human:
# クラスの属性です。このクラスの全てのインスタンスで共有されます。
@@ -656,14 +685,14 @@ class Human:
# 2つのアンダースコアがオブジェクトや属性の前後についているとき、これらはPythonによって利用され、
# ユーザーの名前空間には存在しないということに注意してください。
# __init__ や __str__ 、 __repr__ のようなメソッド(やオブジェクト、属性)は、
- # magic methods (または dunder methods)と呼ばれます。
- # このような名前を自分で発明しないほうがよいでしょう。
+ # special methods (または dunder methods)と呼ばれます。
+ # 同じような名前を自分で発明しないほうがよいでしょう。
def __init__(self, name):
# 引数をインスタンスのname属性に設定します。
self.name = name
# プロパティの初期化
- self.age = 0
+ self._age = 0
# インスタンスメソッド。全てのメソッドは"self"を最初の引数に取ります。
def say(self, msg):
@@ -686,6 +715,7 @@ class Human:
# プロパティはgetterのようなものです。
# age() メソッドを同名の読取専用属性に変換します。
+ # Pythonではわざわざgetterやsetterを書く必要はありません。
@property
def age(self):
return self._age
@@ -720,24 +750,117 @@ if __name__ == '__main__':
j.say(j.get_species()) # => "Joel: H. neanderthalensis"
# スタティックメソッドを呼んでみましょう。
- print(Human.grunt()) # => "*grunt*"
- print(i.grunt()) # => "*grunt*"
+ print(Human.grunt()) # => "*grunt*"
+
+ # スタティックメソッドはインスタンスから呼ぶことはできません。
+ # なぜならば、 i.grunt() は自動的に"self" ( i オブジェクト ) を引数として渡してしまうからです。
+ print(i.grunt()) # => TypeError: grunt() takes 0 positional arguments but 1 was given
# インスタンスのプロパティを更新してみましょう。
i.age = 42
# プロパティを取得してみましょう。
- i.say(i.age) # => 42
- j.say(j.age) # => 0
+ i.say(i.age) # => "Ian: 42"
+ j.say(j.age) # => "Joel: 0"
# プロパティを削除してみましょう。
del i.age
# i.age # => AttributeError が発生します。
####################################################
-# 6.1 多重継承
+# 6.1 継承
+####################################################
+# 継承を行うことで、親クラスからメソッドと変数を継承する新しい子クラスを定義できます。
+
+# 上記で定義されたHumanクラスを親クラス(基底クラス)として使い、Superheroという子クラスを定義します。
+# これは"species"、"name"や"age"といった変数や、"sing"や"grunt"のようなメソッドをHumanから継承しますが、
+# Superhero独自のプロパティを持つこともできます。
+
+# ファイルを分割してモジュール化の利点を活用するために、上記のHumanクラスを独自のファイル、ここでは human.py に記述ましょう。
+
+# 別のファイルから関数をインポートするには次の形式を利用してください:
+# from "拡張子なしのファイル名" import "関数やクラス"
+
+from human import Human
+
+
+# 親クラスを子クラスのパラメータとして指定します
+class Superhero(Human):
+
+ # もし子クラスが親クラスの全ての定義を変更なしで継承する場合、"pass"キーワードのみを書くだけで良いです。
+ # しかし、今回は親クラスとは異なる子クラスを作成するので、今回は以下の通りコメントアウトしています。
+ # pass
+
+ # 子クラスは親クラスの属性を上書きできます。
+ species = 'Superhuman'
+
+ # 子クラスは親クラスのコンストラクタを引数含めて自動的に継承しますが、
+ # 追加の引数や定義を行ってコンストラクタのようなメソッドを上書きすることもできます。
+ # このコンストラクタは"name"引数を"Human"クラスから継承し、"superpower"と"movie"という引数を追加します。
+ def __init__(self, name, movie=False,
+ superpowers=["super strength", "bulletproofing"]):
+
+ # 追加のクラス属性を作成する
+ self.fictional = True
+ self.movie = movie
+ # デフォルト値は共有されるので、可変のデフォルト値には注意してください。
+ self.superpowers = superpowers
+
+ # "super"関数を使うと子クラスに上書きされた親クラスのメソッド(今回は "__init__")にアクセスできます。
+ # これで、親クラスのコンストラクタを呼んでいます。
+ super().__init__(name)
+
+ # singメソッドを上書きし、
+ def sing(self):
+ return 'Dun, dun, DUN!'
+
+ # 追加のインスタンスメソッドを作成します。
+ def boast(self):
+ for power in self.superpowers:
+ print("I wield the power of {pow}!".format(pow=power))
+
+
+if __name__ == '__main__':
+ sup = Superhero(name="Tick")
+
+ # インスタンスの型を調べる
+ if isinstance(sup, Human):
+ print('I am human')
+ if type(sup) is Superhero:
+ print('I am a superhero')
+
+ # getattr()とsuper()で使われるメソッドの解決順序を調べてみます。
+ # この属性は動的であり、変更可能です。
+ print(Superhero.__mro__) # => (<class '__main__.Superhero'>,
+ # => <class 'human.Human'>, <class 'object'>)
+
+ # 親のメソッドを呼びだすものの、独自のクラス属性を参照します。
+ print(sup.get_species()) # => Superhuman
+
+ # 上書きされたメソッドを呼ぶ
+ print(sup.sing()) # => Dun, dun, DUN!
+
+ # Humanのメソッドを呼ぶ
+ sup.say('Spoon') # => Tick: Spoon
+
+ # Superhero限定のメソッドを呼ぶ
+ sup.boast() # => I wield the power of super strength!
+ # => I wield the power of bulletproofing!
+
+ # 継承されたクラス属性
+ sup.age = 31
+ print(sup.age) # => 31
+
+ # Superhero限定の属性
+ print('Am I Oscar eligible? ' + str(sup.movie))
+
+
+
+####################################################
+# 6.2 多重継承
####################################################
# 別のクラスを定義します。
+# bat.py
class Bat:
species = 'Baty'
@@ -759,31 +882,22 @@ if __name__ == '__main__':
print(b.say('hello'))
print(b.fly)
-# ファイル単位のモジュール化を利用するために、上記のクラスを別々のファイルに配置することができます。
-# ここでは、human.pyとbat.pyを作成してみましょう。
-
-# 他のファイルから関数をインポートするために、次のような形式を利用してください。
-# from "拡張子無しのファイル名" import "関数またはクラス"
-
# superhero.py
-from human import Human
+from superhero import Superhero
from bat import Bat
-
-# BatmanはHumanとBatの両方を継承します。
-class Batman(Human, Bat):
-
- # Batmanは species のクラス属性に独自の値を持ちます。
- species = 'Superhero'
+# BatmanをSuperheroとBatの両方を継承した子クラスとして定義します。
+class Batman(Superhero, Bat):
def __init__(self, *args, **kwargs):
# 通常、属性を継承するにはsuper()を呼び出します。
- # super(Batman, self).__init__(*args, **kwargs)
+ # super(Batman, self).__init__(*args, **kwargs)
# しかし、ここでは多重継承を行っているので、 super() はMRO(メソッド解決順序)の次の基本クラスにのみ動作します。
# なので、全ての祖先に対して明示的に __init__ を呼ぶことにします。
# *args と **kwargs を使うことで、それぞれの継承元が
# たまねぎの皮を剥がすごとく、引数を用いることができます。
- Human.__init__(self, 'anonymous', *args, **kwargs)
+ Superhero.__init__(self, 'anonymous', movie=True,
+ superpowers=['Wealthy'], *args, **kwargs)
Bat.__init__(self, *args, can_fly=False, **kwargs)
# 名前の属性の値を上書きします。
self.name = 'Sad Affleck'
@@ -795,22 +909,18 @@ class Batman(Human, Bat):
if __name__ == '__main__':
sup = Batman()
- # インスタンスの型を調べてみましょう。
- if isinstance(sup, Human):
- print('I am human')
- if isinstance(sup, Bat):
- print('I am bat')
- if type(sup) is Batman:
- print('I am Batman')
-
# getattr() や super() の両方で使われるMROを取得します。
# この属性は動的であり、更新が可能です。
- print(Batman.__mro__) # => (<class '__main__.Batman'>, <class 'human.Human'>, <class 'bat.Bat'>, <class 'object'>)
+ print(Batman.__mro__) # => (<class '__main__.Batman'>,
+ # => <class 'superhero.Superhero'>,
+ # => <class 'human.Human'>,
+ # => <class 'bat.Bat'>, <class 'object'>)
+
# 親メソッドを呼び出しますが、独自のクラス属性を参照します。
- print(sup.get_species()) # => Superhero
+ print(sup.get_species()) # => Superhuman
- # オーバーロードされたメソッドを呼び出します。
+ # 上書きされたメソッドを呼び出します。
print(sup.sing()) # => nan nan nan nan nan batman!
# 継承順により、Humanから継承されたメソッドを呼び出します。
@@ -821,10 +931,10 @@ if __name__ == '__main__':
# 継承されたクラス属性
sup.age = 100
- print(sup.age)
+ print(sup.age) # => 100
# デフォルト値が上書きされて、2番目の先祖から継承された属性
- print('Can I fly? ' + str(sup.fly))
+ print('Can I fly? ' + str(sup.fly)) # => Can I fly? False
####################################################
diff --git a/javascript.html.markdown b/javascript.html.markdown
index ecaf02c5..c466c09b 100644
--- a/javascript.html.markdown
+++ b/javascript.html.markdown
@@ -510,6 +510,7 @@ for (var x in myObj){
// Hello world!
// 43
// [Function: myFunc]
+// true
// To only consider properties attached to the object itself
// and not its prototypes, use the `hasOwnProperty()` check.
diff --git a/json.html.markdown b/json.html.markdown
index 322c7a47..3ec7a3af 100644
--- a/json.html.markdown
+++ b/json.html.markdown
@@ -6,6 +6,7 @@ contributors:
- ["Marco Scannadinari", "https://github.com/marcoms"]
- ["himanshu", "https://github.com/himanshu81494"]
- ["Michael Neth", "https://github.com/infernocloud"]
+ - ["Athanasios Emmanouilidis", "https://github.com/athanasiosem"]
---
JSON is an extremely simple data-interchange format. As [json.org](http://json.org) says, it is easy for humans to read and write and for machines to parse and generate.
@@ -14,7 +15,6 @@ A piece of JSON must represent either:
* A collection of name/value pairs (`{ }`). In various languages, this is realized as an object, record, struct, dictionary, hash table, keyed list, or associative array.
* An ordered list of values (`[ ]`). In various languages, this is realized as an array, vector, list, or sequence.
- an array/list/sequence (`[ ]`) or a dictionary/object/associated array (`{ }`).
JSON in its purest form has no actual comments, but most parsers will accept C-style (`//`, `/* */`) comments. Some parsers also tolerate a trailing comma (i.e. a comma after the last element of an array or the after the last property of an object), but they should be avoided for better compatibility.
diff --git a/julia.html.markdown b/julia.html.markdown
index 2fe05c49..5e9ef1b8 100644
--- a/julia.html.markdown
+++ b/julia.html.markdown
@@ -46,6 +46,13 @@ div(5, 2) # => 2 # for a truncated result, use div
# Enforce precedence with parentheses
(1 + 3) * 2 # => 8
+# Julia (unlike Python for instance) has integer under/overflow
+10^19 # => -8446744073709551616
+# use bigint or floating point to avoid this
+big(10)^19 # => 10000000000000000000
+1e19 # => 1.0e19
+10.0^19 # => 1.0e19
+
# Bitwise Operators
~2 # => -3 # bitwise not
3 & 5 # => 1 # bitwise and
@@ -93,21 +100,22 @@ ascii("This is a string")[1]
# Julia indexes from 1
# Otherwise, iterating over strings is recommended (map, for loops, etc).
+# String can be compared lexicographically
+"good" > "bye" # => true
+"good" == "good" # => true
+"1 + 2 = 3" == "1 + 2 = $(1 + 2)" # => true
+
# $ can be used for string interpolation:
"2 + 2 = $(2 + 2)" # => "2 + 2 = 4"
# You can put any Julia expression inside the parentheses.
+# Printing is easy
+println("I'm Julia. Nice to meet you!") # => I'm Julia. Nice to meet you!
+
# Another way to format strings is the printf macro from the stdlib Printf.
using Printf
@printf "%d is less than %f\n" 4.5 5.3 # => 5 is less than 5.300000
-# Printing is easy
-println("I'm Julia. Nice to meet you!") # => I'm Julia. Nice to meet you!
-
-# String can be compared lexicographically
-"good" > "bye" # => true
-"good" == "good" # => true
-"1 + 2 = 3" == "1 + 2 = $(1 + 2)" # => true
####################################################
## 2. Variables and Collections
@@ -163,6 +171,8 @@ matrix = [1 2; 3 4] # => 2×2 Array{Int64,2}: [1 2; 3 4]
b = Int8[4, 5, 6] # => 3-element Array{Int8,1}: [4, 5, 6]
# Add stuff to the end of a list with push! and append!
+# By convention, the exclamation mark '!'' is appended to names of functions
+# that modify their arguments
push!(a, 1) # => [1]
push!(a, 2) # => [1,2]
push!(a, 4) # => [1,2,4]
diff --git a/ko-kr/python-kr.html.markdown b/ko-kr/python-kr.html.markdown
index ed377a99..0145754d 100644
--- a/ko-kr/python-kr.html.markdown
+++ b/ko-kr/python-kr.html.markdown
@@ -441,7 +441,7 @@ Human.grunt() #=> "*grunt*"
# 다음과 같이 모듈을 임포트할 수 있습니다.
import math
-print math.sqrt(16) #=> 4
+print math.sqrt(16) #=> 4.0
# 모듈의 특정 함수를 호출할 수 있습니다.
from math import ceil, floor
diff --git a/kotlin.html.markdown b/kotlin.html.markdown
index 9bc8b420..5bbf6847 100644
--- a/kotlin.html.markdown
+++ b/kotlin.html.markdown
@@ -109,7 +109,7 @@ fun helloWorld(val name : String) {
/*
When a function consists of a single expression then the curly brackets can
- be omitted. The body is specified after a = symbol.
+ be omitted. The body is specified after the = symbol.
*/
fun odd(x: Int): Boolean = x % 2 == 1
println(odd(6)) // => false
@@ -306,7 +306,7 @@ fun helloWorld(val name : String) {
println(result)
/*
- We can check if an object is a particular type by using the "is" operator.
+ We can check if an object is of a particular type by using the "is" operator.
If an object passes a type check then it can be used as that type without
explicitly casting it.
*/
@@ -346,17 +346,25 @@ fun helloWorld(val name : String) {
return this.filter {it != c}
}
println("Hello, world!".remove('l')) // => Heo, word!
-
- println(EnumExample.A) // => A
- println(ObjectExample.hello()) // => hello
-
- testOperator()
}
// Enum classes are similar to Java enum types.
enum class EnumExample {
- A, B, C
+ A, B, C // Enum constants are separated with commas.
+}
+fun printEnum() = println(EnumExample.A) // => A
+
+// Since each enum is an instance of the enum class, they can be initialized as:
+enum class EnumExample(val value: Int) {
+ A(value = 1),
+ B(value = 2),
+ C(value = 3)
}
+fun printProperty() = println(EnumExample.A.value) // => 1
+
+// Every enum has properties to obtain its name and ordinal(position) in the enum class declaration:
+fun printName() = println(EnumExample.A.name) // => A
+fun printPosition() = println(EnumExample.A.ordinal) // => 0
/*
The "object" keyword can be used to create singleton objects.
@@ -367,11 +375,18 @@ object ObjectExample {
fun hello(): String {
return "hello"
}
+
+ override fun toString(): String {
+ return "Hello, it's me, ${ObjectExample::class.simpleName}"
+ }
}
-fun useObject() {
- ObjectExample.hello()
- val someRef: Any = ObjectExample // we use objects name just as is
+
+fun useSingletonObject() {
+ println(ObjectExample.hello()) // => hello
+ // In Kotlin, "Any" is the root of the class hierarchy, just like "Object" is in Java
+ val someRef: Any = ObjectExample
+ println(someRef) // => Hello, it's me, ObjectExample
}
@@ -381,69 +396,54 @@ throws an exception if the value is null.
var b: String? = "abc"
val l = b!!.length
-/* You can add many custom operations using symbol like +, to particular instance
-by overloading the built-in kotlin operator, using "operator" keyword
+data class Counter(var value: Int) {
+ // overload Counter += Int
+ operator fun plusAssign(increment: Int) {
+ this.value += increment
+ }
-below is the sample class to add some operator, and the most basic example
-*/
-data class SomeClass(var savedValue: Int = 0)
+ // overload Counter++ and ++Counter
+ operator fun inc() = Counter(value + 1)
-// instance += valueToAdd
-operator fun SomeClass.plusAssign(valueToAdd: Int) {
- this.savedValue += valueToAdd
-}
+ // overload Counter + Counter
+ operator fun plus(other: Counter) = Counter(this.value + other.value)
-// -instance
-operator fun SomeClass.unaryMinus() = SomeClass(-this.savedValue)
+ // overload Counter * Counter
+ operator fun times(other: Counter) = Counter(this.value * other.value)
-// ++instance or instance++
-operator fun SomeClass.inc() = SomeClass(this.savedValue + 1)
+ // overload Counter * Int
+ operator fun times(value: Int) = Counter(this.value * value)
-// instance * other
-operator fun SomeClass.times(other: SomeClass) =
- SomeClass(this.savedValue * other.savedValue)
+ // overload Counter in Counter
+ operator fun contains(other: Counter) = other.value == this.value
-// an overload for multiply
-operator fun SomeClass.times(value: Int) = SomeClass(this.savedValue * value)
+ // overload Counter[Int] = Int
+ operator fun set(index: Int, value: Int) {
+ this.value = index + value
+ }
-// other in instance
-operator fun SomeClass.contains(other: SomeClass) =
- other.savedValue == this.savedValue
+ // overload Counter instance invocation
+ operator fun invoke() = println("The value of the counter is $value")
-// instance[dummyIndex] = valueToSet
-operator fun SomeClass.set(dummyIndex: Int, valueToSet: Int) {
- this.savedValue = valueToSet + dummyIndex
}
-
-// instance()
-operator fun SomeClass.invoke() {
- println("instance invoked by invoker")
-}
-
-/* return type must be Integer,
-so that, it can be translated to "returned value" compareTo 0
-
-for equality (==,!=) using operator will violates overloading equals function,
-since it is already defined in Any class
-*/
-operator fun SomeClass.compareTo(other: SomeClass) =
- this.savedValue - other.savedValue
-
-fun testOperator() {
- var x = SomeClass(4)
-
- println(x) // => "SomeClass(savedValue=4)"
- x += 10
- println(x) // => "SomeClass(savedValue=14)"
- println(-x) // => "SomeClass(savedValue=-14)"
- println(++x) // => "SomeClass(savedValue=15)"
- println(x * SomeClass(3)) // => "SomeClass(savedValue=45)"
- println(x * 2) // => "SomeClass(savedValue=30)"
- println(SomeClass(15) in x) // => true
- x[2] = 10
- println(x) // => "SomeClass(savedValue=12)"
- x() // => "instance invoked by invoker"
- println(x >= 15) // => false
+/* You can also overload operators through an extension methods */
+// overload -Counter
+operator fun Counter.unaryMinus() = Counter(-this.value)
+
+fun operatorOverloadingDemo() {
+ var counter1 = Counter(0)
+ var counter2 = Counter(5)
+ counter1 += 7
+ println(counter1) // => Counter(value=7)
+ println(counter1 + counter2) // => Counter(value=12)
+ println(counter1 * counter2) // => Counter(value=35)
+ println(counter2 * 2) // => Counter(value=10)
+ println(counter1 in Counter(5)) // => false
+ println(counter1 in Counter(7)) // => true
+ counter1[26] = 10
+ println(counter1) // => Counter(value=36)
+ counter1() // => The value of the counter is 36
+ println(-counter2) // => Counter(value=-5)
}
```
diff --git a/lambda-calculus.html.markdown b/lambda-calculus.html.markdown
index 3d080de7..53a7a7cd 100644
--- a/lambda-calculus.html.markdown
+++ b/lambda-calculus.html.markdown
@@ -85,7 +85,7 @@ Using `IF`, we can define the basic boolean logic operators:
`a OR b` is equivalent to: `λab.IF a T b`
-`a NOT b` is equivalent to: `λa.IF a F T`
+`NOT a` is equivalent to: `λa.IF a F T`
*Note: `IF a b c` is essentially saying: `IF((a b) c)`*
@@ -111,7 +111,7 @@ we use the successor function `S(n) = n + 1` which is:
Using successor, we can define add:
-`ADD = λab.(a S)n`
+`ADD = λab.(a S)b`
**Challenge:** try defining your own multiplication function!
@@ -139,6 +139,7 @@ Take the church number 2 for example:
`2 = λf.λx.f(f x)`
For the inner part `λx.f(f x)`:
+
```
λx.f(f x)
= S (λx.f) (λx.(f x)) (case 3)
@@ -147,6 +148,7 @@ For the inner part `λx.f(f x)`:
```
So:
+
```
2
= λf.λx.f(f x)
@@ -156,6 +158,7 @@ So:
```
For the first argument `λf.(S (K f))`:
+
```
λf.(S (K f))
= S (λf.S) (λf.(K f)) (case 3)
@@ -164,6 +167,7 @@ For the first argument `λf.(S (K f))`:
```
For the second argument `λf.(S (K f) I)`:
+
```
λf.(S (K f) I)
= λf.((S (K f)) I)
@@ -174,6 +178,7 @@ For the second argument `λf.(S (K f) I)`:
```
Merging them up:
+
```
2
= S (λf.(S (K f))) (λf.(S (K f) I))
diff --git a/latex.html.markdown b/latex.html.markdown
index 874efeeb..c980f5e5 100644
--- a/latex.html.markdown
+++ b/latex.html.markdown
@@ -95,7 +95,7 @@ to the source code.
Separate paragraphs by empty lines.
-You need to add a dot after abbreviations (if not followed by a comma), because otherwise the spacing after the dot is too large:
+You need to add a backslash after abbreviations (if not followed by a comma), because otherwise the spacing after the dot is too large:
E.g., i.e., etc.\ are are such abbreviations.
\section{Lists}
diff --git a/linker.html.markdown b/linker.html.markdown
new file mode 100644
index 00000000..ebe6233d
--- /dev/null
+++ b/linker.html.markdown
@@ -0,0 +1,9 @@
+---
+category: tool
+tool: linker
+contributors:
+ - ["Alexander Kovalchuk", "https://github.com/Zamuhrishka"]
+---
+
+This article is available in [Russian](http://localhost:4567/docs/ru-ru/linker-ru/).
+
diff --git a/logtalk.html.markdown b/logtalk.html.markdown
index 5a52bd3c..ce907ee3 100644
--- a/logtalk.html.markdown
+++ b/logtalk.html.markdown
@@ -40,7 +40,7 @@ An object encapsulates predicate declarations and definitions. Objects can be cr
:- end_object.
```
-# Compiling source files
+# Compiling and loading source files
Assuming that the code above for the `list` object is saved in a `list.lgt` file, it can be compiled and loaded using the `logtalk_load/1` built-in predicate or its abbreviation, `{}/1`, with the file path as argument (the extension can be omitted):
@@ -49,6 +49,11 @@ Assuming that the code above for the `list` object is saved in a `list.lgt` file
yes
```
+In general, entities may have dependencies on entities defined in other source files (e.g. library entities). To load a file and all its dependencies, the advised solution is to define a
+_loader_ file that loads all the necessary files for an application. A loader file is simply a source file, typically named `loader.lgt`, that makes calls to the `logtalk_load/1-2`
+built-in predicates, usually from an `initialization/1` directive for portability and
+standards compliance. Loader files are provided for all libraries, tools, and examples.
+
# Sending a message to an object
The `::/2` infix operator is used to send a message to an object. As in Prolog, we can backtrack for alternative solutions:
diff --git a/lua.html.markdown b/lua.html.markdown
index 32174a81..0a7c4f00 100644
--- a/lua.html.markdown
+++ b/lua.html.markdown
@@ -12,13 +12,15 @@ filename: learnlua.lua
Adding two ['s and ]'s makes it a
multi-line comment.
--]]
---------------------------------------------------------------------------------
+
+----------------------------------------------------
-- 1. Variables and flow control.
---------------------------------------------------------------------------------
+----------------------------------------------------
num = 42 -- All numbers are doubles.
--- Don't freak out, 64-bit doubles have 52 bits for storing exact int
--- values; machine precision is not a problem for ints that need < 52 bits.
+-- Don't freak out, 64-bit doubles have 52 bits for
+-- storing exact int values; machine precision is
+-- not a problem for ints that need < 52 bits.
s = 'walternate' -- Immutable strings like Python.
t = "double-quotes are also fine"
@@ -58,15 +60,10 @@ aBoolValue = false
-- Only nil and false are falsy; 0 and '' are true!
if not aBoolValue then print('twas false') end
--- 'or' and 'and' are short-circuited. This is similar to the a?b:c operator
--- in C/js:
+-- 'or' and 'and' are short-circuited.
+-- This is similar to the a?b:c operator in C/js:
ans = aBoolValue and 'yes' or 'no' --> 'no'
--- BEWARE: this only acts as a ternary if the value returned when the condition
--- evaluates to true is not `false` or Nil
-iAmNotFalse = (not aBoolValue) and false or true --> true
-iAmAlsoNotFalse = (not aBoolValue) and true or false --> true
-
karlSum = 0
for i = 1, 100 do -- The range includes both ends.
karlSum = karlSum + i
@@ -84,19 +81,20 @@ repeat
num = num - 1
until num == 0
---------------------------------------------------------------------------------
+
+----------------------------------------------------
-- 2. Functions.
---------------------------------------------------------------------------------
+----------------------------------------------------
function fib(n)
- if n < 2 then return n end
+ if n < 2 then return 1 end
return fib(n - 2) + fib(n - 1)
end
-- Closures and anonymous functions are ok:
function adder(x)
- -- The returned function is created when adder is called, and remembers the
- -- value of x:
+ -- The returned function is created when adder is
+ -- called, and remembers the value of x:
return function (y) return x + y end
end
a1 = adder(9)
@@ -104,9 +102,10 @@ a2 = adder(36)
print(a1(16)) --> 25
print(a2(64)) --> 100
--- Returns, func calls, and assignments all work with lists that may be
--- mismatched in length. Unmatched receivers are nil; unmatched senders are
--- discarded.
+-- Returns, func calls, and assignments all work
+-- with lists that may be mismatched in length.
+-- Unmatched receivers are nil;
+-- unmatched senders are discarded.
x, y, z = 1, 2, 3, 4
-- Now x = 1, y = 2, z = 3, and 4 is thrown away.
@@ -119,15 +118,13 @@ end
x, y = bar('zaphod') --> prints "zaphod nil nil"
-- Now x = 4, y = 8, values 15..42 are discarded.
--- Functions are first-class, may be local/global. These are the same:
+-- Functions are first-class, may be local/global.
+-- These are the same:
function f(x) return x * x end
f = function (x) return x * x end
-- And so are these:
local function g(x) return math.sin(x) end
-local g = function(x) return math.sin(x) end
--- Equivalent to local function g(x)..., except referring to g in the function
--- body won't work as expected.
local g; g = function (x) return math.sin(x) end
-- the 'local g' decl makes g-self-references ok.
@@ -136,16 +133,15 @@ local g; g = function (x) return math.sin(x) end
-- Calls with one string param don't need parens:
print 'hello' -- Works fine.
--- Calls with one table param don't need parens either (more on tables below):
-print {} -- Works fine too.
---------------------------------------------------------------------------------
+----------------------------------------------------
-- 3. Tables.
---------------------------------------------------------------------------------
+----------------------------------------------------
--- Tables = Lua's only compound data structure; they are associative arrays.
--- Similar to php arrays or js objects, they are hash-lookup dicts that can
--- also be used as lists.
+-- Tables = Lua's only compound data structure;
+-- they are associative arrays.
+-- Similar to php arrays or js objects, they are
+-- hash-lookup dicts that can also be used as lists.
-- Using tables as dictionaries / maps:
@@ -161,13 +157,14 @@ t.key2 = nil -- Removes key2 from the table.
u = {['@!#'] = 'qbert', [{}] = 1729, [6.28] = 'tau'}
print(u[6.28]) -- prints "tau"
--- Key matching is basically by value for numbers and strings, but by identity
--- for tables.
+-- Key matching is basically by value for numbers
+-- and strings, but by identity for tables.
a = u['@!#'] -- Now a = 'qbert'.
b = u[{}] -- We might expect 1729, but it's nil:
--- b = nil since the lookup fails. It fails because the key we used is not the
--- same object as the one used to store the original value. So strings &
--- numbers are more portable keys.
+-- b = nil since the lookup fails. It fails
+-- because the key we used is not the same object
+-- as the one used to store the original value. So
+-- strings & numbers are more portable keys.
-- A one-table-param function call needs no parens:
function h(x) print(x.key1) end
@@ -187,15 +184,16 @@ v = {'value1', 'value2', 1.21, 'gigawatts'}
for i = 1, #v do -- #v is the size of v for lists.
print(v[i]) -- Indices start at 1 !! SO CRAZY!
end
--- A 'list' is not a real type. v is just a table with consecutive integer
--- keys, treated as a list.
+-- A 'list' is not a real type. v is just a table
+-- with consecutive integer keys, treated as a list.
---------------------------------------------------------------------------------
+----------------------------------------------------
-- 3.1 Metatables and metamethods.
---------------------------------------------------------------------------------
+----------------------------------------------------
--- A table can have a metatable that gives the table operator-overloadish
--- behaviour. Later we'll see how metatables support js-prototype behaviour.
+-- A table can have a metatable that gives the table
+-- operator-overloadish behavior. Later we'll see
+-- how metatables support js-prototypey behavior.
f1 = {a = 1, b = 2} -- Represents the fraction a/b.
f2 = {a = 2, b = 3}
@@ -205,7 +203,7 @@ f2 = {a = 2, b = 3}
metafraction = {}
function metafraction.__add(f1, f2)
- local sum = {}
+ sum = {}
sum.b = f1.b * f2.b
sum.a = f1.a * f2.b + f2.a * f1.b
return sum
@@ -216,9 +214,10 @@ setmetatable(f2, metafraction)
s = f1 + f2 -- call __add(f1, f2) on f1's metatable
--- f1, f2 have no key for their metatable, unlike prototypes in js, so you must
--- retrieve it as in getmetatable(f1). The metatable is a normal table with
--- keys that Lua knows about, like __add.
+-- f1, f2 have no key for their metatable, unlike
+-- prototypes in js, so you must retrieve it as in
+-- getmetatable(f1). The metatable is a normal table
+-- with keys that Lua knows about, like __add.
-- But the next line fails since s has no metatable:
-- t = s + s
@@ -230,12 +229,11 @@ myFavs = {food = 'pizza'}
setmetatable(myFavs, {__index = defaultFavs})
eatenBy = myFavs.animal -- works! thanks, metatable
---------------------------------------------------------------------------------
--- Direct table lookups that fail will retry using the metatable's __index
--- value, and this recurses.
+-- Direct table lookups that fail will retry using
+-- the metatable's __index value, and this recurses.
--- An __index value can also be a function(tbl, key) for more customized
--- lookups.
+-- An __index value can also be a function(tbl, key)
+-- for more customized lookups.
-- Values of __index,add, .. are called metamethods.
-- Full list. Here a is a table with the metamethod.
@@ -256,19 +254,19 @@ eatenBy = myFavs.animal -- works! thanks, metatable
-- __newindex(a, b, c) for a.b = c
-- __call(a, ...) for a(...)
---------------------------------------------------------------------------------
+----------------------------------------------------
-- 3.2 Class-like tables and inheritance.
---------------------------------------------------------------------------------
+----------------------------------------------------
--- Classes aren't built in; there are different ways to make them using
--- tables and metatables.
+-- Classes aren't built in; there are different ways
+-- to make them using tables and metatables.
-- Explanation for this example is below it.
Dog = {} -- 1.
function Dog:new() -- 2.
- local newObj = {sound = 'woof'} -- 3.
+ newObj = {sound = 'woof'} -- 3.
self.__index = self -- 4.
return setmetatable(newObj, self) -- 5.
end
@@ -281,59 +279,62 @@ mrDog = Dog:new() -- 7.
mrDog:makeSound() -- 'I say woof' -- 8.
-- 1. Dog acts like a class; it's really a table.
--- 2. "function tablename:fn(...)" is the same as
--- "function tablename.fn(self, ...)", The : just adds a first arg called
--- self. Read 7 & 8 below for how self gets its value.
+-- 2. function tablename:fn(...) is the same as
+-- function tablename.fn(self, ...)
+-- The : just adds a first arg called self.
+-- Read 7 & 8 below for how self gets its value.
-- 3. newObj will be an instance of class Dog.
--- 4. "self" is the class being instantiated. Often self = Dog, but inheritance
--- can change it. newObj gets self's functions when we set both newObj's
--- metatable and self's __index to self.
+-- 4. self = the class being instantiated. Often
+-- self = Dog, but inheritance can change it.
+-- newObj gets self's functions when we set both
+-- newObj's metatable and self's __index to self.
-- 5. Reminder: setmetatable returns its first arg.
--- 6. The : works as in 2, but this time we expect self to be an instance
--- instead of a class.
+-- 6. The : works as in 2, but this time we expect
+-- self to be an instance instead of a class.
-- 7. Same as Dog.new(Dog), so self = Dog in new().
-- 8. Same as mrDog.makeSound(mrDog); self = mrDog.
---------------------------------------------------------------------------------
+----------------------------------------------------
-- Inheritance example:
LoudDog = Dog:new() -- 1.
function LoudDog:makeSound()
- local s = self.sound .. ' ' -- 2.
+ s = self.sound .. ' ' -- 2.
print(s .. s .. s)
end
seymour = LoudDog:new() -- 3.
seymour:makeSound() -- 'woof woof woof' -- 4.
---------------------------------------------------------------------------------
-- 1. LoudDog gets Dog's methods and variables.
-- 2. self has a 'sound' key from new(), see 3.
--- 3. Same as "LoudDog.new(LoudDog)", and converted to "Dog.new(LoudDog)" as
--- LoudDog has no 'new' key, but does have "__index = Dog" on its metatable.
--- Result: seymour's metatable is LoudDog, and "LoudDog.__index = Dog". So
--- seymour.key will equal seymour.key, LoudDog.key, Dog.key, whichever
+-- 3. Same as LoudDog.new(LoudDog), and converted to
+-- Dog.new(LoudDog) as LoudDog has no 'new' key,
+-- but does have __index = Dog on its metatable.
+-- Result: seymour's metatable is LoudDog, and
+-- LoudDog.__index = LoudDog. So seymour.key will
+-- = seymour.key, LoudDog.key, Dog.key, whichever
-- table is the first with the given key.
--- 4. The 'makeSound' key is found in LoudDog; this is the same as
--- "LoudDog.makeSound(seymour)".
+-- 4. The 'makeSound' key is found in LoudDog; this
+-- is the same as LoudDog.makeSound(seymour).
-- If needed, a subclass's new() is like the base's:
function LoudDog:new()
- local newObj = {}
+ newObj = {}
-- set up newObj
self.__index = self
return setmetatable(newObj, self)
end
---------------------------------------------------------------------------------
+----------------------------------------------------
-- 4. Modules.
---------------------------------------------------------------------------------
+----------------------------------------------------
---[[ I'm commenting out this section so the rest of this script remains
--- runnable.
+--[[ I'm commenting out this section so the rest of
+-- this script remains runnable.
```
```lua
@@ -359,8 +360,8 @@ local mod = require('mod') -- Run the file mod.lua.
local mod = (function ()
<contents of mod.lua>
end)()
--- It's like mod.lua is a function body, so that locals inside mod.lua are
--- invisible outside it.
+-- It's like mod.lua is a function body, so that
+-- locals inside mod.lua are invisible outside it.
-- This works because mod here = M in mod.lua:
mod.sayHello() -- Says hello to Hrunkner.
@@ -368,19 +369,19 @@ mod.sayHello() -- Says hello to Hrunkner.
-- This is wrong; sayMyName only exists in mod.lua:
mod.sayMyName() -- error
--- require's return values are cached so a file is run at most once, even when
--- require'd many times.
+-- require's return values are cached so a file is
+-- run at most once, even when require'd many times.
-- Suppose mod2.lua contains "print('Hi!')".
local a = require('mod2') -- Prints Hi!
local b = require('mod2') -- Doesn't print; a=b.
-- dofile is like require without caching:
-dofile('mod2') --> Hi!
-dofile('mod2') --> Hi! (runs again, unlike require)
+dofile('mod2.lua') --> Hi!
+dofile('mod2.lua') --> Hi! (runs it again)
-- loadfile loads a lua file but doesn't run it yet.
-f = loadfile('mod2') -- Calling f() runs mod2.lua.
+f = loadfile('mod2.lua') -- Call f() to run it.
-- loadstring is loadfile for strings.
g = loadstring('print(343)') -- Returns a function.
diff --git a/m.html.markdown b/m.html.markdown
new file mode 100644
index 00000000..96828ae5
--- /dev/null
+++ b/m.html.markdown
@@ -0,0 +1,370 @@
+---
+language: M (MUMPS)
+contributors:
+ - ["Fred Turkington", "http://z3ugma.github.io"]
+filename: LEARNM.m
+---
+
+M, or MUMPS (Massachusetts General Hospital Utility Multi-Programming System) is
+a procedural language with a built-in NoSQL database. Or, it’s a database with
+an integrated language optimized for accessing and manipulating that database.
+A key feature of M is that accessing local variables in memory and persistent
+storage use the same basic syntax, so there's no separate query
+language to remember. This makes it fast to program with, especially for
+beginners. M's syntax was designed to be concise in an era where
+computer memory was expensive and limited. This concise style means that a lot
+more fits on one screen without scrolling.
+
+The M database is a hierarchical key-value store designed for high-throughput
+transaction processing. The database is organized into tree structures called
+"globals", which are sparse data structures with parallels to modern formats
+like JSON.
+
+Originally designed in 1966 for the healthcare applications, M continues to be
+used widely by healthcare systems and financial institutions for high-throughput
+real-time applications.
+
+### Example
+
+Here's an example M program to calculate the Fibonacci series:
+
+```
+fib ; compute the first few Fibonacci terms
+ new i,a,b,sum
+ set (a,b)=1 ; Initial conditions
+ for i=1:1 do quit:sum>1000
+ . set sum=a+b
+ . write !,sum
+ . set a=b,b=sum
+```
+
+### Comments
+
+```
+; Comments start with a semicolon (;)
+```
+### Data Types
+
+M has two data types:
+
+```
+; Numbers - no commas, leading and trailing 0 removed.
+; Scientific notation with 'E'.
+; Floats with IEEE 754 double-precision values (15 digits of precision)
+; Examples: 20, 1e3 (stored as 1000), 0500.20 (stored as 500.2)
+; Strings - Characters enclosed in double quotes.
+; "" is the null string. Use "" within a string for "
+; Examples: "hello", "Scrooge said, ""Bah, Humbug!"""
+```
+### Commands
+
+Commands are case insensitive, and have a shortened abbreviation, often the first letter. Commands have zero or more arguments,depending on the command. M is whitespace-aware. Spaces are treated as a delimiter between commands and arguments. Each command is separated from its arguments by 1 space. Commands with zero arguments are followed by 2 spaces.
+
+#### W(rite)
+
+Print data to the current device.
+
+```
+WRITE !,"hello world"
+```
+
+! is syntax for a new line. Multiple statements can be provided as additional arguments:
+
+```
+w !,"foo bar"," ","baz"
+```
+
+#### R(ead)
+
+Retrieve input from the user
+
+```
+READ var
+r !,"Wherefore art thou Romeo? ",why
+```
+Multiple arguments can be passed to a read command. Constants are outputted. Variables are retrieved from the user. The terminal waits for the user to enter the first variable before displaying the second prompt.
+
+```
+r !,"Better one, or two? ",lorem," Better two, or three? ",ipsum
+```
+
+#### S(et)
+
+Assign a value to a variable
+
+```
+SET name="Benjamin Franklin"
+s centi=0.01,micro=10E-6
+w !,centi,!,micro
+
+;.01
+;.00001
+```
+#### K(ill)
+
+Remove a variable from memory or remove a database entry from disk.
+
+```
+KILL centi
+k micro
+```
+### Globals and Arrays
+
+In addition to local variables, M has persistent variables stored to disk called _globals_. Global names must start with a __caret__ (__^__). Globals are the built-in database of M.
+
+Any variable can be an array with the assignment of a _subscript_. Arrays are sparse and do not have a predefined size. Arrays should be visualized like trees, where subscripts are branches and assigned values are leaves. Not all nodes in an array need to have a value.
+
+```
+s ^cars=20
+s ^cars("Tesla",1,"Name")="Model 3"
+s ^cars("Tesla",2,"Name")="Model X"
+s ^cars("Tesla",2,"Doors")=5
+
+w !,^cars
+; 20
+w !,^cars("Tesla")
+; null value - there's no value assigned to this node but it has children
+w !,^cars("Tesla",1,"Name")
+; Model 3
+```
+
+Arrays are automatically sorted in order. Take advantage of the built-in sorting by setting your value of interest as the last child subscript of an array rather than its value.
+
+```
+; A log of temperatures by date and time
+s ^TEMPS("11/12","0600",32)=""
+s ^TEMPS("11/12","1030",48)=""
+s ^TEMPS("11/12","1400",49)=""
+s ^TEMPS("11/12","1700",43)=""
+```
+### Operators
+```jinja
+; Assignment: =
+; Unary: + Convert a string value into a numeric value.
+; Arthmetic:
+; + addition
+­; - subtraction
+; * multiplication
+; / floating-point division
+; \ integer division
+; # modulo
+; ** exponentiation
+; Logical:
+; & and
+; ! or
+; ' not
+; Comparison:
+; = equal
+; '= not equal
+; > greater than
+; < less than
+; '> not greater / less than or equal to
+; '< not less / greater than or equal to
+; String operators:
+; _ concatenate
+; [ contains ­ a contains b
+; ]] sorts after ­ a comes after b
+; '[ does not contain
+; ']] does not sort after
+```
+
+#### Order of operations
+
+Operations in M are _strictly_ evaluated left to right. No operator has precedence over any other.
+You should use parentheses to group expressions.
+
+```
+w 5+3*20
+;160
+;You probably wanted 65
+w 5+(3*20)
+```
+
+### Flow Control, Blocks, & Code Structure
+
+A single M file is called a _routine_. Within a given routine, you can break your code up into smaller chunks with _tags_. The tag starts in column 1 and the commands pertaining to that tag are indented.
+
+A tag can accept parameters and return a value, this is a function. A function is called with '$$':
+
+```
+; Execute the 'tag' function, which has two parameters, and write the result.
+w !,$$tag^routine(a,b)
+```
+
+M has an execution stack. When all levels of the stack have returned, the program ends. Levels are added to the stack with _do_ commands and removed with _quit_ commands.
+
+#### D(o)
+
+With an argument: execute a block of code & add a level to the stack.
+
+```
+d ^routine ;run a routine from the begining.
+; ;routines are identified by a caret.
+d tag ;run a tag in the current routine
+d tag^routine ;run a tag in different routine
+```
+
+Argumentless do: used to create blocks of code. The block is indented with a period for each level of the block:
+
+```
+set a=1
+if a=1 do
+. write !,a
+. read b
+. if b > 10 d
+. . w !, b
+w "hello"
+```
+
+#### Q(uit)
+Stop executing this block and return to the previous stack level.
+Quit can return a value.
+
+#### N(ew)
+Clear a given variable's value _for just this stack level_. Useful for preventing side effects.
+
+Putting all this together, we can create a full example of an M routine:
+
+```
+; RECTANGLE - a routine to deal with rectangle math
+ q ; quit if a specific tag is not called
+
+main
+ n length,width ; New length and width so any previous value doesn't persist
+ w !,"Welcome to RECTANGLE. Enter the dimensions of your rectangle."
+ r !,"Length? ",length,!,"Width? ",width
+ d area(length,width) ;Do a tag
+ s per=$$perimeter(length,width) ;Get the value of a function
+ w !,"Perimeter: ",per
+ q
+
+area(length,width) ; This is a tag that accepts parameters.
+ ; It's not a function since it quits with no value.
+ w !, "Area: ",length*width
+ q ; Quit: return to the previous level of the stack.
+
+perimeter(length,width)
+ q 2*(length+width) ; Quits with a value; thus a function
+```
+
+### Conditionals, Looping and $Order()
+
+F(or) loops can follow a few different patterns:
+
+```jinja
+;Finite loop with counter
+;f var=start:increment:stop
+
+f i=0:5:25 w i," " ;0 5 10 15 20 25
+
+; Infinite loop with counter
+; The counter will keep incrementing forever. Use a conditional with Quit to get out of the loop.
+;f var=start:increment
+
+f j=1:1 w j," " i j>1E3 q ; Print 1-1000 separated by a space
+
+;Argumentless for - infinite loop. Use a conditional with Quit.
+; Also read as "forever" - f or for followed by two spaces.
+s var=""
+f s var=var_"%" w !,var i var="%%%%%%%%%%" q
+; %
+; %%
+; %%%
+; %%%%
+; %%%%%
+; %%%%%%
+; %%%%%%%
+; %%%%%%%%
+; %%%%%%%%%
+; %%%%%%%%%%
+
+```
+
+#### I(f), E(lse), Postconditionals
+
+M has an if/else construct for conditional evaluation, but any command can be conditionally executed without an extra if statement using a _postconditional_. This is a condition that occurs immediately after the command, separated with a colon (:).
+
+```jinja
+; Conditional using traditional if/else
+r "Enter a number: ",num
+i num>100 w !,"huge"
+e i num>10 w !,"big"
+e w !,"small"
+
+; Postconditionals are especially useful in a for loop.
+; This is the dominant for loop construct:
+; a 'for' statement
+; that tests for a 'quit' condition with a postconditional
+; then 'do'es an indented block for each iteration
+
+s var=""
+f s var=var_"%" q:var="%%%%%%%%%%" d ;Read as "Quit if var equals "%%%%%%%%%%"
+. w !,var
+
+;Bonus points - the $L(ength) built-in function makes this even terser
+
+s var=""
+f s var=var_"%" q:$L(var)>10 d ;
+. w !,var
+
+```
+#### Array Looping - $Order
+As we saw in the previous example, M has built-in functions called with a single $, compared to user-defined functions called with $$. These functions have shortened abbreviations, like commands.
+One of the most useful is __$Order()__ / $O(). When given an array subscript, $O returns the next subscript in that array. When it reaches the last subscript, it returns "".
+
+```jinja
+;Let's call back to our ^TEMPS global from earlier:
+; A log of temperatures by date and time
+s ^TEMPS("11/12","0600",32)=""
+s ^TEMPS("11/12","0600",48)=""
+s ^TEMPS("11/12","1400",49)=""
+s ^TEMPS("11/12","1700",43)=""
+; Some more
+s ^TEMPS("11/16","0300",27)=""
+s ^TEMPS("11/16","1130",32)=""
+s ^TEMPS("11/16","1300",47)=""
+
+;Here's a loop to print out all the dates we have temperatures for:
+n date,time ; Initialize these variables with ""
+
+; This line reads: forever; set date as the next date in ^TEMPS.
+; If date was set to "", it means we're at the end, so quit.
+; Do the block below
+f s date=$ORDER(^TEMPS(date)) q:date="" d
+. w !,date
+
+; Add in times too:
+f s date=$ORDER(^TEMPS(date)) q:date="" d
+. w !,"Date: ",date
+. f s time=$O(^TEMPS(date,time)) q:time="" d
+. . w !,"Time: ",time
+
+; Build an index that sorts first by temperature -
+; what dates and times had a given temperature?
+n date,time,temp
+f s date=$ORDER(^TEMPS(date)) q:date="" d
+. f s time=$O(^TEMPS(date,time)) q:time="" d
+. . f s temp=$O(^TEMPS(date,time,temp)) q:temp="" d
+. . . s ^TEMPINDEX(temp,date,time)=""
+
+;This will produce a global like
+^TEMPINDEX(27,"11/16","0300")
+^TEMPINDEX(32,"11/12","0600")
+^TEMPINDEX(32,"11/16","1130")
+```
+
+## Further Reading
+
+There's lots more to learn about M. A great short tutorial comes from the University of Northern Iowa and Professor Kevin O'Kane's [Introduction to the MUMPS Language][1] presentation.
+
+To install an M interpreter / database on your computer, try a [YottaDB Docker image][2].
+
+YottaDB and its precursor, GT.M, have thorough documentation on all the language features including database transactions, locking, and replication:
+
+* [YottaDB Programmer's Guide][3]
+* [GT.M Programmer's Guide][4]
+
+[1]: https://www.cs.uni.edu/~okane/source/MUMPS-MDH/MumpsTutorial.pdf
+[2]: https://yottadb.com/product/get-started/
+[3]: https://docs.yottadb.com/ProgrammersGuide/langfeat.html
+[4]: http://tinco.pair.com/bhaskar/gtm/doc/books/pg/UNIX_manual/index.html
diff --git a/make.html.markdown b/make.html.markdown
index 45d020e9..eecc96bf 100644
--- a/make.html.markdown
+++ b/make.html.markdown
@@ -1,5 +1,6 @@
---
-language: make
+category: tool
+tool: make
contributors:
- ["Robert Steed", "https://github.com/robochat"]
- ["Stephan Fuhrmann", "https://github.com/sfuhrm"]
diff --git a/mercurial.html.markdown b/mercurial.html.markdown
index 330beb35..98658f83 100644
--- a/mercurial.html.markdown
+++ b/mercurial.html.markdown
@@ -350,6 +350,6 @@ $ hg remove *.txt
## Further information
-* [Learning Mercurial in Workflows](https://www.mercurial-scm.org/guid)
+* [Learning Mercurial in Workflows](https://www.mercurial-scm.org/guide)
* [Mercurial Quick Start](https://www.mercurial-scm.org/wiki/QuickStart)
-* [Mercurial: The Definitive Guide by Bryan O'Sullivan](http://hgbook.red-bean.com/) \ No newline at end of file
+* [Mercurial: The Definitive Guide by Bryan O'Sullivan](http://hgbook.red-bean.com/)
diff --git a/ocaml.html.markdown b/ocaml.html.markdown
index 74eb7993..b631df0a 100644
--- a/ocaml.html.markdown
+++ b/ocaml.html.markdown
@@ -161,7 +161,7 @@ let my_lambda = fun x -> x * x ;;
(*** Operators ***)
-(* There is little distintion between operators and functions.
+(* There is little distinction between operators and functions.
Every operator can be called as a function. *)
(+) 3 4 (* Same as 3 + 4 *)
diff --git a/opengl.html.markdown b/opengl.html.markdown
new file mode 100644
index 00000000..83ace3e8
--- /dev/null
+++ b/opengl.html.markdown
@@ -0,0 +1,765 @@
+---
+category: tool
+tool: OpenGL
+filename: learnopengl.cpp
+contributors:
+ - ["Simon Deitermann", "s.f.deitermann@t-online.de"]
+---
+
+**Open Graphics Library** (**OpenGL**) is a cross-language cross-platform application programming interface
+(API) for rendering 2D computer graphics and 3D vector graphics.<sup>[1]</sup> In this tutorial we will be
+focusing on modern OpenGL from 3.3 and above, ignoring "immediate-mode", Displaylists and
+VBO's without use of Shaders.
+I will be using C++ with SFML for window, image and context creation aswell as GLEW
+for modern OpenGL extensions, though there are many other librarys available.
+
+```cpp
+// Creating an SFML window and OpenGL basic setup.
+#include <GL/glew.h>
+#include <GL/gl.h>
+#include <SFML/Graphics.h>
+#include <iostream>
+
+int main() {
+ // First we tell SFML how to setup our OpenGL context.
+ sf::ContextSettings context{ 24, // depth buffer bits
+ 8, // stencil buffer bits
+ 4, // MSAA samples
+ 3, // major opengl version
+ 3 }; // minor opengl version
+ // Now we create the window, enable VSync
+ // and set the window active for OpenGL.
+ sf::Window window{ sf::VideoMode{ 1024, 768 },
+ "opengl window",
+ sf::Style::Default,
+ context };
+ window.setVerticalSyncEnabled(true);
+ window.setActive(true);
+ // After that we initialise GLEW and check if an error occured.
+ GLenum error;
+ glewExperimental = GL_TRUE;
+ if ((err = glewInit()) != GLEW_OK)
+ std::cout << glewGetErrorString(err) << std::endl;
+ // Here we set the color glClear will clear the buffers with.
+ glClearColor(0.0f, // red
+ 0.0f, // green
+ 0.0f, // blue
+ 1.0f); // alpha
+ // Now we can start the event loop, poll for events and draw objects.
+ sf::Event event{ };
+ while (window.isOpen()) {
+ while (window.pollEvent(event)) {
+ if (event.type == sf::Event::Closed)
+ window.close;
+ }
+ // Tell OpenGL to clear the color buffer
+ // and the depth buffer, this will clear our window.
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+ // Flip front- and backbuffer.
+ window.display();
+ }
+ return 0;
+}
+```
+
+## Loading Shaders
+
+After creating a window and our event loop we should create a function,
+that sets up our shader program.
+
+```cpp
+GLuint createShaderProgram(const std::string& vertexShaderPath,
+ const std::string& fragmentShaderPath) {
+ // Load the vertex shader source.
+ std::stringstream ss{ };
+ std::string vertexShaderSource{ };
+ std::string fragmentShaderSource{ };
+ std::ifstream file{ vertexShaderPath };
+ if (file.is_open()) {
+ ss << file.rdbuf();
+ vertexShaderSource = ss.str();
+ file.close();
+ }
+ // Clear the stringstream and load the fragment shader source.
+ ss.str(std::string{ });
+ file.open(fragmentShaderPath);
+ if (file.is_open()) {
+ ss << file.rdbuf();
+ fragmentShaderSource = ss.str();
+ file.close();
+ }
+ // Create the program.
+ GLuint program = glCreateProgram();
+ // Create the shaders.
+ GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER);
+ GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
+ // Now we can load the shader source into the shader objects and compile them.
+ // Because glShaderSource() wants a const char* const*,
+ // we must first create a const char* and then pass the reference.
+ const char* cVertexSource = vertexShaderSource.c_str();
+ glShaderSource(vertexShader, // shader
+ 1, // number of strings
+ &cVertexSource, // strings
+ nullptr); // length of strings (nullptr for 1)
+ glCompileShader(vertexShader);
+ // Now we have to do the same for the fragment shader.
+ const char* cFragmentSource = fragmentShaderSource.c_str();
+ glShaderSource(fragmentShader, 1, &cFragmentSource, nullptr);
+ glCompileShader(fragmentShader);
+ // After attaching the source and compiling the shaders,
+ // we attach them to the program;
+ glAttachShader(program, vertexShader);
+ glAttachShader(program, fragmentShader);
+ glLinkProgram(program);
+ // After linking the shaders we should detach and delete
+ // them to prevent memory leak.
+ glDetachShader(program, vertexShader);
+ glDetachShader(program, fragmentShader);
+ glDeleteShader(vertexShader);
+ glDeleteShader(fragmentShader);
+ // With everything done we can return the completed program.
+ return program;
+}
+```
+
+If you want to check the compilation log you can add the following between <code>glCompileShader()</code> and <code>glAttachShader()</code>.
+
+```cpp
+GLint logSize = 0;
+std::vector<GLchar> logText{ };
+glGetShaderiv(vertexShader, // shader
+ GL_INFO_LOG_LENGTH, // requested parameter
+ &logSize); // return object
+if (logSize > 0) {
+ logText.resize(logSize);
+ glGetShaderInfoLog(vertexShader, // shader
+ logSize, // buffer length
+ &logSize, // returned length
+ logText.data()); // buffer
+ std::cout << logText.data() << std::endl;
+}
+```
+
+The same is possibile after <code>glLinkProgram()</code>, just replace <code>glGetShaderiv()</code> with <code>glGetProgramiv()</code>
+and <code>glGetShaderInfoLog()</code> with <code>glGetProgramInfoLog()</code>.
+
+```cpp
+// Now we can create a shader program with a vertex and a fragment shader.
+// ...
+glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
+
+GLuint program = createShaderProgram("vertex.glsl", "fragment.glsl");
+
+sf::Event event{ };
+// ...
+// We also have to delete the program at the end of the application.
+// ...
+ }
+ glDeleteProgram(program);
+ return 0;
+}
+// ...
+```
+
+Ofcourse we have to create the vertex and fragment shader before we can load them,
+so lets create two basic shaders.
+
+**Vertex Shader**
+
+```glsl
+// Declare which version of GLSL we use.
+// Here we declare, that we want to use the OpenGL 3.3 version of GLSL.
+#version 330 core
+// At attribute location 0 we want an input variable of type vec3,
+// that contains the position of the vertex.
+// Setting the location is optional, if you don't set it you can ask for the
+// location with glGetAttribLocation().
+layout(location = 0) in vec3 position;
+// Every shader starts in it's main function.
+void main() {
+ // gl_Position is a predefined variable that holds
+ // the final vertex position.
+ // It consists of a x, y, z and w coordinate.
+ gl_Position = vec4(position, 1.0);
+}
+```
+
+**Fragment Shader**
+
+```glsl
+#version 330 core
+// The fragment shader does not have a predefined variable for
+// the vertex color, so we have to define a output vec4,
+// that holds the final vertex color.
+out vec4 outColor;
+
+void main() {
+ // We simply set the ouput color to red.
+ // The parameters are red, green, blue and alpha.
+ outColor = vec4(1.0, 0.0, 0.0, 1.0);
+}
+```
+
+## VAO and VBO
+Now we need to define some vertex position we can pass to our shaders. Lets define a simple 2D quad.
+
+```cpp
+// The vertex data is defined in a counter-clockwise way,
+// as this is the default front face.
+std::vector<float> vertexData {
+ -0.5f, 0.5f, 0.0f,
+ -0.5f, -0.5f, 0.0f,
+ 0.5f, -0.5f, 0.0f,
+ 0.5f, 0.5f, 0.0f
+};
+// If you want to use a clockwise definition, you can simply call
+glFrontFace(GL_CW);
+// Next we need to define a Vertex Array Object (VAO).
+// The VAO stores the current state while its active.
+GLuint vao = 0;
+glGenVertexArrays(1, &vao);
+glBindVertexArray(vao);
+// With the VAO active we can now create a Vertex Buffer Object (VBO).
+// The VBO stores our vertex data.
+GLuint vbo = 0;
+glGenBuffers(1, &vbo);
+glBindBuffer(GL_ARRAY_BUFFER, vbo);
+// For reading and copying there are also GL_*_READ and GL_*_COPY,
+// if your data changes more often use GL_DYNAMIC_* or GL_STREAM_*.
+glBufferData(GL_ARRAY_BUFFER, // target buffer
+ sizeof(vertexData[0]) * vertexData.size(), // size
+ vertexData.data(), // data
+ GL_STATIC_DRAW); // usage
+// After filling the VBO link it to the location 0 in our vertex shader,
+// which holds the vertex position.
+// ...
+// To ask for the attibute location, if you haven't set it:
+GLint posLocation = glGetAttribLocation(program, "position");
+// ..
+glEnableVertexAttribArray(0);
+glVertexAttribPointer(0, 3, // location and size
+ GL_FLOAT, // type of data
+ GL_FALSE, // normalized (always false for floats)
+ 0, // stride (interleaved arrays)
+ nullptr); // offset (interleaved arrays)
+// Everything should now be saved in our VAO and we can unbind it and the VBO.
+glBindVertexArray(0);
+glBindBuffer(GL_ARRAY_BUFFER, 0);
+// Now we can draw the vertex data in our render loop.
+// ...
+glClear(GL_COLOR_BUFFER_BIT);
+// Tell OpenGL we want to use our shader program.
+glUseProgram(program);
+// Binding the VAO loads the data we need.
+glBindVertexArray(vao);
+// We want to draw a quad starting at index 0 of the VBO using 4 indices.
+glDrawArrays(GL_QUADS, 0, 4);
+glBindVertexArray(0);
+window.display();
+// ...
+// Ofcource we have to delete the allocated memory for the VAO and VBO at
+// the end of our application.
+// ...
+glDeleteBuffers(1, &vbo);
+glDeleteVertexArrays(1, &vao);
+glDeleteProgram(program);
+return 0;
+// ...
+```
+
+You can find the current code here: [OpenGL - 1](https://pastebin.com/W8jdmVHD).
+
+## More VBO's and Color
+Let's create another VBO for some colors.
+
+```cpp
+std::vector<float> colorData {
+ 1.0f, 0.0f, 0.0f,
+ 0.0f, 1.0f, 0.0f,
+ 0.0f, 0.0f, 1.0f,
+ 1.0f, 1.0f, 0.0f
+};
+```
+
+Next we can simply change some previous parameters to create a second VBO for our colors.
+
+```cpp
+// ...
+GLuint vbo[2];
+glGenBuffers(2, vbo);
+glBindBuffer(GL_ARRAY_BUFFER, vbo[0]);
+// ...
+glDeleteBuffers(2, vbo);
+/ ...
+// With these changes made we now have to load our color data into the new VBO
+// ...
+glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, nullptr);
+
+glBindBuffer(GL_ARRAY_BUFFER, vbo[1]);
+glBufferData(GL_ARRAY_BUFFER, sizeof(colorData[0]) * colorData.size(),
+ colorData.data(), GL_STATIC_DRAW);
+glEnableVertexAttribArray(1);
+glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, nullptr);
+
+glBindVertexArray(0);
+// ...
+```
+
+Next we have to change our vertex shader to pass the color data to the fragment shader.<br>
+**Vertex Shader**
+
+```glsl
+#version 330 core
+
+layout(location = 0) in vec3 position;
+// The new location has to differ from any other input variable.
+// It is the same index we need to pass to
+// glEnableVertexAttribArray() and glVertexAttribPointer().
+layout(location = 1) in vec3 color;
+
+out vec3 fColor;
+
+void main() {
+ fColor = color;
+ gl_Position = vec4(position, 1.0);
+}
+```
+
+**Fragment Shader**
+
+```glsl
+#version 330 core
+
+in vec3 fColor;
+
+out vec4 outColor;
+
+void main() {
+ outColor = vec4(fColor, 1.0);
+}
+```
+
+We define a new input variable ```color``` which represents our color data, this data
+is passed on to ```fColor```, which is an output variable of our vertex shader and
+becomes an input variable for our fragment shader.
+It is imporatant that variables passed between shaders have the exact same name
+and type.
+
+## Handling VBO's
+
+```cpp
+// If you want to completely clear and refill a VBO use glBufferData(),
+// just like we did before.
+// ...
+// There are two mains ways to update a subset of a VBO's data.
+// To update a VBO with existing data
+std::vector<float> newSubData {
+ -0.25f, 0.5f, 0.0f
+};
+glBindBuffer(GL_ARRAY_BUFFER, vbo[0]);
+glBufferSubData(GL_ARRAY_BUFFER, // target buffer
+ 0, // offset
+ sizeof(newSubData[0]) * newSubData.size(), // size
+ newSubData.data()); // data
+// This would update the first three values in our vbo[0] buffer.
+// If you want to update starting at a specific location just set the second
+// parameter to that value and multiply by the types size.
+// ...
+// If you are streaming data, for example from a file,
+// it is faster to directly pass the data to the buffer.
+// Other access values are GL_READ_ONLY and GL_READ_WRITE.
+glBindBuffer(GL_ARRAY_BUFFER, vbo[0]);
+// You can static_cast<float*>() the void* to be more safe.
+void* Ptr = glMapBuffer(GL_ARRAY_BUFFER, // buffer to map
+ GL_WRITE_ONLY); // access to buffer
+memcpy(Ptr, newSubData.data(), sizeof(newSubData[0]) * newSubData.size());
+// To copy to a specific location add a destination offset to memcpy().
+glUnmapBuffer(GL_ARRAY_BUFFER);
+// ...
+// There is also a way to copy data from one buffer to another,
+// If we have two VBO's vbo[0] and vbo[1], we can copy like so
+// You can also read from GL_ARRAY_BUFFER.
+glBindBuffer(GL_COPY_READ_BUFFER, vbo[0]);
+// GL_COPY_READ_BUFFER and GL_COPY_WRITE_BUFFER are specifically for
+// copying buffer data.
+glBindBuffer(GL_COPY_WRITE_BUFFER, vbo[1]);
+glCopyBufferSubData(GL_COPY_READ_BUFFER, // read buffer
+ GL_COPY_WRITE_BUFFER, // write buffer
+ 0, 0, // read and write offset
+ sizeof(vbo[0]) * 3); // copy size
+// This will copy the first three elements from vbo[0] to vbo[1].
+```
+
+## Uniforms
+
+**Fragment Shader**
+
+```glsl
+// Uniforms are variables like in and out, however,
+// we can change them easily by passing new values with glUniform().
+// Lets define a time variable in our fragment shader.
+#version 330 core
+// Unlike a in/out variable we can use a uniform in every shader,
+// without the need to pass it to the next one, they are global.
+// Don't use locations already used for attributes!
+// Uniform layout locations require OpenGL 4.3!
+layout(location = 10) uniform float time;
+
+in vec3 fColor;
+
+out vec4 outColor;
+
+void main() {
+ // Create a sine wave from 0 to 1 based on the time passed to the shader.
+ float factor = (sin(time * 2) + 1) / 2;
+ outColor = vec4(fColor.r * factor, fColor.g * factor, fColor.b * factor, 1.0);
+}
+```
+
+Back to our source code.
+
+```cpp
+// If we haven't set the layout location, we can ask for it.
+GLint timeLocation = glGetUniformLocation(program, "time");
+// ...
+// Also we should define a Timer counting the current time.
+sf::Clock clock{ };
+// In out render loop we can now update the uniform every frame.
+ // ...
+ window.display();
+ glUniform1f(10, // location
+ clock.getElapsedTime().asSeconds()); // data
+}
+// ...
+```
+
+With the time getting updated every frame the quad should now be changing from
+fully colored to pitch black.
+There are different types of glUniform() you can find simple documentation here:
+[glUniform - OpenGL Refpage](https://www.khronos.org/registry/OpenGL-Refpages/gl4/html/glUniform.xhtml)
+
+## Indexing and IBO's
+
+Element Array Buffers or more commonly Index Buffer Objects (IBO) allow us to use the
+same vertex data again which makes drawing a lot easier and faster. here's an example:
+
+```cpp
+// Lets create a quad from two rectangles.
+// We can simply use the old vertex data from before.
+// First, we have to create the IBO.
+// The index is referring to the first declaration in the VBO.
+std::vector<unsigned int> iboData {
+ 0, 1, 2,
+ 0, 2, 3
+};
+// That's it, as you can see we could reuse 0 - the top left
+// and 2 - the bottom right.
+// Now that we have our data, we have to fill it into a buffer.
+// Note that this has to happen between the two glBindVertexArray() calls,
+// so it gets saved into the VAO.
+GLuint ibo = 0;
+glGenBufferrs(1, &ibo);
+glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo);
+glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(iboData[0]) * iboData.size(),
+ iboData.data(), GL_STATIC_DRAW);
+// Next in our render loop, we replace glDrawArrays() with:
+glDrawElements(GL_TRIANGLES, iboData.size(), GL_UNSINGED_INT, nullptr);
+// Remember to delete the allocated memory for the IBO.
+```
+
+You can find the current code here: [OpenGL - 2](https://pastebin.com/R3Z9ACDE).
+
+## Textures
+
+To load out texture we first need a library that loads the data, for simplicity I will be
+using SFML, however there are a lot of librarys for loading image data.
+
+```cpp
+// Lets save we have a texture called "my_tex.tga", we can load it with:
+sf::Image image;
+image.loadFromFile("my_tex.tga");
+// We have to flip the texture around the y-Axis, because OpenGL's texture
+// origin is the bottom left corner, not the top left.
+image.flipVertically();
+// After loading it we have to create a OpenGL texture.
+GLuint texture = 0;
+glGenTextures(1, &texture);
+glBindTexture(GL_TEXTURE_2D, texture);
+// Specify what happens when the coordinates are out of range.
+glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
+glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
+// Specify the filtering if the object is very large.
+glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+// Load the image data to the texture.
+glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, image.getSize().x, image.getSize().y,
+ 0, GL_RGBA, GL_UNSIGNED_BYTE, image.getPixelsPtr());
+// Unbind the texture to prevent modifications.
+glBindTexture(GL_TEXTURE_2D, 0);
+// Delete the texture at the end of the application.
+// ...
+glDeleteTextures(1, &texture);
+```
+
+Ofcourse there are more texture formats than only 2D textures,
+You can find further information on parameters here:
+[glBindTexture - OpenGL Refpage](https://www.khronos.org/registry/OpenGL-Refpages/gl4/html/glBindTexture.xhtml)<br>
+[glTexImage2D - OpenGL Refpage](https://www.khronos.org/registry/OpenGL-Refpages/gl4/html/glTexImage2D.xhtml)<br>
+[glTexParameter - OpenGL Refpage](https://www.khronos.org/registry/OpenGL-Refpages/gl4/html/glTexParameter.xhtml)<br>
+
+```cpp
+// With the texture created, we now have to specify the UV,
+// or in OpenGL terms ST coordinates.
+std::vector<float> texCoords {
+ // The texture coordinates have to match the triangles/quad
+ // definition.
+ 0.0f, 1.0f, // start at top-left
+ 0.0f, 0.0f, // go round counter-clockwise
+ 1.0f, 0.0f,
+ 1.0f, 1.0f // end at top-right
+};
+// Now we increase the VBO's size again just like we did for the colors.
+// ...
+GLuint vbo[3];
+glGenBuffers(3, vbo);
+// ...
+glDeleteBuffers(3, vbo);
+// ...
+// Load the texture coordinates into the new buffer.
+glBindBuffer(GL_ARRAY_BUFFER, vbo[2]);
+glBufferData(GL_ARRAY_BUFFER, sizeof(texCoords[0]) * texCoords.size(),
+ texCoords.data(), GL_STATIC_DRAW);
+glEnableVertexAttribArray(2);
+glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 0, nullptr);
+// Because the VAO does not store the texture we have to bind it before drawing.
+// ...
+glBindVertexArray(vao);
+glBindTexture(GL_TEXTURE_2D, texture);
+glDrawElements(GL_TRIANGLES, iboData.size(), GL_UNSINGED_INT, nullptr);
+// ...
+```
+
+Change the shaders to pass the data to the fragment shader.<br>
+
+**Vertex Shader**
+
+```glsl
+#version 330 core
+
+layout(location = 0) in vec3 position;
+layout(location = 1) in vec3 color;
+layout(location = 2) in vec2 texCoords;
+
+out vec3 fColor;
+out vec2 fTexCoords;
+
+void main() {
+ fColor = color;
+ fTexCoords = texCoords;
+ gl_Position = vec4(position, 1.0);
+}
+```
+
+**Fragment Shader**
+
+```glsl
+#version 330 core
+// sampler2D represents our 2D texture.
+uniform sampler2D tex;
+uniform float time;
+
+in vec3 fColor;
+in vec2 fTexCoords;
+
+out vec4 outColor;
+
+void main() {
+ // texture() loads the current texure data at the specified texture coords,
+ // then we can simply multiply them by our color.
+ outColor = texture(tex, fTexCoords) * vec4(fColor, 1.0);
+}
+```
+
+You can find the current code here: [OpenGL - 3](https://pastebin.com/u3bcwM6q)
+
+## Matrix Transformation
+
+**Vertex Shader**
+
+```glsl
+#version 330 core
+
+layout(location = 0) in vec3 position;
+layout(location = 1) in vec3 color;
+layout(location = 2) in vec2 texCoords;
+// Create 2 4x4 matricies, 1 for the projection matrix
+// and 1 for the model matrix.
+// Because we draw in a static scene, we don't need a view matrix.
+uniform mat4 projection;
+uniform mat4 model;
+
+out vec3 fColor;
+out vec2 fTexCoords;
+
+void main() {
+ fColor = color;
+ fTexCoords = texCoords;
+ // Multiplay the position by the model matrix and then by the
+ // projection matrix.
+ // Beware order of multiplication for matricies!
+ gl_Position = projection * model * vec4(position, 1.0);
+}
+```
+
+In our source we now need to change the vertex data, create a model- and a projection matrix.
+
+```cpp
+// The new vertex data, counter-clockwise declaration.
+std::vector<float> vertexData {
+ 0.0f, 1.0f, 0.0f, // top left
+ 0.0f, 0.0f, 0.0f, // bottom left
+ 1.0f, 0.0f, 0.0f, // bottom right
+ 1.0f, 1.0f, 0.0f // top right
+};
+// Request the location of our matricies.
+GLint projectionLocation = glGetUniformLocation(program, "projection");
+GLint modelLocation = glGetUniformLocation(program, "model");
+// Declaring the matricies.
+// Orthogonal matrix for a 1024x768 window.
+std::vector<float> projection {
+ 0.001953f, 0.0f, 0.0f, 0.0f,
+ 0.0f, -0.002604f, 0.0f, 0.0f,
+ 0.0f, 0.0f, -1.0f, 0.0f,
+ -1.0f, 1.0f, 0.0f, 1.0f
+};
+// Model matrix translating to x 50, y 50
+// and scaling to x 200, y 200.
+std::vector<float> model {
+ 200.0f, 0.0f, 0.0f, 0.0f,
+ 0.0f, 200.0f, 0.0f, 0.0f,
+ 0.0f, 0.0f, 1.0f, 0.0f,
+ 50.0f, 50.0f, 0.0f, 1.0f
+};
+// Now we can send our calculated matricies to the program.
+glUseProgram(program);
+glUniformMatrix4fv(projectionLocation, // location
+ 1, // count
+ GL_FALSE, // transpose the matrix
+ projection.data()); // data
+glUniformMatrix4fv(modelLocation, 1, GL_FALSE, model.data());
+glUseProgram(0);
+// The glUniform*() calls have to be done, while the program is bound.
+```
+
+The application should now display the texture at the defined position and size.<br>
+You can find the current code here: [OpenGL - 4](https://pastebin.com/9ahpFLkY)
+
+```cpp
+// There are many math librarys for OpenGL, which create
+// matricies and vectors, the most used in C++ is glm (OpenGL Mathematics).
+// Its a header only library.
+// The same code using glm would look like:
+glm::mat4 projection{ glm::ortho(0.0f, 1024.0f, 768.0f, 0.0f) };
+glUniformMatrix4fv(projectionLocation, 1, GL_FALSE,
+ glm::value_ptr(projection));
+// Initialise the model matrix to the identity matrix, otherwise every
+// multiplication would be 0.
+glm::mat4 model{ 1.0f };
+model = glm::translate(model, glm::vec3{ 50.0f, 50.0f, 0.0f });
+model = glm::scale(model, glm::vec3{ 200.0f, 200.0f, 0.0f });
+glUniformMatrix4fv(modelLocation, 1, GL_FALSE,
+ glm::value_ptr(model));
+```
+
+## Geometry Shader
+
+Gemoetry shaders were introduced in OpenGL 3.2, they can produce vertices
+that are send to the rasterizer. They can also change the primitive type e.g.
+they can take a point as an input and output other primitives.
+Geometry shaders are inbetween the vertex and the fragment shader.
+
+**Vertex Shader**
+
+```glsl
+#version 330 core
+
+layout(location = 0) in vec3 position;
+layout(location = 1) in vec3 color;
+// Create an output interface block passed to the next shadaer stage.
+// Interface blocks can be used to structure data passed between shaders.
+out VS_OUT {
+ vec3 color;
+} vs_out;
+
+void main() {
+ vs_out.color = color
+ gl_Position = vec4(position, 1.0);
+}
+```
+
+**Geometry Shader**
+
+```glsl
+#version 330 core
+// The geometry shader takes in points.
+layout(points) in;
+// It outputs a triangle every 3 vertices emitted.
+layout(triangle_strip, max_vertices = 3) out;
+// VS_OUT becomes an input variable in the geometry shader.
+// Every input to the geometry shader in treated as an array.
+in VS_OUT {
+ vec3 color;
+} gs_in[];
+// Output color for the fragment shader.
+// You can also simply define color as 'out vec3 color',
+// If you don't want to use interface blocks.
+out GS_OUT {
+ vec3 color;
+} gs_out;
+
+void main() {
+ // Each emit calls the fragment shader, so we set a color for each vertex.
+ gs_out.color = mix(gs_in[0].color, vec3(1.0, 0.0, 0.0), 0.5);
+ // Move 0.5 units to the left and emit the new vertex.
+ // gl_in[] is the current vertex from the vertex shader, here we only
+ // use 0, because we are receiving points.
+ gl_Position = gl_in[0].gl_Position + vec4(-0.5, 0.0, 0.0, 0.0);
+ EmitVertex();
+ gs_out.color = mix(gs_in[0].color, vec3(0.0, 1.0, 0.0), 0.5);
+ // Move 0.5 units to the right and emit the new vertex.
+ gl_Position = gl_in[0].gl_Position + vec4(0.5, 0.0, 0.0, 0.0);
+ EmitVertex();
+ gs_out.color = mix(gs_in[0].color, vec3(0.0, 0.0, 1.0), 0.5);
+ // Move 0.5 units up and emit the new vertex.
+ gl_Position = gl_in[0].gl_Position + vec4(0.0, 0.75, 0.0, 0.0);
+ EmitVertex();
+ EndPrimitive();
+}
+```
+
+**Fragment Shader**
+
+```glsl
+in GS_OUT {
+ vec3 color;
+} fs_in;
+
+out vec4 outColor;
+
+void main() {
+ outColor = vec4(fs_in.color, 1.0);
+}
+```
+
+If you now store a single point with a single color in a VBO and draw them,
+you should see a triangle, with your color mixed half way between
+red, green and blue on each vertex.
+
+
+## Quotes
+<sup>[1]</sup>[OpenGL - Wikipedia](https://en.wikipedia.org/wiki/OpenGL)
+
+## Books
+
+- OpenGL Superbible - Fifth Edition (covering OpenGL 3.3)
+- OpenGL Programming Guide - Eighth Edition (covering OpenGL 4.3)
diff --git a/p5.html.markdown b/p5.html.markdown
new file mode 100644
index 00000000..be22d3e5
--- /dev/null
+++ b/p5.html.markdown
@@ -0,0 +1,53 @@
+---
+category: tool
+tool: p5
+contributors:
+ - ['Amey Bhavsar', 'https://github.com/ameybhavsar24']
+ - ['Claudio Busatto', 'https://github.com/cjcbusatto']
+filename: p5.js
+---
+
+p5.js is a JavaScript library that starts with the original goal of [Processing](http://processing.org"), to make coding accessible for artists, designers, educators, and beginners, and reinterprets this for today's web.
+Since p5 is a JavaScript library, you should learn [Javascript](https://learnxinyminutes.com/docs/javascript/) first.
+
+```js
+///////////////////////////////////
+// p5.js has two important functions to work with.
+
+function setup() {
+ // the setup function gets executed just once when the window is loaded
+}
+function draw() {
+ // the draw function gets called every single frame. This means that for a frameRate(30) it would get called 30 times per second.
+}
+
+// the following code explains all features
+
+function setup() {
+ createCanvas(640, 480); // creates a new canvas element with 640px as width as 480px as height
+ background(128); // changes the background color of the canvas, can accept rgb values like background(100,200,20) else grayscale values like background(0) = black or background(255) = white
+}
+
+function draw() {
+ ellipse(10, 10, 50, 50); // creates a ellipse at the 10px from the left and 10px from the top with width adn height as 50 each, so its basically a circle.
+ //remember in p5.js the origin is at the top-left corner of the canvas
+
+ if (mouseIsPressed) {
+ // mouseIsPressed is a boolean variable that changes to true if the mouse buttton is pressed down at that instant
+
+ fill(0); // fill refers to the innner color or filling color of whatever shape you are going to draw next
+ } else {
+ fill(255); // you can give in rgb values like fill(72, 240, 80) to get colors, else a single values determines the grayscale where fill(255) stands for #FFF(white) and fill(0) stands for #000(black)
+ }
+
+ ellipse(mouseX, mouseY, 80, 80);
+ // mouseX is the x-coordinate of the mouse's current position and mouseY is the y-coordinate of the mouse's current position
+
+ // the above code creates a circle wherever mouse's current position and fills it either black or white based on the mouseIsPressed
+}
+```
+
+## Further Reading
+
+- [p5.js | get started](http://p5js.org/get-started/) The official documentation
+- [Code! Programming for Beginners with p5.js - YouTube](https://www.youtube.com/watch?v=yPWkPOfnGsw&vl=en) Introduction and Coding challenges using Processing and p5.js by Coding Train
diff --git a/pascal.html.markdown b/pascal.html.markdown
index 28dcc10f..9fb51c3b 100644
--- a/pascal.html.markdown
+++ b/pascal.html.markdown
@@ -66,7 +66,7 @@ program Learn_More;
const
PI = 3.141592654;
- GNU = 'GNU's Not Unix';
+ GNU = 'GNU''s Not Unix';
// constants are conventionally named using CAPS
// their values are fixed and cannot be changed during runtime
// holds any standard data type (integer, real, boolean, char, string)
diff --git a/perl.html.markdown b/perl.html.markdown
index 17a538e3..08001ab0 100644
--- a/perl.html.markdown
+++ b/perl.html.markdown
@@ -152,7 +152,7 @@ while (condition) {
...
}
-
+my $max = 5;
# for loops and iteration
for my $i (0 .. $max) {
print "index is $i";
diff --git a/perl6-pod.html.markdown b/perl6-pod.html.markdown
new file mode 100644
index 00000000..80a501b8
--- /dev/null
+++ b/perl6-pod.html.markdown
@@ -0,0 +1,622 @@
+---
+language: Pod
+contributors:
+ - ["Luis F. Uceta", "https://uzluisf.gitlab.io/"]
+filename: learnpod.pod6
+---
+
+Pod is an easy-to-use and purely descriptive mark-up language,
+with no presentational components. Besides its use for documenting
+Raku Perl 6 programs and modules, Pod can be utilized to write language
+documentation, blogs, and other types of document composition as well.
+
+Pod documents can be easily converted to HTML and many other formats
+(e.g., Markdown, Latex, plain text, etc.) by using the corresponding
+variant of the `Pod::To` modules (e.g. `Pod::To::HTML` for HTML conversion).
+
+- [General Info](#general-info)
+- [Pod Basics](#pod-basics)
+ - [Basic Text Formatting](#basic-text-formatting)
+ - [Headings](#headings)
+ - [Ordinary Paragraphs](#ordinary-paragraphs)
+ - [Lists](#lists)
+ - [Code Blocks](#code-blocks)
+ - [Comments](#comments)
+ - [Links](#links)
+ - [Tables](#tables)
+- [Block Structures](#block-structures)
+ - [Abbreviated Blocks](#abbreviated-blocks)
+ - [Delimited Blocks](#delimited-blocks)
+ - [Paragraph Blocks](#paragraph-blocks)
+- [Configuration Data](#configuration-data)
+ - [Standard Configuration Options](#standard-configuration-options)
+ - [Block Pre-configuration](#block-pre-configuration)
+- [Semantic Blocks](#semantic-blocks)
+- [Miscellaneous](#miscellaneous)
+ - [Notes](#notes)
+ - [Keyboard Input](#keyboard-input)
+ - [Terminal Output](#terminal-output)
+ - [Unicode](#unicode)
+- [Rendering Pod](#rendering-pod)
+- [Accessing Pod](#accessing-pod)
+
+## General Info
+
+Every Pod document has to begin with `=begin pod` and end with `=end pod`.
+Everything between these two delimiters will be processed and used to
+generate documentation.
+
+```
+=begin pod
+
+A very simple Raku Perl 6 Pod document. All the other directives go here!
+
+=end pod
+```
+
+Pod documents usually coexist with Raku Perl 6 code. If by themselves,
+Pod files often have the `.pod6` suffix. Moving forward, it's assumed that
+the constructs being discussed are surrounded by the `=begin pod ... =end pod`
+directives.
+
+## Pod Basics
+
+### Basic Text Formatting
+
+Text can be easily styled as bold, italic, underlined or verbatim (for code
+formatting) using the following formatting codes: `B<>`, `I<>`, `U<>`
+and `C<>`.
+
+```
+B<This text is in Bold.>
+
+I<This text is in Italics.>
+
+U<This text is Underlined.>
+
+The function C<sub sum { $^x + $^y}> is treated as verbatim.
+```
+
+There are more formatting codes (e.g., `L<>`, `T<>`, etc.) but they'll be
+discussed later throughout the document. You'll recognize them because they're
+just a single capital letter followed immediately by a set of single or double
+angle brackets. The Unicode variant («») of the angle brackets can also be
+used.
+
+### Headings
+
+Headings are created by using the `=headN` directive where `N` is the
+heading level.
+
+```
+=head1 This is level 1
+=head2 This is level 2
+=head3 This is level 3
+=head4 This is level 4
+=head5 This is level 5
+=head6 This is level 6
+```
+
+### Ordinary Paragraphs
+
+Ordinary paragraphs consist of one or more adjacent lines of text, each of
+which starts with a non-whitespace character. Any paragraph is terminated
+by the first blank line or block directive.
+
+```
+=head1 First level heading block
+
+=head2 Paragraph 1
+
+This is an ordinary paragraph. Its text will be squeezed and
+short lines filled. It is terminated by the first blank line.
+
+=head2 Paragraph 2
+
+This is another ordinary paragraph albeit shorter.
+```
+
+Alternatively, the `=para` directive can be used to explicitly mark adjacent
+lines of text as a paragraph.
+
+```
+=head1 First level heading block
+
+=head2 Paragraph 1
+
+=para
+This is an ordinary paragraph. Its text will be squeezed and
+short lines filled. It is terminated by the first blank line.
+
+=head2 Paragraph 2
+
+=para
+This is another ordinary paragraph albeit shorter.
+```
+
+### Lists
+
+Unordered lists can be created using the `=item` directive.
+
+```
+=item Item
+=item Item
+=item Another item
+```
+
+Sublists are achieved with items at each level specified using the `=item1`,
+`=item2`, `=item3`, `...`, `=itemN` etc. directives. The `=item` directive
+defaults to `=item1`.
+
+```
+=item1 Item one
+=item1 Item two
+=item1 Item three
+ =item2 Sub-item
+ =item2 Sub-item
+=item1 Item four
+```
+
+Definition lists that define terms or commands use the `=defn` directive.
+This is equivalent to the `<dl>` element in HTML.
+
+```
+=defn Beast of Bodmin
+A large feline inhabiting Bodmin Moor.
+
+=defn Morgawr
+A sea serpent.
+
+=defn Owlman
+A giant owl-like creature.
+```
+
+### Code Blocks
+
+A code block is created (which uses the HTML `<code>` element) by starting each
+line with one or more whitespace characters.
+
+```
+ #`( this is comment )
+ my $sum = -> $x, $y { $x + $y }
+ say $sum(12, 5);
+```
+
+As shown in the [Basic Text Formatting](#basic-text-formatting) section,
+inline code can be created using the `C<>` code.
+
+```
+In Raku Perl 6, there are several functions/methods to output text. Some of them
+are C<print>, C<put> and C<say>.
+```
+
+### Comments
+
+Although Pod blocks are ignored by the Raku Perl 6 compiler, everything
+indentified as a Pod block will be read and interpreted by Pod renderers. In
+order to prevent Pod blocks from being rendered by any renderer, use the
+`=comment` directive.
+
+```
+=comment Add more here about the algorithm.
+
+=comment Pod comments are great for documenting the documentation.
+```
+
+To create inline comments, use the `Z<>` code.
+
+```
+Pod is awesome Z<Of course it is!>. And Raku Perl 6 too!
+```
+
+Given that the Perl interpreter never executes embedded Pod blocks,
+comment blocks can also be used as an alternative form of nestable block
+comments in Raku Perl 6.
+
+### Links
+
+Creating links in Pod is quite easy and is done by enclosing them in
+a `L<>` code. The general format is `L<Label|Url>` with `Label`
+being optional.
+
+```
+Raku Perl 6 homepage is L<https://perl6.org>.
+L<Click me!|http://link.org/>.
+```
+
+Relative paths work too.
+
+```
+L<Go to music|/music/>.
+```
+
+Linking to a section in the same document works as well.
+
+```
+L<Link to Headings|#Headings>
+```
+
+### Tables
+
+The Pod specifications are not completely handled properly yet and this
+includes the handling of table. For simplicity's sake, only one way of
+constructing tables is shown here. To learn about good practices and see
+examples of both good and bad tables, please visit
+<https://docs.perl6.org/language/tables>.
+
+```
+=begin table
+Option | Description
+============|================
+data | path to data files.
+engine | engine to be used for processing templates.
+ext | extension to be used for dest files.
+=end table
+```
+
+## Block Structures
+
+As mentioned earlier, Pod documents are specified using directives, which are
+used to delimit blocks of textual content and declare optional
+[configuration information](#configuration-data). Every directive starts with
+an equals sign (`=`) in the first column. The content of a document is
+specified within one or more blocks. Every Pod block may be declared in any of
+three equivalent forms: delimited style, paragraph style, or abbreviated style.
+
+Up to this point, we have only used the abbreviated style for the block
+types (e.g., `=head1`, `=para`, `=comment`, `=item`, etc).
+
+### Abbreviated Blocks
+
+Abbreviated blocks are introduced by an `=` sign in the first column, which
+is followed immediately by the `typename` of the block and then the content.
+The rest of the line is treated as block data, rather than as configuration.
+The content terminates at the next Pod directive or the first blank line
+(which is not part of the block data). The general syntax is
+
+```
+=BLOCK_TYPE BLOCK_DATA
+```
+For example:
+
+```
+=head1 Top level heading
+```
+
+### Delimited Blocks
+
+Delimited blocks are bounded by `=begin` and `=end` markers, both of which are
+followed by a valid Pod identifier, which is the `typename` of the block.
+The general syntax is
+
+```
+=begin BLOCK_TYPE
+BLOCK_DATA
+=end BLOCK_TYPE
+```
+
+For example:
+
+```
+=begin head1
+Top level heading
+=end head1
+```
+
+This type of blocks is useful for creating headings, list items, code blocks,
+etc. with multiple paragraphs. For example,
+
+* a multiline item of a list
+
+```
+=begin item
+This is a paragraph in list item.
+
+This is another paragraph in the same list item.
+=end item
+```
+
+* a code block
+
+```
+=begin code
+#`(
+A non-efficient recursive implementation of a power function using multi subs.
+)
+
+multi pow( Real $base, 0 ) { 1 }
+
+multi pow( Real $base, Int $exp where * ≥ 0) {
+ $base * pow($base, $exp - 1)
+}
+
+multi pow( Real $base ) {
+ pow($base, 2)
+}
+
+say pow(3, 0); #=> 1
+say pow(4.2, 2); #=> 17.64
+say pow(6); #=> 36
+=end code
+```
+
+### Paragraph Blocks
+
+Paragraph blocks are introduced by a `=for` marker and terminated by
+the next Pod directive or the first blank line (which is not considered to
+be part of the block's contents). The `=for` marker is followed by the
+`typename` of the block. The general syntax is
+
+```
+=for BLOCK_TYPE
+BLOCK DATA
+```
+
+For example:
+
+```
+=for head1
+Top level heading
+```
+
+## Configuration Data
+
+Except for abbreviated blocks, both delimited blocks and paragraph
+blocks can be supplied with configuration information about their
+contents right after the `typename` of the block. Thus the following
+are more general syntaxes for these blocks:
+
+* Delimited blocks
+
+```
+=begin BLOCK_TYPE OPTIONAL_CONFIG_INFO
+= ADDITIONAL_CONFIG_INFO
+BLOCK_DATA
+=end BLOCK_TYPE
+```
+
+* Paragraph blocks
+
+```
+=for BLOCK_TYPE OPTIONAL_CONFIG_INFO
+= ADDITIONAL_CONFIG_INFO
+BLOCK DATA
+```
+
+The configuration information is provided in a format akin to the
+["colon pair"](https://docs.perl6.org/language/glossary#index-entry-Colon_Pair)
+syntax in Raku Perl 6. The following table is a simplified version of the
+different ways in which configuration info can be supplied. Please go to
+<https://docs.perl6.org/language/pod#Configuration_information> for a more
+thorough treatment of the subject.
+
+| Value | Specify with... | Example |
+| :-------- | :------ | :------ |
+| List | :key($elem1, $elem2, ...) | :tags('Pod', 'Perl6') |
+| Hash | :key{$key1 => $value1, ...} | :feeds{url => 'perl6.org'} |
+| Boolean | :key/:key(True) | :skip-test(True) |
+| Boolean | :!key/:key(False) | :!skip-test |
+| String | :key('string') | :nonexec-reason('SyntaxError') |
+| Int | :key(2) | :post-number(6) |
+
+
+### Standard Configuration Options
+
+Pod provides a small number of standard configuration options that can
+be applied uniformly to built-in block types. Some of them are:
+
+* `:numbered`
+
+This option specifies that the block is to be numbered. The most common
+use of this option is to create numbered headings and ordered lists, but it
+can be applied to any block.
+
+For example:
+
+```
+=for head1 :numbered
+The Problem
+=for head1 :numbered
+The Solution
+=for head2 :numbered
+Analysis
+=for head3 :numbered
+Overview
+```
+
+* `:allow`
+
+The value of the `:allow` option must be a list of the (single-letter) names
+of one or more formatting codes. Those codes will then remain active inside
+the code block. The option is most often used on `=code` blocks to allow
+mark-up within those otherwise verbatim blocks, though it can be used in any
+block that contains verbatim text.
+
+Given the following snippet:
+
+```
+=begin code :allow('B', 'I')
+B<sub> greet( $name ) {
+ B<say> "Hello, $nameI<!>";
+}
+=end code
+```
+
+we get the following output:
+
+<pre><strong>sub</strong> greet( $name ) {
+ <strong>say</strong> &quot;Hello, $name<em>!</em>&quot;;
+}
+</pre>
+
+This is highly dependent on the format output. For example, while this works
+when Pod is converted to HTML, it might not be preserved when converted
+to Markdown.
+
+### Block Pre-configuration
+
+The `=config` directive allows you to prespecify standard configuration
+information that is applied to every block of a particular type.
+The general syntax for configuration directives is:
+
+```
+=config BLOCK_TYPE CONFIG OPTIONS
+= ADDITIONAL_CONFIG_INFO
+```
+
+For example, to specify that every heading level 1 be numbered, bold
+and underlined, you preconfigure the `=head1` as follows:
+
+```
+=config head1 :formatted('B', 'U') :numbered
+```
+
+## Semantic Blocks
+
+All uppercase block typenames are reserved for specifying standard
+documentation, publishing, source components, or meta-information.
+Some of them are:
+
+```
+=NAME
+=AUTHOR
+=VERSION
+=CREATED
+=SYNOPSIS
+=DESCRIPTION
+=USAGE
+```
+
+Most of these blocks would typically be used in their full
+delimited forms. For example,
+
+```
+=NAME B<Doc::Magic>
+
+=begin DESCRIPTION
+This module helps you generate documentation automagically.
+Not source code needed! Most of it is outsourced from a black hole.
+=end DESCRIPTION
+
+=begin SYNOPSIS
+=begin code
+ use Doc::Magic;
+
+ my Doc::Magic $doc .= new();
+
+ my $result = $doc.create-documentation($fh);
+=end code
+=end SYNOPSIS
+
+=AUTHOR Authorius Docus
+=VERSION 42
+```
+
+## Miscellaneous
+
+### Notes
+
+Notes are rendered as footnotes and created by enclosing a note in a
+`N<>` code.
+
+```
+In addition, the language is also multi-paradigmatic N<According to Wikipedia,
+this means that it supports procedural, object-oriented, and functional
+programming.>
+```
+
+### Keyboard Input
+
+To flag text as keyboard input enclose it in a `K<>` code.
+
+```
+Enter your name K<John Doe>
+```
+
+### Terminal Output
+
+To flag text as terminal output enclose it in `T<>` code.
+
+```
+Hello, T<John Doe>
+```
+
+### Unicode
+
+To include Unicode code points or HTML5 character references in
+a Pod document, enclose them in a `E<>` code.
+
+For example:
+
+```
+Raku Perl 6 makes considerable use of the E<171> and E<187> characters.
+Raku Perl 6 makes considerable use of the E<laquo> and E<raquo> characters.
+```
+
+is rendered as:
+
+Raku Perl 6 makes considerable use of the « and » characters.
+Raku Perl 6 makes considerable use of the « and » characters.
+
+## Rendering Pod
+
+To generate any output (i.e., Markdown, HTML, Text, etc.), you need to
+have the Raku Perl 6 compiler installed. In addition, you must install
+a module (e.g., `Pod::To::Markdown`, `Pod::To::HTML`, `Pod::To::Text`, etc.)
+that generates your desired output from Pod.
+
+For instructions about installing Raku Perl 6,
+[look here](https://perl6.org/downloads/).
+
+Run the following command to generate a certain output:
+
+```
+perl6 --doc=TARGET input.pod6 > output.html
+```
+
+with `TARGET` being `Markdown`, `HTML`, `Text`, etc. Thus to generate
+Markdown from Pod, run this:
+
+```
+perl6 --doc=Markdown input.pod6 > output.html
+```
+
+## Accessing Pod
+
+In order to access Pod documentation from within a Raku Perl 6 program,
+it is required to use the special `=` twigil (e.g., `$=pod`, `$=SYNOPSIS`,etc).
+
+The `$=` construct provides the introspection over the Pod structure,
+producing a `Pod::Block` tree root from which it is possible to access
+the whole structure of the Pod document.
+
+If we place the following piece of Raku Perl 6 code and the Pod documentation
+in the section [Semantic blocks](#semantic-blocks) in the same file:
+
+```
+my %used-directives;
+for $=pod -> $pod-item {
+ for $pod-item.contents -> $pod-block {
+ next unless $pod-block ~~ Pod::Block::Named;
+ %used-directives{$pod-block.name} = True;
+ }
+}
+
+say %used-directives.keys.join("\n");
+```
+
+we get the following output:
+
+```
+SYNOPSIS
+NAME
+VERSION
+AUTHOR
+DESCRIPTION
+```
+
+## Additional Information
+
+* <https://docs.perl6.org/language/pod> for the Pod documentation.
+* <https://docs.perl6.org/language/tables> for advices about Pod tables.
+* <https://design.perl6.org/S26.html> for the Pod specification.
diff --git a/perl6.html.markdown b/perl6.html.markdown
index 04f9c6e3..1304869b 100644
--- a/perl6.html.markdown
+++ b/perl6.html.markdown
@@ -13,24 +13,28 @@ least the next hundred years.
The primary Perl 6 compiler is called [Rakudo](http://rakudo.org), which runs on
the JVM and [the MoarVM](http://moarvm.com).
-Meta-note : double pound signs (##) are used to indicate paragraphs, while
-single pound signs (#) indicate notes.
+Meta-note: double pound signs (`##`) are used to indicate paragraphs,
+while single pound signs (`#`) indicate notes.
`#=>` represents the output of a command.
```perl6
-# Single line comment start with a pound
+# Single line comments start with a pound sign.
-#`(
- Multiline comments use #` and a quoting construct.
+#`( Multiline comments use #` and a quoting construct.
(), [], {}, 「」, etc, will work.
)
+
+# Use the same syntax for multiline comments to embed comments.
+for #`(each element in) @array {
+ put #`(or print element) $_ #`(with newline);
+}
```
## Variables
```perl6
-## In Perl 6, you declare a lexical variable using `my`
+## In Perl 6, you declare a lexical variable using the `my` keyword:
my $variable;
## Perl 6 has 3 basic types of variables: scalars, arrays, and hashes.
```
@@ -38,79 +42,81 @@ my $variable;
### Scalars
```perl6
-# Scalars represent a single value. They start with a `$`
-
+# Scalars represent a single value. They start with the `$` sigil:
my $str = 'String';
-# double quotes allow for interpolation (which we'll see later):
+
+# Double quotes allow for interpolation (which we'll see later):
my $str2 = "String";
## Variable names can contain but not end with simple quotes and dashes,
-## and can contain (and end with) underscores :
-my $weird'variable-name_ = 5; # works !
+## and can contain (and end with) underscores:
+my $person's-belongings = 'towel'; # this works!
-my $bool = True; # `True` and `False` are Perl 6's boolean values.
-my $inverse = !$bool; # You can invert a bool with the prefix `!` operator
-my $forced-bool = so $str; # And you can use the prefix `so` operator
- # which turns its operand into a Bool
+my $bool = True; # `True` and `False` are Perl 6's boolean values.
+my $inverse = !$bool; # Invert a bool with the prefix `!` operator.
+my $forced-bool = so $str; # And you can use the prefix `so` operator
+$forced-bool = ?$str; # to turn its operand into a Bool. Or use `?`.
```
### Arrays and Lists
```perl6
-## Arrays represent multiple values. Their name start with `@`.
-## Lists are similar but are an immutable type.
+## Arrays represent multiple values. An array variable starts with the `@`
+## sigil. Unlike lists, from which arrays inherit, arrays are mutable.
my @array = 'a', 'b', 'c';
-# equivalent to :
+# equivalent to:
my @letters = <a b c>; # array of words, delimited by space.
# Similar to perl5's qw, or Ruby's %w.
-my @array = 1, 2, 3;
+@array = 1, 2, 3;
-say @array[2]; # Array indices start at 0 -- This is the third element
+say @array[2]; # Array indices start at 0. Here the third element
+ # is being accessed.
-say "Interpolate all elements of an array using [] : @array[]";
-#=> Interpolate all elements of an array using [] : 1 2 3
+say "Interpolate an array using []: @array[]";
+#=> Interpolate an array using []: 1 2 3
-@array[0] = -1; # Assign a new value to an array index
-@array[0, 1] = 5, 6; # Assign multiple values
+@array[0] = -1; # Assigning a new value to an array index
+@array[0, 1] = 5, 6; # Assigning multiple values
my @keys = 0, 2;
@array[@keys] = @letters; # Assignment using an array containing index values
-say @array; #=> a 6 b
+say @array; #=> a 6 b
```
### Hashes, or key-value Pairs.
```perl6
-## Hashes are pairs of keys and values.
-## You can construct a Pair object using the syntax `Key => Value`.
-## Hash tables are very fast for lookup, and are stored unordered.
-## Keep in mind that keys get "flattened" in hash context, and any duplicated
-## keys are deduplicated.
-my %hash = 1 => 2,
- 3 => 4;
-my %hash = foo => "bar", # keys get auto-quoted
- "some other" => "value", # trailing commas are okay
- ;
+## Hashes are pairs of keys and values. You can construct a `Pair` object
+## using the syntax `Key => Value`. Hash tables are very fast for lookup,
+## and are stored unordered. Keep in mind that keys get "flattened" in hash
+## context, and any duplicated keys are deduplicated.
+my %hash = 'a' => 1, 'b' => 2;
+
+%hash = a => 1, # keys get auto-quoted when => (fat comma) is used.
+ b => 2, # Trailing commas are okay.
+;
## Even though hashes are internally stored differently than arrays,
## Perl 6 allows you to easily create a hash from an even numbered array:
-my %hash = <key1 value1 key2 value2>;
-
-my %hash = key1 => 'value1', key2 => 'value2'; # same result as above
-
-## You can also use the "colon pair" syntax:
-## (especially handy for named parameters that you'll see later)
-my %hash = :w(1), # equivalent to `w => 1`
- # this is useful for the `True` shortcut:
- :truey, # equivalent to `:truey(True)`, or `truey => True`
- # and for the `False` one:
- :!falsey, # equivalent to `:falsey(False)`, or `falsey => False`
- ;
-
-say %hash{'key1'}; # You can use {} to get the value from a key
-say %hash<key2>; # If it's a string, you can actually use <>
- # (`{key1}` doesn't work, as Perl6 doesn't have barewords)
+%hash = <key1 value1 key2 value2>; # Or:
+%hash = "key1", "value1", "key2", "value2";
+
+%hash = key1 => 'value1', key2 => 'value2'; # same result as above
+
+## You can also use the "colon pair" syntax. This syntax is especially
+## handy for named parameters that you'll see later.
+%hash = :w(1), # equivalent to `w => 1`
+ :truey, # equivalent to `:truey(True)` or `truey => True`
+ :!falsey, # equivalent to `:falsey(False)` or `falsey => False`
+;
+## The :truey and :!falsey constructs are known as the
+## `True` and `False` shortcuts respectively.
+
+say %hash{'key1'}; # You can use {} to get the value from a key.
+say %hash<key2>; # If it's a string without spaces, you can actually use
+ # <> (quote-words operator). `{key1}` doesn't work,
+ # as Perl6 doesn't have barewords.
```
## Subs
@@ -120,112 +126,112 @@ say %hash<key2>; # If it's a string, you can actually use <>
## created with the `sub` keyword.
sub say-hello { say "Hello, world" }
-## You can provide (typed) arguments.
-## If specified, the type will be checked at compile-time if possible,
-## otherwise at runtime.
-sub say-hello-to(Str $name) {
+## You can provide (typed) arguments. If specified, the type will be checked
+## at compile-time if possible, otherwise at runtime.
+sub say-hello-to( Str $name ) {
say "Hello, $name !";
}
-## A sub returns the last value of the block.
-sub return-value {
- 5;
-}
-say return-value; # prints 5
-sub return-empty {
-}
-say return-empty; # prints Nil
+## A sub returns the last value of the block. Similarly, the semicolon in
+## the last can be omitted.
+sub return-value { 5 }
+say return-value; # prints 5
-## Some control flow structures produce a value, like if:
+sub return-empty { }
+say return-empty; # prints Nil
+
+## Some control flow structures produce a value, like `if`:
sub return-if {
- if True {
- "Truthy";
- }
+ if True { "Truthy" }
}
-say return-if; # prints Truthy
+say return-if; # prints Truthy
-## Some don't, like for:
+## Some don't, like `for`:
sub return-for {
- for 1, 2, 3 { }
+ for 1, 2, 3 { 'Hi' }
}
-say return-for; # prints Nil
+say return-for; # prints Nil
-## A sub can have optional arguments:
-sub with-optional($arg?) { # the "?" marks the argument optional
- say "I might return `(Any)` (Perl's 'null'-like value) if I don't have
- an argument passed, or I'll return my argument";
+## Positional arguments are required by default. To make them optional, use
+## the `?` after the parameters' names.
+sub with-optional( $arg? ) {
+ # This sub returns `(Any)` (Perl's null-like value) if
+ # no argument is passed. Otherwise, it returns its argument.
$arg;
}
-with-optional; # returns Any
-with-optional(); # returns Any
-with-optional(1); # returns 1
+with-optional; # returns Any
+with-optional(); # returns Any
+with-optional(1); # returns 1
-## You can also give them a default value when they're not passed:
-sub hello-to($name = "World") {
- say "Hello, $name !";
+## You can also give them a default value when they're not passed.
+## Required parameters must come before optional ones.
+sub greeting( $name, $type = "Hello" ) {
+ say "$type, $name!";
}
-hello-to; #=> Hello, World !
-hello-to(); #=> Hello, World !
-hello-to('You'); #=> Hello, You !
+
+greeting("Althea"); #=> Hello, Althea!
+greeting("Arthur", "Good morning"); #=> Good morning, Arthur!
## You can also, by using a syntax akin to the one of hashes
-## (yay unified syntax !), pass *named* arguments to a `sub`.
-## They're optional, and will default to "Any".
-sub with-named($normal-arg, :$named) {
- say $normal-arg + $named;
+## (yay unified syntax !), pass *named* arguments to a `sub`. They're
+## optional, and will default to "Any".
+sub with-named( $normal-arg, :$named ) {
+ say $normal-arg + $named;
}
with-named(1, named => 6); #=> 7
-## There's one gotcha to be aware of, here:
-## If you quote your key, Perl 6 won't be able to see it at compile time,
-## and you'll have a single Pair object as a positional parameter,
-## which means this fails:
-with-named(1, 'named' => 6);
-with-named(2, :named(5)); #=> 7
+## There's one gotcha to be aware of, here: If you quote your key, Perl 6
+## won't be able to see it at compile time, and you'll have a single `Pair`
+## object as a positional parameter, which means
+## `with-named(1, 'named' => 6);` fails.
+
+with-named(2, :named(5)); #=> 7
-## To make a named argument mandatory, you can use `?`'s inverse, `!`
-sub with-mandatory-named(:$str!) {
- say "$str !";
+## To make a named argument mandatory, you can append `!` to the parameter,
+## which is the inverse of `?`:
+sub with-mandatory-named( :$str! ) {
+ say "$str!";
}
-with-mandatory-named(str => "My String"); #=> My String !
-with-mandatory-named; # run time error: "Required named parameter not passed"
-with-mandatory-named(3);# run time error:"Too many positional parameters passed"
+with-mandatory-named(str => "My String"); #=> My String!
+with-mandatory-named; # runtime error:"Required named parameter not passed"
+with-mandatory-named(3);# runtime error:"Too many positional parameters passed"
-## If a sub takes a named boolean argument ...
-sub takes-a-bool($name, :$bool) {
- say "$name takes $bool";
+## If a sub takes a named boolean argument...
+sub takes-a-bool( $name, :$bool ) {
+ say "$name takes $bool";
}
## ... you can use the same "short boolean" hash syntax:
-takes-a-bool('config', :bool); # config takes True
-takes-a-bool('config', :!bool); # config takes False
+takes-a-bool('config', :bool); #=> config takes True
+takes-a-bool('config', :!bool); #=> config takes False
-## You can also provide your named arguments with defaults:
-sub named-def(:$def = 5) {
- say $def;
+## You can also provide your named arguments with default values:
+sub named-def( :$def = 5 ) {
+ say $def;
}
-named-def; #=> 5
+named-def; #=> 5
named-def(def => 15); #=> 15
## Since you can omit parenthesis to call a function with no arguments,
-## you need "&" in the name to store `say-hello` in a variable.
+## you need `&` in the name to store `say-hello` in a variable. This means
+## `&say-hello` is a code object and not a subroutine call.
my &s = &say-hello;
-my &other-s = sub { say "Anonymous function !" }
+my &other-s = sub { say "Anonymous function!" }
-## A sub can have a "slurpy" parameter, or "doesn't-matter-how-many"
-sub as-many($head, *@rest) { #`*@` (slurpy) will "take everything else"
-## Note: you can have parameters *before* a slurpy one (like here),
-## but not *after*.
- say @rest.join(' / ') ~ " !";
+## A sub can have a "slurpy" parameter, or "doesn't-matter-how-many". For
+## this, you must use `*@` (slurpy) which will "take everything else". You can
+## have as many parameters *before* a slurpy one, but not *after*.
+sub as-many($head, *@rest) {
+ say @rest.join(' / ') ~ " !";
}
-say as-many('Happy', 'Happy', 'Birthday'); #=> Happy / Birthday !
- # Note that the splat (the *) did not
- # consume the parameter before.
+say as-many('Happy', 'Happy', 'Birthday');#=> Happy / Birthday !
+ # Note that the splat (the *) did not
+ # consume the parameter before it.
-## You can call a function with an array using the
-## "argument list flattening" operator `|`
-## (it's not actually the only role of this operator, but it's one of them)
+## You can call a function with an array using the "argument list flattening"
+## operator `|` (it's not actually the only role of this operator,
+## but it's one of them).
sub concat3($a, $b, $c) {
- say "$a, $b, $c";
+ say "$a, $b, $c";
}
concat3(|@array); #=> a, b, c
# `@array` got "flattened" as a part of the argument list
@@ -234,159 +240,189 @@ concat3(|@array); #=> a, b, c
## Containers
```perl6
-## In Perl 6, values are actually stored in "containers".
-## The assignment operator asks the container on the left to store the value on
-## its right. When passed around, containers are marked as immutable.
-## Which means that, in a function, you'll get an error if you try to
-## mutate one of your arguments.
-## If you really need to, you can ask for a mutable container using `is rw`:
-sub mutate($n is rw) {
- $n++;
- say "\$n is now $n !";
+## In Perl 6, values are actually stored in "containers". The assignment
+## operator asks the container on the left to store the value on its right.
+## When passed around, containers are marked as immutable which means that,
+## in a function, you'll get an error if you try to mutate one of your
+## arguments. If you really need to, you can ask for a mutable container by
+## using the `is rw` trait:
+sub mutate( $n is rw ) {
+ $n++; # postfix ++ operator increments its argument but returns its old value
}
my $m = 42;
-mutate $m; # $n is now 43 !
+mutate $m; # the value is incremented but the old value is returned
+ #=> 42
+say $m; #=> 43
-## This works because we are passing the container $m to mutate. If we try
-## to just pass a number instead of passing a variable it won't work because
-## there is no container being passed and integers are immutable by themselves:
+## This works because we are passing the container $m to the `mutate` sub.
+## If we try to just pass a number instead of passing a variable it won't work
+## because there is no container being passed and integers are immutable by
+## themselves:
mutate 42; # Parameter '$n' expected a writable container, but got Int value
-## If what you want a copy instead, use `is copy`.
+## Similar error would be obtained, if a bound variable is passed to
+## to the subroutine:
+
+my $v := 50; # binding 50 to the variable $v
+mutate $v; # Parameter '$n' expected a writable container, but got Int value
+
+## If what you want is a copy instead, use the `is copy` trait which will
+## cause the argument to be copied and allow you to modify the argument
+## inside the routine.
## A sub itself returns a container, which means it can be marked as rw:
my $x = 42;
sub x-store() is rw { $x }
x-store() = 52; # in this case, the parentheses are mandatory
# (else Perl 6 thinks `x-store` is an identifier)
-say $x; #=> 52
+say $x; #=> 52
```
## Control Flow Structures
+
### Conditionals
```perl6
## - `if`
## Before talking about `if`, we need to know which values are "Truthy"
-## (represent True), and which are "Falsey" (or "Falsy") -- represent False.
-## Only these values are Falsey: 0, (), {}, "", Nil, A type (like `Str` or
-## `Int`) and of course False itself.
-## Every other value is Truthy.
+## (represent True), and which are "Falsey" (represent False). Only these
+## values are Falsey: 0, (), {}, "", Nil, A type (like `Str` or `Int`) and
+## of course False itself. Any other value is Truthy.
if True {
- say "It's true !";
+ say "It's true!";
}
unless False {
- say "It's not false !";
+ say "It's not false!";
}
-## As you can see, you don't need parentheses around conditions.
-## However, you do need the brackets around the "body" block:
-# if (true) say; # This doesn't work !
+## As you can see, you don't need parentheses around conditions. However, you
+## do need the curly braces around the "body" block. For example,
+## `if (true) say;` doesn't work.
-## You can also use their postfix versions, with the keyword after:
-say "Quite truthy" if True;
+## You can also use their statement modifier (postfix) versions:
+say "Quite truthy" if True; #=> Quite truthy
+say "Quite falsey" unless False; #=> Quite falsey
-## - Ternary conditional, "?? !!" (like `x ? y : z` in some other languages)
-## returns $value-if-true if the condition is true and $value-if-false
-## if it is false.
-## my $result = $value condition ?? $value-if-true !! $value-if-false;
+## - Ternary operator, "x ?? y !! z"
+## This returns $value-if-true if the condition is true and $value-if-false
+## if it is false.
+## my $result = condition ?? $value-if-true !! $value-if-false;
my $age = 30;
say $age > 18 ?? "You are an adult" !! "You are under 18";
+#=> You are an adult
```
-### given/when, or switch
+### given/when, or Perl 6's switch construct
```perl6
-## - `given`-`when` looks like other languages' `switch`, but is much more
+## `given...when` looks like other languages' `switch`, but is much more
## powerful thanks to smart matching and Perl 6's "topic variable", $_.
##
-## This variable contains the default argument of a block,
-## a loop's current iteration (unless explicitly named), etc.
+## The topic variable $_ contains the default argument of a block, a loop's
+## current iteration (unless explicitly named), etc.
##
## `given` simply puts its argument into `$_` (like a block would do),
## and `when` compares it using the "smart matching" (`~~`) operator.
##
## Since other Perl 6 constructs use this variable (as said before, like `for`,
-## blocks, etc), this means the powerful `when` is not only applicable along
+## blocks, etc), this means the powerful `when` is not only applicable along
## with a `given`, but instead anywhere a `$_` exists.
given "foo bar" {
- say $_; #=> foo bar
- when /foo/ { # Don't worry about smart matching yet – just know `when` uses it
- # This is equivalent to `if $_ ~~ /foo/`.
- say "Yay !";
- }
- when $_.chars > 50 { # smart matching anything with True is True,
- # i.e. (`$a ~~ True`)
- # so you can also put "normal" conditionals.
- # This `when` is equivalent to this `if`:
- # if $_ ~~ ($_.chars > 50) {...}
- # Which means:
- # if $_.chars > 50 {...}
- say "Quite a long string !";
- }
- default { # same as `when *` (using the Whatever Star)
- say "Something else"
- }
+ say $_; #=> foo bar
+ when /foo/ { # Don't worry about smart matching yet. Just know
+ say "Yay !"; # `when` uses it. This is equivalent to `if $_ ~~ /foo/`.
+
+ }
+ when $_.chars > 50 { # smart matching anything with True is True,
+ # i.e. (`$a ~~ True`)
+ # so you can also put "normal" conditionals.
+ # This `when` is equivalent to this `if`:
+ # `if $_ ~~ ($_.chars > 50) {...}`
+ # which means: `if $_.chars > 50 {...}`
+ say "Quite a long string !";
+ }
+ default { # same as `when *` (using the Whatever Star)
+ say "Something else"
+ }
}
```
### Looping constructs
```perl6
-## - `loop` is an infinite loop if you don't pass it arguments,
-## but can also be a C-style `for` loop:
+## - `loop` is an infinite loop if you don't pass it arguments, but can also
+## be a C-style `for` loop:
loop {
- say "This is an infinite loop !";
- last; # last breaks out of the loop, like the `break` keyword in other
- # languages
+ say "This is an infinite loop !";
+ last; # last breaks out of the loop, like
+ # the `break` keyword in other languages
}
loop (my $i = 0; $i < 5; $i++) {
- next if $i == 3; # `next` skips to the next iteration, like `continue`
+ next if $i == 3; # `next` skips to the next iteration, like `continue`
# in other languages. Note that you can also use postfix
# conditionals, loops, etc.
- say "This is a C-style for loop !";
+ say "This is a C-style for loop!";
}
-## - `for` - Passes through an array
+## - `for` - Iterating through an array
+
+my @array = 1, 2, 6, 7, 3;
+
+## Accessing the array's elements with the topic variable $_.
+for @array {
+ say "I've got $_ !";
+}
+
+## Accessing the array's elements with a "pointy block", `->`.
+## Here each element is read-only.
for @array -> $variable {
- say "I've got $variable !";
+ say "I've got $variable !";
}
-## As we saw with given, for's default "current iteration" variable is `$_`.
-## That means you can use `when` in a `for` just like you were in a `given`.
+## Accessing the array's elements with a "doubly pointy block", `<->`.
+## Here each element is read-write so mutating `$variable` mutates
+## that element in the array.
+for @array <-> $variable {
+ say "I've got $variable !";
+}
+
+## As we saw with given, a for loop's default "current iteration" variable
+## is `$_`. That means you can use `when` in a `for`loop just like you were
+## able to in a `given`.
for @array {
- say "I've got $_";
+ say "I've got $_";
- .say; # This is also allowed.
- # A dot call with no "topic" (receiver) is sent to `$_` by default
- $_.say; # the above and this are equivalent.
+ .say; # This is also allowed. A dot call with no "topic" (receiver)
+ # is sent to `$_` by default
+ $_.say; # This is equivalent to the above statement.
}
for @array {
- # You can...
- next if $_ == 3; # Skip to the next iteration (`continue` in C-like languages)
- redo if $_ == 4; # Re-do the iteration, keeping the same topic variable (`$_`)
- last if $_ == 5; # Or break out of a loop (like `break` in C-like languages)
+ # You can...
+ next if $_ == 3; # Skip to the next iteration (`continue` in C-like lang.)
+ redo if $_ == 4; # Re-do iteration, keeping the same topic variable (`$_`)
+ last if $_ == 5; # Or break out of loop (like `break` in C-like lang.)
}
-## The "pointy block" syntax isn't specific to for.
-## It's just a way to express a block in Perl6.
+## The "pointy block" syntax isn't specific to the `for` loop. It's just a way
+## to express a block in Perl 6.
+sub long-computation { "Finding factors of large primes" }
if long-computation() -> $result {
- say "The result is $result";
+ say "The result is $result.";
}
```
## Operators
```perl6
-## Since Perl languages are very much operator-based languages,
-## Perl 6 operators are actually just funny-looking subroutines, in syntactic
+## Since Perl languages are very much operator-based languages, Perl 6
+## operators are actually just funny-looking subroutines, in syntactic
## categories, like infix:<+> (addition) or prefix:<!> (bool not).
## The categories are:
@@ -394,105 +430,127 @@ if long-computation() -> $result {
## - "postfix": after (like `++` in `$a++`).
## - "infix": in between (like `*` in `4 * 3`).
## - "circumfix": around (like `[`-`]` in `[1, 2]`).
-## - "post-circumfix": around, after another term (like `{`-`}` in
-## `%hash{'key'}`)
+## - "post-circumfix": around, after another term (like `{`-`}` in
+## `%hash{'key'}`)
## The associativity and precedence list are explained below.
-## Alright, you're set to go !
+## Alright, you're set to go!
-## * Equality Checking
+## Equality Checking
+##------------------
## - `==` is numeric comparison
-3 == 4; # False
-3 != 4; # True
+3 == 4; #=> False
+3 != 4; #=> True
## - `eq` is string comparison
-'a' eq 'b';
-'a' ne 'b'; # not equal
-'a' !eq 'b'; # same as above
+'a' eq 'b'; #=> False
+'a' ne 'b'; #=> True, not equal
+'a' !eq 'b'; #=> True, same as above
## - `eqv` is canonical equivalence (or "deep equality")
-(1, 2) eqv (1, 3);
+(1, 2) eqv (1, 3); #=> False
+(1, 2) eqv (1, 2); #=> True
+Int === Int #=> True
-## - Smart Match Operator: `~~`
+## - `~~` is the smart match operator
## Aliases the left hand side to $_ and then evaluates the right hand side.
## Here are some common comparison semantics:
-## String or Numeric Equality
-
+## String or numeric equality
'Foo' ~~ 'Foo'; # True if strings are equal.
-12.5 ~~ 12.50; # True if numbers are equal.
+12.5 ~~ 12.50; # True if numbers are equal.
## Regex - For matching a regular expression against the left side.
-## Returns a (Match) object, which evaluates as True if regexp matches.
+## Returns a `Match` object, which evaluates as True if regexp matches.
my $obj = 'abc' ~~ /a/;
-say $obj; # 「a」
-say $obj.WHAT; # (Match)
+say $obj; #=> 「a」
+say $obj.WHAT; #=> (Match)
## Hashes
-'key' ~~ %hash; # True if key exists in hash
-
-## Type - Checks if left side "has type" (can check superclasses and roles)
-
-1 ~~ Int; # True
+'key' ~~ %hash; # True if key exists in hash.
-## Smart-matching against a boolean always returns that boolean (and will warn).
+## Type - Checks if left side "is of type" (can check superclasses and
+## roles).
+say 1 ~~ Int; #=> True
-1 ~~ True; # True
-False ~~ True; # True
+## Smart-matching against a boolean always returns that boolean
+## (and will warn).
+say 1 ~~ True; #=> True
+say False ~~ True; #=> True
-## General syntax is $arg ~~ &bool-returning-function;
-## For a complete list of combinations, use this table:
+## General syntax is `$arg ~~ &bool-returning-function;`. For a complete list
+## of combinations, use this table:
## http://perlcabal.org/syn/S03.html#Smart_matching
-## You also, of course, have `<`, `<=`, `>`, `>=`.
-## Their string equivalent are also available : `lt`, `le`, `gt`, `ge`.
-3 > 4;
+## Of course, you also use `<`, `<=`, `>`, `>=` for numeric comparison.
+## Their string equivalent are also available: `lt`, `le`, `gt`, `ge`.
+3 > 4; # False
+3 >= 4; # False
+3 < 4; # True
+3 <= 4; # True
+'a' gt 'b'; # False
+'a' ge 'b'; # False
+'a' lt 'b'; # True
+'a' le 'b'; # True
+
+
+## Range constructor
+##------------------
+3 .. 7; # 3 to 7, both included
+3 ..^ 7; # 3 to 7, exclude right endpoint.
+3 ^.. 7; # 3 to 7, exclude left endpoint. Same as `4..7`.
+3 ^..^ 7; # 3 to 7, exclude both endpoints. Same as `4..6`.
-## * Range constructors
-3 .. 7; # 3 to 7, both included
-## `^` on either side them exclusive on that side :
-3 ^..^ 7; # 3 to 7, not included (basically `4 .. 6`)
## This also works as a shortcut for `0..^N`:
-^10; # means 0..^10
+^10; # means 0..^10
## This also allows us to demonstrate that Perl 6 has lazy/infinite arrays,
## using the Whatever Star:
-my @array = 1..*; # 1 to Infinite ! `1..Inf` is the same.
-say @array[^10]; # you can pass arrays as subscripts and it'll return
- # an array of results. This will print
- # "1 2 3 4 5 6 7 8 9 10" (and not run out of memory !)
-## Note : when reading an infinite list, Perl 6 will "reify" the elements
+my @array = 1..*; # 1 to Infinite! Equivalent to `1..Inf`.
+say @array[^10]; # You can pass ranges as subscripts and it'll return
+ # an array of results. This will print
+ # "1 2 3 4 5 6 7 8 9 10" (and not run out of memory!)
+
+## Note: when reading an infinite list, Perl 6 will "reify" the elements
## it needs, then keep them in memory. They won't be calculated more than once.
## It also will never calculate more elements that are needed.
-## Trying
-## An array subscript can also be a closure.
-## It'll be called with the length as the argument
+## An array subscript can also be a closure. It'll be called with the length
+## as the argument:
say join(' ', @array[15..*]); #=> 15 16 17 18 19
## which is equivalent to:
say join(' ', @array[-> $n { 15..$n }]);
+
## Note: if you try to do either of those with an infinite array,
-## you'll trigger an infinite loop (your program won't finish)
+## you'll trigger an infinite loop (your program won't finish).
-## You can use that in most places you'd expect, even assigning to an array
+## You can use that in most places you'd expect, even when assigning to
+## an array:
my @numbers = ^20;
-## Here numbers increase by "6"; more on `...` operator later.
-my @seq = 3, 9 ... * > 95; # 3 9 15 21 27 [...] 81 87 93 99;
+## Here the numbers increase by 6, like an arithmetic sequence; more on the
+## sequence (`...`) operator later.
+my @seq = 3, 9 ... * > 95; # 3 9 15 21 27 [...] 81 87 93 99;
@numbers[5..*] = 3, 9 ... *; # even though the sequence is infinite,
# only the 15 needed values will be calculated.
-say @numbers; #=> 0 1 2 3 4 3 9 15 21 [...] 81 87
- # (only 20 values)
+say @numbers; #=> 0 1 2 3 4 3 9 15 21 [...] 81 87
+ # (only 20 values)
-## * And &&, Or ||
-3 && 4; # 4, which is Truthy. Calls `.Bool` on `4` and gets `True`.
-0 || False; # False. Calls `.Bool` on `0`
+## and (&&), or (||)
+##------------------
+3 && 4; # 4, which is Truthy. Calls `.Bool` on both 3 and 4 and gets `True`
+ # so it returns 4 since both are `True`.
+3 && 0; # 0
+0 && 4; # 0
-## * Short-circuit (and tight) versions of the above
-# Returns the first argument that evaluates to False, or the last argument.
+0 || False; # False. Calls `.Bool` on `0` and `False` which are both `False`
+ # so it retusns `False` since both are `False`.
+
+## Short-circuit (and tight) versions of the above
+## Return the first argument that evaluates to False, or the last argument.
my ( $a, $b, $c ) = 1, 0, 2;
$a && $b && $c; # Returns 0, the first False value
@@ -500,203 +558,242 @@ $a && $b && $c; # Returns 0, the first False value
## || Returns the first argument that evaluates to True
$b || $a; # 1
-## And because you're going to want them,
-## you also have compound assignment operators:
-$a *= 2; # multiply and assignment. Equivalent to $a = $a * 2;
-$b %%= 5; # divisible by and assignment
+## And because you're going to want them, you also have compound assignment
+## operators:
+$a *= 2; # multiply and assignment. Equivalent to $a = $a * 2;
+$b %%= 5; # divisible by and assignment. Equivalent to $b = $b %% 2;
+$c div= 3; # return divisor and assignment. Equivalent to $c = $c div 3;
+$d mod= 4; # return remainder and assignment. Equivalent to $d = $d mod 4;
@array .= sort; # calls the `sort` method and assigns the result back
```
-## More on subs !
+## More on subs!
```perl6
-## As we said before, Perl 6 has *really* powerful subs. We're going to see
-## a few more key concepts that make them better than in any other language :-).
+## As we said before, Perl 6 has *really* powerful subs. We're going
+## to see a few more key concepts that make them better than in any
+## other language :-).
```
-### Unpacking !
+### Unpacking!
```perl6
-## It's the ability to "extract" arrays and keys (AKA "destructuring").
-## It'll work in `my`s and in parameter lists.
+## Unpacking is the ability to "extract" arrays and keys
+## (AKA "destructuring"). It'll work in `my`s and in parameter lists.
my ($f, $g) = 1, 2;
-say $f; #=> 1
-my ($, $, $h) = 1, 2, 3; # keep the non-interesting anonymous
-say $h; #=> 3
+say $f; #=> 1
+my ($, $, $h) = 1, 2, 3; # keep the non-interesting values anonymous (`$`)
+say $h; #=> 3
my ($head, *@tail) = 1, 2, 3; # Yes, it's the same as with "slurpy subs"
my (*@small) = 1;
-sub unpack_array(@array [$fst, $snd]) {
- say "My first is $fst, my second is $snd ! All in all, I'm @array[].";
+sub unpack_array( @array [$fst, $snd] ) {
+ say "My first is $fst, my second is $snd! All in all, I'm @array[].";
# (^ remember the `[]` to interpolate the array)
}
-unpack_array(@tail); #=> My first is 2, my second is 3 ! All in all, I'm 2 3
+unpack_array(@tail); #=> My first is 2, my second is 3! All in all, I'm 2 3.
## If you're not using the array itself, you can also keep it anonymous,
## much like a scalar:
-sub first-of-array(@ [$fst]) { $fst }
+sub first-of-array( @ [$fst] ) { $fst }
first-of-array(@small); #=> 1
-first-of-array(@tail); # Throws an error "Too many positional parameters passed"
- # (which means the array is too big).
+first-of-array(@tail); # Error: "Too many positional parameters passed"
+ # (which means the array is too big).
-## You can also use a slurp ...
+## You can also use a slurp...
sub slurp-in-array(@ [$fst, *@rest]) { # You could keep `*@rest` anonymous
- say $fst + @rest.elems; # `.elems` returns a list's length.
- # Here, `@rest` is `(3,)`, since `$fst` holds the `2`.
+ say $fst + @rest.elems; # `.elems` returns a list's length.
+ # Here, `@rest` is `(3,)`, since `$fst`
+ # holds the `2`.
}
-slurp-in-array(@tail); #=> 3
+slurp-in-array(@tail); #=> 3
## You could even extract on a slurpy (but it's pretty useless ;-).)
-sub fst(*@ [$fst]) { # or simply : `sub fst($fst) { ... }`
- say $fst;
+sub fst(*@ [$fst]) { # or simply: `sub fst($fst) { ... }`
+ say $fst;
}
-fst(1); #=> 1
+fst(1); #=> 1
fst(1, 2); # errors with "Too many positional parameters passed"
-## You can also destructure hashes (and classes, which you'll learn about later)
-## The syntax is basically `%hash-name (:key($variable-to-store-value-in))`.
+## You can also destructure hashes (and classes, which you'll learn about
+## later). The syntax is basically the same as
+## `%hash-name (:key($variable-to-store-value-in))`.
## The hash can stay anonymous if you only need the values you extracted.
-sub key-of(% (:value($val), :qua($qua))) {
- say "Got val $val, $qua times.";
+sub key-of( % (:value($val), :qua($qua)) ) {
+ say "Got val $val, $qua times.";
}
-## Then call it with a hash: (you need to keep the brackets for it to be a hash)
-key-of({value => 'foo', qua => 1});
+## Then call it with a hash. You need to keep the curly braces for it to be a
+## hash or use `%()` instead to indicate a hash is being passed.
+key-of({value => 'foo', qua => 1}); #=> Got val foo, 1 times.
+key-of(%(value => 'foo', qua => 1)); #=> Got val foo, 1 times.
#key-of(%hash); # the same (for an equivalent `%hash`)
-## The last expression of a sub is returned automatically
-## (though you may use the `return` keyword, of course):
-sub next-index($n) {
- $n + 1;
+## The last expression of a sub is returned automatically (though you may
+## indicate explicitly by using the `return` keyword, of course):
+sub next-index( $n ) {
+ $n + 1;
}
my $new-n = next-index(3); # $new-n is now 4
-## This is true for everything, except for the looping constructs
-## (due to performance reasons): there's reason to build a list
-## if we're just going to discard all the results.
-## If you still want to build one, you can use the `do` statement prefix:
-## (or the `gather` prefix, which we'll see later)
-sub list-of($n) {
- do for ^$n { # note the use of the range-to prefix operator `^` (`0..^N`)
- $_ # current loop iteration
- }
+## This is true for everything, except for the looping constructs (due to
+## performance reasons): there's no reason to build a list if we're just going to
+## discard all the results. If you still want to build one, you can use the
+## `do` statement prefix or the `gather` prefix, which we'll see later:
+
+sub list-of( $n ) {
+ do for ^$n { # note the range-to prefix operator `^` (`0..^N`)
+ $_ # current loop iteration known as the "topic" variable
+ }
}
my @list3 = list-of(3); #=> (0, 1, 2)
```
-### lambdas
+### lambdas (or anonymous subroutines)
```perl6
-## You can create a lambda with `-> {}` ("pointy block") or `{}` ("block")
-my &lambda = -> $argument { "The argument passed to this lambda is $argument" }
+## You can create a lambda with `-> {}` ("pointy block") ,
+## `{}` ("block") or `sub {}`.
+
+my &lambda1 = -> $argument {
+ "The argument passed to this lambda is $argument"
+}
+
+my &lambda2 = {
+ "The argument passed to this lambda is $_"
+}
+
+my &lambda3 = sub ($argument) {
+ "The argument passed to this lambda is $argument"
+}
+
## `-> {}` and `{}` are pretty much the same thing, except that the former can
## take arguments, and that the latter can be mistaken as a hash by the parser.
-## We can, for example, add 3 to each value of an array using map:
+## We can, for example, add 3 to each value of an array using the
+## `map` function with a lambda:
my @arrayplus3 = map({ $_ + 3 }, @array); # $_ is the implicit argument
## A sub (`sub {}`) has different semantics than a block (`{}` or `-> {}`):
## A block doesn't have a "function context" (though it can have arguments),
-## which means that if you return from it,
-## you're going to return from the parent function. Compare:
-sub is-in(@array, $elem) {
- # this will `return` out of the `is-in` sub
- # once the condition evaluated to True, the loop won't be run anymore
- map({ return True if $_ == $elem }, @array);
-}
-sub truthy-array(@array) {
- # this will produce an array of `True` and `False`:
- # (you can also say `anon sub` for "anonymous subroutine")
- map(sub ($i) { if $i { return True } else { return False } }, @array);
- # ^ the `return` only returns from the anonymous `sub`
-}
-
-## You can also use the "whatever star" to create an anonymous function
+## which means that if you return from it, you're going to return from the
+## parent function. Compare:
+sub is-in( @array, $elem ) {
+ # this will `return` out of the `is-in` sub once the condition evaluated
+ ## to True, the loop won't be run anymore.
+ map({ return True if $_ == $elem }, @array);
+}
+## with:
+sub truthy-array( @array ) {
+ # this will produce an array of `True` and `False`:
+ # (you can also say `anon sub` for "anonymous subroutine")
+ map(sub ($i) { if $i { return True } else { return False } }, @array);
+ # ^ the `return` only returns from the anonymous `sub`
+}
+
+## The `anon` declarator can be used to create an anonymous sub from a
+## regular subroutine. The regular sub knows its name but its symbol is
+## prevented from getting installed in the lexical scope, the method table
+## and everywhere else.
+
+my $anon-sum = anon sub summation(*@a) { [+] *@a }
+say $anon-sum.name; #=> summation
+say $anon-sum(2, 3, 5); #=> 10
+#say summation; #=> Error: Undeclared routine: ...
+
+## You can also use the "whatever star" to create an anonymous subroutine.
## (it'll stop at the furthest operator in the current expression)
-my @arrayplus3 = map(*+3, @array); # `*+3` is the same as `{ $_ + 3 }`
+my @arrayplus3 = map(*+3, @array); # `*+3` is the same as `{ $_ + 3 }`
my @arrayplus3 = map(*+*+3, @array); # Same as `-> $a, $b { $a + $b + 3 }`
# also `sub ($a, $b) { $a + $b + 3 }`
-say (*/2)(4); #=> 2
- # Immediately execute the function Whatever created.
+say (*/2)(4); #=> 2
+ # Immediately execute the function Whatever created.
say ((*+3)/5)(5); #=> 1.6
- # works even in parens !
-
-## But if you need to have more than one argument (`$_`)
-## in a block (without wanting to resort to `-> {}`),
-## you can also use the implicit argument syntax, `$^` :
-map({ $^a + $^b + 3 }, @array); # equivalent to following:
-map(sub ($a, $b) { $a + $b + 3 }, @array); # (here with `sub`)
-
-## Note : those are sorted lexicographically.
-# `{ $^b / $^a }` is like `-> $a, $b { $b / $a }`
+ # It works even in parens!
+
+## But if you need to have more than one argument (`$_`) in a block (without
+## wanting to resort to `-> {}`), you can also use the implicit argument
+## syntax, `$^`:
+map({ $^a + $^b + 3 }, @array);
+# which is equivalent to the following which uses a `sub`:
+map(sub ($a, $b) { $a + $b + 3 }, @array);
+
+## The parameters `$^a`, `$^b`, etc. are known as placeholder parameters or
+## self-declared positional parameters. They're sorted lexicographically so
+## `{ $^b / $^a }` is equivalent `-> $a, $b { $b / $a }`.
```
### About types...
```perl6
-## Perl6 is gradually typed. This means you can specify the type
-## of your variables/arguments/return types, or you can omit them
-## and they'll default to "Any".
-## You obviously get access to a few base types, like Int and Str.
-## The constructs for declaring types are "class", "role",
-## which you'll see later.
-
-## For now, let us examine "subset":
-## a "subset" is a "sub-type" with additional checks.
-## For example: "a very big integer is an Int that's greater than 500"
-## You can specify the type you're subtyping (by default, Any),
-## and add additional checks with the "where" keyword:
+## Perl 6 is gradually typed. This means you can specify the type of your
+## variables/arguments/return types, or you can omit the type annotations in
+## in which case they'll default to `Any`. Obviously you get access to a few
+## base types, like `Int` and `Str`. The constructs for declaring types are
+## "subset", "class", "role", etc. which you'll see later.
+
+## For now, let us examine "subset" which is a "sub-type" with additional
+## checks. For example, "a very big integer is an Int that's greater than 500".
+## You can specify the type you're subtyping (by default, `Any`), and add
+## additional checks with the `where` clause:
subset VeryBigInteger of Int where * > 500;
+## Or the set of the whole numbers:
+subset WholeNumber of Int where * >= 0;
```
### Multiple Dispatch
```perl6
## Perl 6 can decide which variant of a `sub` to call based on the type of the
-## arguments, or on arbitrary preconditions, like with a type or a `where`:
+## arguments, or on arbitrary preconditions, like with a type or `where`:
-## with types
-multi sub sayit(Int $n) { # note the `multi` keyword here
+## with types:
+multi sub sayit( Int $n ) { # note the `multi` keyword here
say "Number: $n";
}
-multi sayit(Str $s) { # a multi is a `sub` by default
+multi sayit( Str $s ) { # a multi is a `sub` by default
say "String: $s";
}
-sayit("foo"); # prints "String: foo"
-sayit(True); # fails at *compile time* with
- # "calling 'sayit' will never work with arguments of types ..."
+sayit("foo"); #=> "String: foo"
+sayit(25); #=> "Number: 25"
+sayit(True); # fails at *compile time* with "calling 'sayit' will never
+ # work with arguments of types ..."
-## with arbitrary precondition (remember subsets?):
-multi is-big(Int $n where * > 50) { "Yes !" } # using a closure
-multi is-big(Int $ where 10..50) { "Quite." } # Using smart-matching
- # (could use a regexp, etc)
+## with arbitrary preconditions (remember subsets?):
+multi is-big(Int $n where * > 50) { "Yes!" } # using a closure
+multi is-big(Int $n where {$_ > 50}) { "Yes!" } # similar to above
+multi is-big(Int $ where 10..50) { "Quite." } # Using smart-matching
+ # (could use a regexp, etc)
multi is-big(Int $) { "No" }
subset Even of Int where * %% 2;
-
multi odd-or-even(Even) { "Even" } # The main case using the type.
# We don't name the argument.
-multi odd-or-even($) { "Odd" } # "else"
+multi odd-or-even($) { "Odd" } # "everthing else" hence the $ variable
-## You can even dispatch based on a positional's argument presence !
-multi with-or-without-you(:$with!) { # You need make it mandatory to
- # be able to dispatch against it.
- say "I can live ! Actually, I can't.";
+## You can even dispatch based on the presence of positional and
+## named arguments:
+multi with-or-without-you($with) {
+ say "I wish I could but I can't";
+}
+multi with-or-without-you(:$with) {
+ say "I can live! Actually, I can't.";
}
multi with-or-without-you {
- say "Definitely can't live.";
+ say "Definitely can't live.";
}
-## This is very, very useful for many purposes, like `MAIN` subs (covered
-## later), and even the language itself is using it in several places.
+
+## This is very, very useful for many purposes, like `MAIN` subs (covered
+## later), and even the language itself uses it in several places.
##
## - `is`, for example, is actually a `multi sub` named `trait_mod:<is>`,
## and it works off that.
## - `is rw`, is simply a dispatch to a function with this signature:
## sub trait_mod:<is>(Routine $r, :$rw!) {}
##
-## (commented because running this would be a terrible idea !)
+## (commented out because running this would be a terrible idea!)
```
## Scoping
@@ -705,175 +802,207 @@ multi with-or-without-you {
## In Perl 6, unlike many scripting languages, (such as Python, Ruby, PHP),
## you must declare your variables before using them. The `my` declarator
## you have learned uses "lexical scoping". There are a few other declarators,
-## (`our`, `state`, ..., ) which we'll see later.
-## This is called "lexical scoping", where in inner blocks,
-## you can access variables from outer blocks.
+## (`our`, `state`, ..., ) which we'll see later. This is called
+## "lexical scoping", where in inner blocks, you can access variables from
+## outer blocks.
my $file_scoped = 'Foo';
sub outer {
- my $outer_scoped = 'Bar';
- sub inner {
- say "$file_scoped $outer_scoped";
- }
- &inner; # return the function
+ my $outer_scoped = 'Bar';
+ sub inner {
+ say "$file_scoped $outer_scoped";
+ }
+ &inner; # return the function
}
-outer()(); #=> 'Foo Bar'
+outer()(); #=> 'Foo Bar'
## As you can see, `$file_scoped` and `$outer_scoped` were captured.
-## But if we were to try and use `$bar` outside of `foo`,
+## But if we were to try and use `$outer_scoped` outside the `outer` sub,
## the variable would be undefined (and you'd get a compile time error).
```
## Twigils
```perl6
-## There are many special `twigils` (composed sigil's) in Perl 6.
-## Twigils define the variables' scope.
+## There are many special `twigils` (composed sigils) in Perl 6. Twigils
+## define the variables' scope.
## The * and ? twigils work on standard variables:
## * Dynamic variable
## ? Compile-time variable
## The ! and the . twigils are used with Perl 6's objects:
-## ! Attribute (class member)
+## ! Attribute (instance attribute)
## . Method (not really a variable)
-## `*` Twigil: Dynamic Scope
-## These variables use the`*` twigil to mark dynamically-scoped variables.
+## `*` twigil: Dynamic Scope
+## These variables use the `*` twigil to mark dynamically-scoped variables.
## Dynamically-scoped variables are looked up through the caller, not through
-## the outer scope
+## the outer scope.
my $*dyn_scoped_1 = 1;
my $*dyn_scoped_2 = 10;
sub say_dyn {
- say "$*dyn_scoped_1 $*dyn_scoped_2";
+ say "$*dyn_scoped_1 $*dyn_scoped_2";
}
sub call_say_dyn {
my $*dyn_scoped_1 = 25; # Defines $*dyn_scoped_1 only for this sub.
- $*dyn_scoped_2 = 100; # Will change the value of the file scoped variable.
- say_dyn(); #=> 25 100 $*dyn_scoped 1 and 2 will be looked for in the call.
- # It uses the value of $*dyn_scoped_1 from inside this sub's
- # lexical scope even though the blocks aren't nested (they're
- # call-nested).
-}
-say_dyn(); #=> 1 10
+ $*dyn_scoped_2 = 100; # Will change the value of the file scoped variable.
+ say_dyn(); #=> 25 100, $*dyn_scoped 1 and 2 will be looked
+ # for in the call.
+ # It uses the value of $*dyn_scoped_1 from inside
+ # this sub's lexical scope even though the blocks
+ # aren't nested (they're call-nested).
+}
+say_dyn(); #=> 1 10
call_say_dyn(); #=> 25 100
# Uses $*dyn_scoped_1 as defined in call_say_dyn even though
# we are calling it from outside.
-say_dyn(); #=> 1 100 We changed the value of $*dyn_scoped_2 in call_say_dyn
- # so now its value has changed.
+say_dyn(); #=> 1 100 We changed the value of $*dyn_scoped_2 in
+ # call_say_dyn so now its value has changed.
```
## Object Model
```perl6
## To call a method on an object, add a dot followed by the method name:
-## => $object.method
+## `$object.method`
+
## Classes are declared with the `class` keyword. Attributes are declared
-## with the `has` keyword, and methods declared with `method`.
-## Every attribute that is private uses the ! twigil for example: `$!attr`.
-## Immutable public attributes use the `.` twigil.
-## (you can make them mutable with `is rw`)
-## The easiest way to remember the `$.` twigil is comparing it to how methods
-## are called.
-
-## Perl 6's object model ("SixModel") is very flexible,
-## and allows you to dynamically add methods, change semantics, etc ...
-## (these will not all be covered here, and you should refer to:
+## with the `has` keyword, and methods declared with the `method` keyword.
+
+## Every attribute that is private uses the ! twigil. For example: `$!attr`.
+## Immutable public attributes use the `.` twigil which creates a read-only
+## method named after the attribute. In fact, declaring an attribute with `.`
+## is equivalent to declaring the same attribute with `!` and then creating
+## a read-only method with the attribute's name. However, this is done for us
+## by Perl 6 automatically. The easiest way to remember the `$.` twigil is
+## by comparing it to how methods are called.
+
+## Perl 6's object model ("SixModel") is very flexible, and allows you to
+## dynamically add methods, change semantics, etc... Unfortunately, these will
+## not all be covered here, and you should refer to:
## https://docs.perl6.org/language/objects.html.
-class Attrib-Class {
- has $.attrib; # `$.attrib` is immutable.
- # From inside the class, use `$!attrib` to modify it.
- has $.other-attrib is rw; # You can mark a public attribute `rw`.
- has Int $!private-attrib = 10;
-
- method get-value {
- $.attrib + $!private-attrib;
- }
+class Human {
+ has Str $.name; # `$.name` is immutable but with an accessor method.
+ has Str $.bcountry; # Use `$!bcountry` to modify it inside the class.
+ has Str $.ccountry is rw; # This attribute can be modified from outside.
+ has Int $!age = 0; # A private attribute with default value.
- method set-value($param) { # Methods can take parameters
- $!attrib = $param; # This works, because `$!` is always mutable.
- # $.attrib = $param; # Wrong: You can't use the `$.` immutable version.
+ method birthday {
+ $!age += 1; # Add a year to human's age
+ }
- $.other-attrib = 5; # This works, because `$.other-attrib` is `rw`.
- }
+ method get-age {
+ return $!age;
+ }
- method !private-method {
- say "This method is private to the class !";
- }
+ # This method is private to the class. Note the `!` before the
+ # method's name.
+ method !do-decoration {
+ return "$!name was born in $!bcountry and now lives in $!ccountry."
+ }
+
+ # This method is public, just like `birthday` and `get-age`.
+ method get-info {
+ self.do-decoration; # Invoking a method on `self` inside the class.
+ # Use `self!priv-method` for private method.
+ # Use `self.publ-method` for public method.
+ }
};
-## Create a new instance of Attrib-Class with $.attrib set to 5 :
+## Create a new instance of Human class.
## Note: you can't set private-attribute from here (more later on).
-my $class-obj = Attrib-Class.new(attrib => 5);
-say $class-obj.get-value; #=> 15
-# $class-obj.attrib = 5; # This fails, because the `has $.attrib` is immutable
-$class-obj.other-attrib = 10; # This, however, works, because the public
- # attribute is mutable (`rw`).
+my $person1 = Human.new(
+ name => "Jord",
+ bcountry = "Togo",
+ ccountry => "Togo"
+);
+
+say $person1.name; #=> Jord
+say $person1.bcountry; #=> Togo
+say $person1.ccountry; #=> Togo
+
+
+# $person1.bcountry = "Mali"; # This fails, because the `has $.bcountry`
+ # is immutable. Jord can't change his birthplace.
+$person1.ccountry = "France"; # This works because the `$.ccountry` is mutable
+ # (`is rw`). Now Jord's current country is France.
+
+# Calling methods on the instance objects.
+$person1.birthday; #=> 1
+$person1.get-info; #=> Jord was born in Togo and now lives in France.
+$person1.do-decoration; # This fails since the method `do-decoration` is
+ # private.
```
### Object Inheritance
```perl6
-## Perl 6 also has inheritance (along with multiple inheritance)
-## While `method`'s are inherited, `submethod`'s are not.
-## Submethods are useful for object construction and destruction tasks,
-## such as BUILD, or methods that must be overridden by subtypes.
-## We will learn about BUILD later on.
+## Perl 6 also has inheritance (along with multiple inheritance). While
+## methods are inherited, submethods are not. Submethods are useful for
+## object construction and destruction tasks, such as BUILD, or methods that
+## must be overridden by subtypes. We will learn about BUILD later on.
class Parent {
- has $.age;
- has $.name;
- # This submethod won't be inherited by Child.
- submethod favorite-color {
- say "My favorite color is Blue";
- }
- # This method is inherited
- method talk { say "Hi, my name is $!name" }
+ has $.age;
+ has $.name;
+
+ # This submethod won't be inherited by the Child class.
+ submethod favorite-color {
+ say "My favorite color is Blue";
+ }
+
+ # This method is inherited
+ method talk { say "Hi, my name is $!name" }
}
+
# Inheritance uses the `is` keyword
class Child is Parent {
- method talk { say "Goo goo ga ga" }
- # This shadows Parent's `talk` method, This child hasn't learned to speak yet!
+ method talk { say "Goo goo ga ga" }
+ # This shadows Parent's `talk` method.
+ # This child hasn't learned to speak yet!
}
+
my Parent $Richard .= new(age => 40, name => 'Richard');
-$Richard.favorite-color; #=> "My favorite color is Blue"
-$Richard.talk; #=> "Hi, my name is Richard"
-## $Richard is able to access the submethod, he knows how to say his name.
+$Richard.favorite-color; #=> "My favorite color is Blue"
+$Richard.talk; #=> "Hi, my name is Richard"
+## $Richard is able to access the submethod and he knows how to say his name.
my Child $Madison .= new(age => 1, name => 'Madison');
-$Madison.talk; # prints "Goo goo ga ga" due to the overridden method.
-# $Madison.favorite-color # does not work since it is not inherited
+$Madison.talk; #=> "Goo goo ga ga", due to the overridden method.
+# $Madison.favorite-color # does not work since it is not inherited.
## When you use `my T $var`, `$var` starts off with `T` itself in it,
## so you can call `new` on it.
## (`.=` is just the dot-call and the assignment operator:
-## `$a .= b` is the same as `$a = $a.b`)
+## `$a .= b` is the same as `$a = $a.b`)
## Also note that `BUILD` (the method called inside `new`)
-## will set parent properties too, so you can pass `val => 5`.
+## will set parent's properties too, so you can pass `val => 5`.
```
### Roles, or Mixins
```perl6
-## Roles are supported too (also called Mixins in other languages)
+## Roles are supported too (which are called Mixins in other languages)
role PrintableVal {
- has $!counter = 0;
- method print {
- say $.val;
- }
+ has $!counter = 0;
+ method print {
+ say $.val;
+ }
}
-## you "import" a mixin (a "role") with "does":
+## you "apply" a role (or mixin) with `does` keyword:
class Item does PrintableVal {
- has $.val;
+ has $.val;
- ## When `does`-ed, a `role` literally "mixes in" the class:
- ## the methods and attributes are put together, which means a class can access
- ## the private attributes/methods of its roles (but not the inverse !):
- method access {
- say $!counter++;
- }
+ ## When `does`-ed, a `role` literally "mixes in" the class:
+ ## the methods and attributes are put together, which means a class
+ ## can access the private attributes/methods of its roles (but
+ ## not the inverse!):
+ method access {
+ say $!counter++;
+ }
## However, this:
## method print {}
@@ -881,9 +1010,9 @@ class Item does PrintableVal {
## (this means a parent class can shadow a child class's `multi print() {}`,
## but it's an error if a role does)
- ## NOTE: You can use a role as a class (with `is ROLE`). In this case,
- ## methods will be shadowed, since the compiler will consider `ROLE` to
- ## be a class.
+ ## NOTE: You can use a role as a class (with `is ROLE`). In this case,
+ ## methods will be shadowed, since the compiler will consider `ROLE`
+ ## to be a class.
}
```
@@ -891,91 +1020,109 @@ class Item does PrintableVal {
```perl6
## Exceptions are built on top of classes, in the package `X` (like `X::IO`).
-## In Perl6 exceptions are automatically 'thrown'
-open 'foo'; #> Failed to open file foo: no such file or directory
-## It will also print out what line the error was thrown at and other error info
+## In Perl6 exceptions are automatically 'thrown':
+open 'foo'; #=> Failed to open file foo: no such file or directory
+## It will also print out what line the error was thrown at
+## and other error info.
## You can throw an exception using `die`:
die 'Error!'; #=> Error!
## Or more explicitly:
-die X::AdHoc.new(payload => 'Error!');
+X::AdHoc.new(payload => 'Error!').throw; #=> Error!
## In Perl 6, `orelse` is similar to the `or` operator, except it only matches
-## undefined variables instead of anything evaluating as false.
+## undefined variables instead of anything evaluating as `False`.
## Undefined values include: `Nil`, `Mu` and `Failure` as well as `Int`, `Str`
## and other types that have not been initialized to any value yet.
## You can check if something is defined or not using the defined method:
my $uninitialized;
-say $uninitiazilzed.defined; #> False
-## When using `orelse` it will disarm the exception and alias $_ to that failure
-## This will avoid it being automatically handled and printing lots of scary
-## error messages to the screen.
-## We can use the exception method on $_ to access the exception
+say $uninitiazilzed.defined; #=> False
+
+## When using `orelse` it will disarm the exception and alias $_ to that
+## failure. This will prevent it to being automatically handled and printing
+## lots of scary error messages to the screen. We can use the `exception`
+## method on the `$_` variable to access the exception
open 'foo' orelse say "Something happened {.exception}";
## This also works:
-open 'foo' orelse say "Something happened $_"; #> Something happened
- #> Failed to open file foo: no such file or directory
-## Both of those above work but in case we get an object from the left side that
-## is not a failure we will probably get a warning. We see below how we can use
-## `try` and `CATCH` to be more specific with the exceptions we catch.
+open 'foo' orelse say "Something happened $_"; #=> Something happened
+ #=> Failed to open file foo: no such file or directory
+## Both of those above work but in case we get an object from the left side
+## that is not a failure we will probably get a warning. We see below how we
+## can use try` and `CATCH` to be more specific with the exceptions we catch.
```
### Using `try` and `CATCH`
```perl6
## By using `try` and `CATCH` you can contain and handle exceptions without
-## disrupting the rest of the program. `try` will set the last exception to
-## the special variable `$!` Note: This has no relation to $!variables.
+## disrupting the rest of the program. The `try` block will set the last
+## exception to the special variable `$!` (known as the error variable).
+## Note: This has no relation to $!variables seen inside class definitions.
+
try open 'foo';
-say "Well, I tried! $!" if defined $!; #> Well, I tried! Failed to open file
- #foo: no such file or directory
+say "Well, I tried! $!" if defined $!;
+#=> Well, I tried! Failed to open file foo: no such file or directory
+
## Now, what if we want more control over handling the exception?
## Unlike many other languages, in Perl 6, you put the `CATCH` block *within*
-## the block to `try`. Similar to how $_ was set when we 'disarmed' the
-## exception with orelse, we also use $_ in the CATCH block.
-## Note: ($! is only set *after* the `try` block)
-## By default, a `try` has a `CATCH` block that catches
-## any exception (`CATCH { default {} }`).
+## the block to `try`. Similar to how the `$_` variable was set when we
+## 'disarmed' the exception with `orelse`, we also use `$_` in the CATCH block.
+## Note: The `$!` variable is only set *after* the `try` block has caught an
+## exception. By default, a `try` block has a `CATCH` block of its own that
+## catches any exception (`CATCH { default {} }`).
-try { my $a = (0 %% 0); CATCH { say "Something happened: $_" } }
- #=> Something happened: Attempt to divide by zero using infix:<%%>
+try {
+ my $a = (0 %% 0);
+ CATCH {
+ say "Something happened: $_"
+ }
+}
+#=> Something happened: Attempt to divide by zero using infix:<%%>
+
+## You can redefine it using `when`s (and `default`) to handle the exceptions
+## you want to catch explicitly:
-## You can redefine it using `when`s (and `default`)
-## to handle the exceptions you want:
try {
open 'foo';
- CATCH { # In the `CATCH` block, the exception is set to $_
- when X::AdHoc { say "Error: $_" }
- #=>Error: Failed to open file /dir/foo: no such file or directory
-
- ## Any other exception will be re-raised, since we don't have a `default`
- ## Basically, if a `when` matches (or there's a `default`) marks the
- ## exception as
- ## "handled" so that it doesn't get re-thrown from the `CATCH`.
- ## You still can re-throw the exception (see below) by hand.
+ CATCH {
+ # In the `CATCH` block, the exception is set to the $_ variable.
+ when X::AdHoc {
+ say "Error: $_"
+ }
+ when X::Numeric::DivideByZero {
+ say "Error: $_";
+ }
+ ## Any other exceptions will be re-raised, since we don't have a `default`.
+ ## Basically, if a `when` matches (or there's a `default`), the
+ ## exception is marked as "handled" so as to prevent its re-throw
+ ## from the `CATCH` block. You still can re-throw the exception (see below)
+ ## by hand.
}
}
+#=>Error: Failed to open file /dir/foo: no such file or directory
## There are also some subtleties to exceptions. Some Perl 6 subs return a
-## `Failure`, which is a kind of "unthrown exception". They're not thrown until
-## you tried to look at their content, unless you call `.Bool`/`.defined` on
-## them - then they're handled.
+## `Failure`, which is a wrapper around an `Exception` object which is
+## "unthrown". They're not thrown until you try to use the variables containing
+## them unless you call `.Bool`/`.defined` on them - then they're handled.
## (the `.handled` method is `rw`, so you can mark it as `False` back yourself)
-##
## You can throw a `Failure` using `fail`. Note that if the pragma `use fatal`
## is on, `fail` will throw an exception (like `die`).
+
fail "foo"; # We're not trying to access the value, so no problem.
try {
- fail "foo";
- CATCH {
- default { say "It threw because we tried to get the fail's value!" }
+ fail "foo";
+ CATCH {
+ default {
+ say "It threw because we tried to get the fail's value!"
+ }
}
}
## There is also another kind of exception: Control exceptions.
-## Those are "good" exceptions, which happen when you change your program's
+## Those are "good" exceptions, which happen when you change your program's
## flow, using operators like `return`, `next` or `last`.
## You can "catch" those with `CONTROL` (not 100% working in Rakudo yet).
```
@@ -989,29 +1136,35 @@ try {
## Packages are important - especially as Perl is well-known for CPAN,
## the Comprehensive Perl Archive Network.
-## You can use a module (bring its declarations into scope) with `use`
+## You can use a module (bring its declarations into scope) with
+## the `use` keyword:
use JSON::Tiny; # if you installed Rakudo* or Panda, you'll have this module
say from-json('[1]').perl; #=> [1]
## You should not declare packages using the `package` keyword (unlike Perl 5).
## Instead, use `class Package::Name::Here;` to declare a class, or if you only
-## want to export variables/subs, you can use `module`.
+## want to export variables/subs, you can use `module` instead.
+
+module Hello::World { # bracketed form
+ # If `Hello` doesn't exist yet, it'll just be a "stub",
+ # that can be redeclared as something else later.
-module Hello::World { # Bracketed form
- # If `Hello` doesn't exist yet, it'll just be a "stub",
- # that can be redeclared as something else later.
- # ... declarations here ...
+ # ... declarations here ...
}
-unit module Parse::Text; # file-scoped form
-grammar Parse::Text::Grammar { # A grammar is a package, which you could `use`
-} # You will learn more about grammars in the regex section
+unit module Parse::Text; # file-scoped form which extends until
+ # the end of the file
+
+grammar Parse::Text::Grammar {
+ # A grammar is a package, which you could `use`.
+ # You will learn more about grammars in the regex section
+}
## As said before, any part of the six model is also a package.
## Since `JSON::Tiny` uses its own `JSON::Tiny::Actions` class, you can use it:
my $actions = JSON::Tiny::Actions.new;
-## We'll see how to export variables and subs in the next part:
+## We'll see how to export variables and subs in the next part.
```
## Declarators
@@ -1020,36 +1173,38 @@ my $actions = JSON::Tiny::Actions.new;
## In Perl 6, you get different behaviors based on how you declare a variable.
## You've already seen `my` and `has`, we'll now explore the others.
-## * `our` declarations happen at `INIT` time -- (see "Phasers" below)
-## It's like `my`, but it also creates a package variable.
-## (All packagish things (`class`, `role`, etc) are `our` by default)
-module Var::Increment {
- our $our-var = 1; # Note: you can't put a type constraint like Int on an
- my $my-var = 22; # `our` variable.
- our sub Inc {
-
- our sub available { # If you try to make inner `sub`s `our`...
- # Better know what you're doing (Don't !).
- say "Don't do that. Seriously. You'll get burned.";
- }
+## `our` - these declarations happen at `INIT` time -- (see "Phasers" below).
+## It's like `my`, but it also creates a package variable. All packagish
+## things such as `class`, `role`, etc. are `our` by default.
- my sub unavailable { # `my sub` is the default
- say "Can't access me from outside, I'm 'my'!";
- }
- say ++$our-var; # Increment the package variable and output its value
+module Var::Increment {
+ our $our-var = 1; # Note: `our`-declared variables cannot be typed.
+ my $my-var = 22;
+
+ our sub Inc {
+ our sub available { # If you try to make inner `sub`s `our`...
+ # ... Better know what you're doing (Don't !).
+ say "Don't do that. Seriously. You'll get burned.";
+ }
+
+ my sub unavailable { # `sub`s are `my`-declared by default
+ say "Can't access me from outside, I'm 'my'!";
+ }
+ say ++$our-var; # Increment the package variable and output its value
}
}
-say $Var::Increment::our-var; #=> 1 This works
-say $Var::Increment::my-var; #=> (Any) This will not work.
-Var::Increment::Inc; #=> 2
-Var::Increment::Inc; #=> 3 # Notice how the value of $our-var was
- # retained.
-Var::Increment::unavailable; #> Could not find symbol '&unavailable'
+say $Var::Increment::our-var; #=> 1, this works!
+say $Var::Increment::my-var; #=> (Any), this will not work!
+
+Var::Increment::Inc; #=> 2
+Var::Increment::Inc; #=> 3 , notice how the value of $our-var was
+ # retained.
+Var::Increment::unavailable; #=> Could not find symbol '&unavailable'
-## * `constant` (happens at `BEGIN` time)
-## You can use the `constant` keyword to declare a compile-time variable/symbol:
+## `constant` - these declarations happen at `BEGIN` time. You can use
+## the `constant` keyword to declare a compile-time variable/symbol:
constant Pi = 3.14;
constant $var = 1;
@@ -1057,12 +1212,12 @@ constant $var = 1;
constant why-not = 5, 15 ... *;
say why-not[^5]; #=> 5 15 25 35 45
-## * `state` (happens at run time, but only once)
-## State variables are only initialized one time
-## (they exist in other languages such as C as `static`)
+## `state` - these declarations happen at run time, but only once. State
+## variables are only initialized one time. In other languages such as C
+## they exist as `static` variables.
sub fixed-rand {
- state $val = rand;
- say $val;
+ state $val = rand;
+ say $val;
}
fixed-rand for ^10; # will print the same number 10 times
@@ -1070,40 +1225,42 @@ fixed-rand for ^10; # will print the same number 10 times
## If you declare a function with a `state` within a loop, it'll re-create the
## variable for each iteration of the loop. See:
for ^5 -> $a {
- sub foo {
- state $val = rand; # This will be a different value for every value of `$a`
- }
- for ^5 -> $b {
- say foo; # This will print the same value 5 times, but only 5.
- # Next iteration will re-run `rand`.
- }
+ sub foo {
+ state $val = rand; # This will be a different value for
+ # every value of `$a`
+ }
+ for ^5 -> $b {
+ say foo; # This will print the same value 5 times,
+ # but only 5. Next iteration will re-run `rand`.
+ }
}
```
## Phasers
```perl6
-## Phasers in Perl 6 are blocks that happen at determined points of time in your
-## program. They are called phasers because they mark a change in the phase
-## of a program. For example, when the program is compiled, a for loop runs,
-## you leave a block, or an exception gets thrown.
-## (`CATCH` is actually a phaser!)
-## Some of them can be used for their return values, some of them can't
-## (those that can have a "[*]" in the beginning of their explanation text).
-## Let's have a look !
-
-## * Compile-time phasers
+## Phasers in Perl 6 are blocks that happen at determined points of time in
+## your program. They are called phasers because they mark a change in the
+## phase of a program. For example, when the program is compiled, a for loop
+## runs, you leave a block, or an exception gets thrown (The `CATCH` block is
+## actually a phaser!). Some of them can be used for their return values,
+## some of them can't (those that can have a "[*]" in the beginning of their
+## explanation text). Let's have a look!
+
+## Compile-time phasers
BEGIN { say "[*] Runs at compile time, as soon as possible, only once" }
CHECK { say "[*] Runs at compile time, as late as possible, only once" }
-## * Run-time phasers
+## Run-time phasers
INIT { say "[*] Runs at run time, as soon as possible, only once" }
-END { say "Runs at run time, as late as possible, only once" }
+END { say "Runs at run time, as late as possible, only once" }
-## * Block phasers
+## Block phasers
ENTER { say "[*] Runs everytime you enter a block, repeats on loop blocks" }
-LEAVE { say "Runs everytime you leave a block, even when an exception
- happened. Repeats on loop blocks." }
+LEAVE {
+ say "Runs everytime you leave a block, even when an exception
+ happened. Repeats on loop blocks."
+}
PRE {
say "Asserts a precondition at every block entry,
@@ -1112,7 +1269,7 @@ PRE {
an exception of type X::Phaser::PrePost is thrown.";
}
-## example:
+## Example:
for 0..2 {
PRE { $_ > 1 } # This is going to blow up with "Precondition failed"
}
@@ -1123,83 +1280,86 @@ POST {
say "If this block doesn't return a truthy value,
an exception of type X::Phaser::PrePost is thrown, like PRE.";
}
+
for 0..2 {
POST { $_ < 2 } # This is going to blow up with "Postcondition failed"
}
-## * Block/exceptions phasers
+## Block/exceptions phasers
sub {
KEEP { say "Runs when you exit a block successfully
(without throwing an exception)" }
- UNDO { say "Runs when you exit a block unsuccessfully
+ UNDO { say "Runs when you exit a block unsuccessfully
(by throwing an exception)" }
}
-## * Loop phasers
+## Loop phasers
for ^5 {
FIRST { say "[*] The first time the loop is run, before ENTER" }
- NEXT { say "At loop continuation time, before LEAVE" }
- LAST { say "At loop termination time, after LEAVE" }
+ NEXT { say "At loop continuation time, before LEAVE" }
+ LAST { say "At loop termination time, after LEAVE" }
}
-## * Role/class phasers
+## Role/class phasers
COMPOSE { "When a role is composed into a class. /!\ NOT YET IMPLEMENTED" }
-## They allow for cute tricks or clever code ...:
+## They allow for cute tricks or clever code...:
say "This code took " ~ (time - CHECK time) ~ "s to compile";
## ... or clever organization:
sub do-db-stuff {
- $db.start-transaction; # start a new transaction
- KEEP $db.commit; # commit the transaction if all went well
- UNDO $db.rollback; # or rollback if all hell broke loose
+ $db.start-transaction; # start a new transaction
+ KEEP $db.commit; # commit the transaction if all went well
+ UNDO $db.rollback; # or rollback if all hell broke loose
}
```
## Statement prefixes
```perl6
-## Those act a bit like phasers: they affect the behavior of the following code.
-## Though, they run in-line with the executable code, so they're in lowercase.
-## (`try` and `start` are theoretically in that list, but explained elsewhere)
-## Note: all of these (except start) don't need explicit brackets `{` and `}`.
+## Those act a bit like phasers: they affect the behavior of the following
+## code. Though, they run in-line with the executable code, so they're in
+## lowercase. (`try` and `start` are theoretically in that list, but explained
+## elsewhere) Note: all of these (except start) don't need explicit curly
+## braces `{` and `}`.
-## - `do` (that you already saw) - runs a block or a statement as a term
-## You can't normally use a statement as a value (or "term"):
-##
-## my $value = if True { 1 } # `if` is a statement - parse error
-##
-## This works:
-my $a = do if True { 5 } # with `do`, `if` is now a term.
-
-## - `once` - Makes sure a piece of code only runs once
-for ^5 { once say 1 }; #=> 1
- # Only prints ... once.
-## Like `state`, they're cloned per-scope
-for ^5 { sub { once say 1 }() } #=> 1 1 1 1 1
- # Prints once per lexical scope
-
-## - `gather` - Co-routine thread
-## Gather allows you to `take` several values in an array,
-## much like `do`, but allows you to take any expression.
+## `do` - (which you already saw) runs a block or a statement as a term.
+## Normally you cannot use a statement as a value (or "term"). `do` helps us
+## do it.
+
+# my $value = if True { 1 } # this fails since `if` is a statement
+my $a = do if True { 5 } # with `do`, `if` is now a term returning a value
+
+## `once` - makes sure a piece of code only runs once.
+for ^5 {
+ once say 1
+}; #=> 1, only prints ... once
+
+## Similar to `state`, they're cloned per-scope.
+for ^5 {
+ sub { once say 1 }()
+}; #=> 1 1 1 1 1, prints once per lexical scope.
+
+## `gather` - co-routine thread. The `gather` constructs allows us to `take`
+## several values from an array/list, much like `do`.
say gather for ^5 {
- take $_ * 3 - 1;
- take $_ * 3 + 1;
-} #=> -1 1 2 4 5 7 8 10 11 13
+ take $_ * 3 - 1;
+ take $_ * 3 + 1;
+}
+#=> -1 1 2 4 5 7 8 10 11 13
+
say join ',', gather if False {
- take 1;
- take 2;
- take 3;
-} # Doesn't print anything.
+ take 1;
+ take 2;
+ take 3;
+}
+# Doesn't print anything.
-## - `eager` - Evaluate statement eagerly (forces eager context)
+## `eager` - evaluates a statement eagerly (forces eager context)
## Don't try this at home:
-##
-## eager 1..*; # this will probably hang for a while (and might crash ...).
-##
+# eager 1..*; # this will probably hang for a while (and might crash ...).
## But consider:
constant thrice = gather for ^3 { say take $_ }; # Doesn't print anything
-
## versus:
constant thrice = eager gather for ^3 { say take $_ }; #=> 0 1 2
```
@@ -1207,102 +1367,105 @@ constant thrice = eager gather for ^3 { say take $_ }; #=> 0 1 2
## Iterables
```perl6
-## Iterables are objects that can be iterated similar to the `for` construct
-## `flat`, flattens iterables:
-say (1, 10, (20, 10) ); #> (1 10 (20 10)) Notice how grouping is maintained
-say (1, 10, (20, 10) ).flat; #> (1 10 20 10) Now the iterable is flat
+## Iterables are objects that can be iterated over which are
+## are similar to the `for` construct.
-## - `lazy` - Defer actual evaluation until value is fetched
-## (forces lazy context)
+## `flat` - flattens iterables.
+say (1, 10, (20, 10) ); #=> (1 10 (20 10)), notice how neste lists are
+ # preserved
+say (1, 10, (20, 10) ).flat; #=> (1 10 20 10), now the iterable is flat
+
+## - `lazy` - defers actual evaluation until value is fetched by forcing
+## lazy context.
my @lazy-array = (1..100).lazy;
-say @lazy-array.is-lazy; #> True # Check for laziness with the `is-lazy` method.
-say @lazy-array; #> [...] List has not been iterated on!
+say @lazy-array.is-lazy; #=> True, check for laziness with the `is-lazy` method.
+say @lazy-array; #=> [...] List has not been iterated on!
my @lazy-array { .print }; # This works and will only do as much work as
# is needed.
-[//]: # ( TODO explain that gather/take and map are all lazy)
-## - `sink` - An `eager` that discards the results (forces sink context)
+
+# ( **TODO** explain that gather/take and map are all lazy)
+
+## `sink` - an `eager` that discards the results by forcing sink context.
constant nilthingie = sink for ^3 { .say } #=> 0 1 2
-say nilthingie.perl; #=> Nil
+say nilthingie.perl; #=> Nil
-## - `quietly` blocks will suppress warnings:
+## `quietly` - suppresses warnings in blocks.
quietly { warn 'This is a warning!' }; #=> No output
-## - `contend` - Attempts side effects under STM
-## Not yet implemented !
+## `contend` - attempts side effects under STM
+## Not yet implemented!
```
-## More operators thingies !
+## More operators thingies!
```perl6
-## Everybody loves operators ! Let's get more of them
+## Everybody loves operators! Let's get more of them.
## The precedence list can be found here:
## https://docs.perl6.org/language/operators#Operator_Precedence
## But first, we need a little explanation about associativity:
-## * Binary operators:
+## Binary operators:
$a ! $b ! $c; # with a left-associative `!`, this is `($a ! $b) ! $c`
$a ! $b ! $c; # with a right-associative `!`, this is `$a ! ($b ! $c)`
$a ! $b ! $c; # with a non-associative `!`, this is illegal
$a ! $b ! $c; # with a chain-associative `!`, this is `($a ! $b) and ($b ! $c)`
$a ! $b ! $c; # with a list-associative `!`, this is `infix:<>`
-## * Unary operators:
+## Unary operators:
!$a! # with left-associative `!`, this is `(!$a)!`
!$a! # with right-associative `!`, this is `!($a!)`
!$a! # with non-associative `!`, this is illegal
```
-### Create your own operators !
+### Create your own operators!
```perl6
-## Okay, you've been reading all of that, so I guess I should try
-## to show you something exciting.
-## I'll tell you a little secret (or not-so-secret):
+## Okay, you've been reading all of that, so you might want to try something
+## more exciting?! I'll tell you a little secret (or not-so-secret):
## In Perl 6, all operators are actually just funny-looking subroutines.
## You can declare an operator just like you declare a sub:
-sub prefix:<win>($winner) { # refer to the operator categories
- # (yes, it's the "words operator" `<>`)
- say "$winner Won !";
+# prefix refers to the operator categories (prefix, infix, postfix, etc).
+sub prefix:<win>( $winner ) {
+ say "$winner Won!";
}
-win "The King"; #=> The King Won !
- # (prefix is before)
+win "The King"; #=> The King Won!
+ # (prefix means 'before')
## you can still call the sub with its "full name":
-say prefix:<!>(True); #=> False
+say prefix:<!>(True); #=> False
+prefix:<win>("The Queen"); #=> The Queen Won!
-sub postfix:<!>(Int $n) {
- [*] 2..$n; # using the reduce meta-operator ... See below ;-) !
+sub postfix:<!>( Int $n ) {
+ [*] 2..$n; # using the reduce meta-operator... See below ;-)!
}
say 5!; #=> 120
- # Postfix operators (after) have to come *directly* after the term.
+ # Postfix operators ('after') have to come *directly* after the term.
# No whitespace. You can use parentheses to disambiguate, i.e. `(5!)!`
-
-sub infix:<times>(Int $n, Block $r) { # infix in the middle
- for ^$n {
- $r(); # You need the explicit parentheses to call the function in `$r`,
- # else you'd be referring at the variable itself, like with `&r`.
- }
+sub infix:<times>( Int $n, Block $r ) { # infix ('between')
+ for ^$n {
+ $r(); # You need the explicit parentheses to call the function in `$r`,
+ # else you'd be referring at the variable itself, like with `&r`.
+ }
}
3 times -> { say "hello" }; #=> hello
#=> hello
#=> hello
- # You're very recommended to put spaces
- # around your infix operator calls.
+## It's recommended to put spaces around your
+## infix operator calls.
## For circumfix and post-circumfix ones
-sub circumfix:<[ ]>(Int $n) {
- $n ** $n
+sub circumfix:<[ ]>( Int $n ) {
+ $n ** $n
}
say [5]; #=> 3125
- # circumfix is around. Again, no whitespace.
+ # circumfix means 'around'. Again, no whitespace.
-sub postcircumfix:<{ }>(Str $s, Int $idx) {
- ## post-circumfix is
- ## "after a term, around something"
- $s.substr($idx, 1);
+sub postcircumfix:<{ }>( Str $s, Int $idx ) {
+ ## post-circumfix is 'after a term, around something'
+ $s.substr($idx, 1);
}
say "abc"{1}; #=> b
# after the term `"abc"`, and around the index (1)
@@ -1312,47 +1475,47 @@ say "abc"{1}; #=> b
## (a simple named argument underneath):
%h{$key}:delete;
## equivalent to:
-postcircumfix:<{ }>(%h, $key, :delete); # (you can call operators like that)
+postcircumfix:<{ }>( %h, $key, :delete ); # (you can call operators like this)
-## It's *all* using the same building blocks!
-## Syntactic categories (prefix infix ...), named arguments (adverbs), ...,
-## - used to build the language - are available to you.
-## (you are, obviously, recommended against making an operator out of
-## *everything* -- with great power comes great responsibility)
+## It's *all* using the same building blocks! Syntactic categories
+## (prefix infix ...), named arguments (adverbs), ..., etc. used to build
+## the language - are available to you. Obviously, you're advised against
+## making an operator out of *everything* -- with great power comes great
+## responsibility.
```
-### Meta operators !
+### Meta operators!
```perl6
-## Oh boy, get ready. Get ready, because we're delving deep
-## into the rabbit's hole, and you probably won't want to go
-## back to other languages after reading that.
-## (I'm guessing you don't want to already at that point).
+## Oh boy, get ready!. Get ready, because we're delving deep into the rabbit's
+## hole, and you probably won't want to go back to other languages after
+## reading this. (I'm guessing you don't want to go back at this point but
+## let's continue, for the journey is long and enjoyable!).
+
## Meta-operators, as their name suggests, are *composed* operators.
-## Basically, they're operators that apply another operator.
+## Basically, they're operators that act on another operators.
+
+## The reduce meta-operator is a prefix meta-operator that takes a binary
+## function and one or many lists. If it doesn't get passed any argument,
+## it either returns a "default value" for this operator (a meaningless value)
+## or `Any` if there's none (examples below). Otherwise, it pops an element
+## from the list(s) one at a time, and applies the binary function to the last
+## result (or the list's first element) and the popped element.
-## * Reduce meta-operator
-## It's a prefix meta-operator that takes a binary function and
-## one or many lists. If it doesn't get passed any argument,
-## it either returns a "default value" for this operator
-## (a meaningless value) or `Any` if there's none (examples below).
-##
-## Otherwise, it pops an element from the list(s) one at a time, and applies
-## the binary function to the last result (or the list's first element)
-## and the popped element.
-##
## To sum a list, you could use the reduce meta-operator with `+`, i.e.:
-say [+] 1, 2, 3; #=> 6
-## equivalent to `(1+2)+3`
+say [+] 1, 2, 3; #=> 6, equivalent to (1+2)+3.
-say [*] 1..5; #=> 120
-## equivalent to `((((1*2)*3)*4)*5)`.
+## To multiply a list
+say [*] 1..5; #=> 120, equivalent to ((((1*2)*3)*4)*5).
## You can reduce with any operator, not just with mathematical ones.
-## For example, you could reduce with `//` to get
-## the first defined element of a list:
-say [//] Nil, Any, False, 1, 5; #=> False
- # (Falsey, but still defined)
+## For example, you could reduce with `//` to get first defined element
+## of a list:
+say [//] Nil, Any, False, 1, 5; #=> False
+ # (Falsey, but still defined)
+## Or with relational operators, i.e., `>` to check elements of a list
+## are ordered accordingly:
+say say [>] 234, 156, 6, 3, -20; #=> True
## Default value examples:
say [*] (); #=> 1
@@ -1365,15 +1528,14 @@ say [//]; #=> (Any)
sub add($a, $b) { $a + $b }
say [[&add]] 1, 2, 3; #=> 6
-## * Zip meta-operator
-## This one is an infix meta-operator that also can be used as a "normal"
-## operator. It takes an optional binary function (by default, it just creates
-## a pair), and will pop one value off of each array and call its binary
-## function on these until it runs out of elements. It returns an array with
-## all of these new elements.
-(1, 2) Z (3, 4); # ((1, 3), (2, 4)), since by default, the function
- # makes an array.
-1..3 Z+ 4..6; # (5, 7, 9), using the custom infix:<+> function
+## The zip meta-operator is an infix meta-operator that also can be used as a
+## "normal" operator. It takes an optional binary function (by default, it
+## just creates a pair), and will pop one value off of each array and call
+## its binary function on these until it runs out of elements. It returns an
+## array with all of these new elements.
+say (1, 2) Z (3, 4); #=> ((1, 3), (2, 4)), since by default the function
+ # makes an array.
+say 1..3 Z+ 4..6; #=> (5, 7, 9), using the custom infix:<+> function
## Since `Z` is list-associative (see the list above),
## you can use it on more than one list
@@ -1385,252 +1547,258 @@ say [[&add]] 1, 2, 3; #=> 6
## And to end the operator list:
-## * Sequence operator
## The sequence operator is one of Perl 6's most powerful features:
## it's composed of first, on the left, the list you want Perl 6 to deduce from
## (and might include a closure), and on the right, a value or the predicate
-## that says when to stop (or Whatever for a lazy infinite list).
-my @list = 1, 2, 3 ... 10; # basic deducing
-#my @list = 1, 3, 6 ... 10; # this dies because Perl 6 can't figure out the end
-my @list = 1, 2, 3 ...^ 10; # as with ranges, you can exclude the last element
- # (the iteration when the predicate matches).
-my @list = 1, 3, 9 ... * > 30; # you can use a predicate
- # (with the Whatever Star, here).
-my @list = 1, 3, 9 ... { $_ > 30 }; # (equivalent to the above)
-
-my @fib = 1, 1, *+* ... *; # lazy infinite list of fibonacci series,
- # computed using a closure!
+## that says when to stop (or a Whatever Star for a lazy infinite list).
+
+my @list = 1, 2, 3...10; # basic arithmetic sequence
+# my @list = 1, 3, 6...10; # this dies because Perl 6 can't figure out the end
+my @list = 1, 2, 3...^10; # as with ranges, you can exclude the last element
+ # (the iteration ends when the predicate matches).
+my @list = 1, 3, 9...* > 30; # you can use a predicate (with the Whatever Star).
+my @list = 1, 3, 9 ... { $_ > 30 }; # (equivalent to the above
+ # using a block here).
+
+my @fib = 1, 1, *+* ... *; # lazy infinite list of fibonacci sequence,
+ # computed using a closure!
my @fib = 1, 1, -> $a, $b { $a + $b } ... *; # (equivalent to the above)
-my @fib = 1, 1, { $^a + $^b } ... *; #(... also equivalent to the above)
+my @fib = 1, 1, { $^a + $^b } ... *; # (also equivalent to the above)
## $a and $b will always take the previous values, meaning here
-## they'll start with $a = 1 and $b = 1 (values we set by hand).
-## then $a = 1 and $b = 2 (result from previous $a+$b), and so on.
+## they'll start with $a = 1 and $b = 1 (values we set by hand),
+## then $a = 1 and $b = 2 (result from previous $a+$b), and so on.
say @fib[^10]; #=> 1 1 2 3 5 8 13 21 34 55
# (using a range as the index)
-## Note : as for ranges, once reified, elements aren't re-calculated.
+## Note: as for ranges, once reified, elements aren't re-calculated.
## That's why `@primes[^100]` will take a long time the first time you print
-## it, then be instant.
+## it, then will be instateneous.
```
## Regular Expressions
```perl6
-## I'm sure a lot of you have been waiting for this one.
-## Well, now that you know a good deal of Perl 6 already, we can get started.
-## First off, you'll have to forget about "PCRE regexps" (perl-compatible
-## regexps).
+## I'm sure a lot of you have been waiting for this one. Well, now that you know
+## a good deal of Perl 6 already, we can get started. First off, you'll have to
+## forget about "PCRE regexps" (perl-compatible regexps).
##
-## IMPORTANT: Don't skip them because you know PCRE. They're different.
-## Some things are the same (like `?`, `+`, and `*`),
-## but sometimes the semantics change (`|`).
-## Make sure you read carefully, because you might trip over a new behavior.
+## IMPORTANT: Don't skip them because you know PCRE. They're different. Some
+## things are the same (like `?`, `+`, and `*`), but sometimes the semantics
+## change (`|`). Make sure you read carefully, because you might trip over a
+## new behavior.
##
## Perl 6 has many features related to RegExps. After all, Rakudo parses itself.
-## We're first going to look at the syntax itself,
-## then talk about grammars (PEG-like), differences between
-## `token`, `regex` and `rule` declarators, and some more.
-## Side note: you still have access to PCRE regexps using the `:P5` modifier.
-## (we won't be discussing this in this tutorial, however)
+## We're first going to look at the syntax itself, then talk about grammars
+## (PEG-like), differences between `token`, `regex` and `rule` declarators,
+## and some more. Side note: you still have access to PCRE regexps using the
+## `:P5` modifier which we won't be discussing this in this tutorial, though.
##
## In essence, Perl 6 natively implements PEG ("Parsing Expression Grammars").
## The pecking order for ambiguous parses is determined by a multi-level
-## tie-breaking test:
-## - Longest token matching. `foo\s+` beats `foo` (by 2 or more positions)
-## - Longest literal prefix. `food\w*` beats `foo\w*` (by 1)
+## tie-breaking test:
+## - Longest token matching: `foo\s+` beats `foo` (by 2 or more positions)
+## - Longest literal prefix: `food\w*` beats `foo\w*` (by 1)
## - Declaration from most-derived to less derived grammars
-## (grammars are actually classes)
+## (grammars are actually classes)
## - Earliest declaration wins
-say so 'a' ~~ /a/; #=> True
-say so 'a' ~~ / a /; #=> True # More readable with some spaces!
+say so 'a' ~~ /a/; #=> True
+say so 'a' ~~ / a /; #=> True, more readable with some spaces!
## In all our examples, we're going to use the smart-matching operator against
-## a regexp. We're converting the result using `so`, but in fact, it's
-## returning a `Match` object. They know how to respond to list indexing,
-## hash indexing, and return the matched string.
-## The results of the match are available as `$/` (implicitly lexically-scoped).
-## You can also use the capture variables which start at 0:
-## `$0`, `$1', `$2`...
+## a regexp. We're converting the result using `so` to a Boolean value because,
+## in fact, it's returning a `Match` object. They know how to respond to list
+## indexing, hash indexing, and return the matched string. The results of the
+## match are available in the `$/` variable (implicitly lexically-scoped). You
+## can also use the capture variables which start at 0: `$0`, `$1', `$2`...
##
-## You can also note that `~~` does not perform start/end checking
-## (meaning the regexp can be matched with just one char of the string),
-## we're going to explain later how you can do it.
-
-## In Perl 6, you can have any alphanumeric as a literal,
-## everything else has to be escaped, using a backslash or quotes.
-say so 'a|b' ~~ / a '|' b /; # `True`. Wouldn't mean the same if `|` wasn't
- # escaped
-say so 'a|b' ~~ / a \| b /; # `True`. Another way to escape it.
-
-## The whitespace in a regexp is actually not significant,
-## unless you use the `:s` (`:sigspace`, significant space) adverb.
-say so 'a b c' ~~ / a b c /; #> `False`. Space is not significant here
-say so 'a b c' ~~ /:s a b c /; #> `True`. We added the modifier `:s` here.
+## You can also note that `~~` does not perform start/end checking, meaning
+## the regexp can be matched with just one character of the string. We'll
+## explain later how you can do it.
+
+## In Perl 6, you can have any alphanumeric as a literal, everything else has
+## to be escaped by using a backslash or quotes.
+say so 'a|b' ~~ / a '|' b /; #=> `True`, it wouldn't mean the same thing if
+ # `|` wasn't escaped.
+say so 'a|b' ~~ / a \| b /; #=> `True`, another way to escape it.
+
+## The whitespace in a regexp is actually not significant, unless you use the
+## `:s` (`:sigspace`, significant space) adverb.
+say so 'a b c' ~~ / a b c /; #=> `False`, space is not significant here!
+say so 'a b c' ~~ /:s a b c /; #=> `True`, we added the modifier `:s` here.
+
## If we use only one space between strings in a regex, Perl 6 will warn us:
-say so 'a b c' ~~ / a b c /; #> 'False' #> Space is not significant here;
-## please use quotes or :s (:sigspace) modifier (or, to suppress this warning,
-## omit the space, or otherwise change the spacing)
-## To fix this and make the spaces less ambiguous, either use at least two
-## spaces between strings or use the `:s` adverb.
+say so 'a b c' ~~ / a b c /; #=> `False`, with warning about space
+say so 'a b c' ~~ / a b c /; #=> `False`
+
+## Please use quotes or :s (:sigspace) modifier (or, to suppress this warning,
+## omit the space, or otherwise change the spacing). To fix this and make the
+## spaces less ambiguous, either use at least two spaces between strings
+## or use the `:s` adverb.
-## As we saw before, we can embed the `:s` inside the slash delimiters, but we
+## As we saw before, we can embed the `:s` inside the slash delimiters, but we
## can also put it outside of them if we specify `m` for 'match':
-say so 'a b c' ~~ m:s/a b c/; #> `True`
-## By using `m` to specify 'match', we can also use delimiters other
-## than slashes:
-say so 'abc' ~~ m{a b c}; #> `True`
+say so 'a b c' ~~ m:s/a b c/; #=> `True`
+
+## By using `m` to specify 'match', we can also use delimiters other than
+## slashes:
+say so 'abc' ~~ m{a b c}; #=> `True`
+say so 'abc' ~~ m[a b c]; #=> `True`
+# m/.../ is equivalent to /.../
## Use the :i adverb to specify case insensitivity:
-say so 'ABC' ~~ m:i{a b c}; #> `True`
+say so 'ABC' ~~ m:i{a b c}; #=> `True`
-## It is, however, important as for how modifiers (that you're gonna see just
-## below) are applied ...
+## However, whitespace is important as for how modifiers are applied (
+## (which you'll see just below) ...
## Quantifying - `?`, `+`, `*` and `**`.
-## - `?` - 0 or 1
-so 'ac' ~~ / a b c /; # `False`
-so 'ac' ~~ / a b? c /; # `True`, the "b" matched 0 times.
-so 'abc' ~~ / a b? c /; # `True`, the "b" matched 1 time.
+## `?` - zero or one match
+so 'ac' ~~ / a b c /; #=> `False`
+so 'ac' ~~ / a b? c /; #=> `True`, the "b" matched 0 times.
+so 'abc' ~~ / a b? c /; #=> `True`, the "b" matched 1 time.
-## ... As you read just before, whitespace is important because it determines
-## which part of the regexp is the target of the modifier:
-so 'def' ~~ / a b c? /; # `False`. Only the `c` is optional
-so 'def' ~~ / a b? c /; # `False`. Whitespace is not significant
-so 'def' ~~ / 'abc'? /; # `True`. The whole "abc" group is optional.
+## ...As you read before, whitespace is important because it determines which
+## part of the regexp is the target of the modifier:
+so 'def' ~~ / a b c? /; #=> `False`, only the `c` is optional
+so 'def' ~~ / a b? c /; #=> `False`, whitespace is not significant
+so 'def' ~~ / 'abc'? /; #=> `True`, the whole "abc" group is optional
## Here (and below) the quantifier applies only to the `b`
-## - `+` - 1 or more
-so 'ac' ~~ / a b+ c /; # `False`; `+` wants at least one matching
-so 'abc' ~~ / a b+ c /; # `True`; one is enough
-so 'abbbbc' ~~ / a b+ c /; # `True`, matched 4 "b"s
-
-## - `*` - 0 or more
-so 'ac' ~~ / a b* c /; # `True`, they're all optional.
-so 'abc' ~~ / a b* c /; # `True`
-so 'abbbbc' ~~ / a b* c /; # `True`
-so 'aec' ~~ / a b* c /; # `False`. "b"(s) are optional, not replaceable.
-
-## - `**` - (Unbound) Quantifier
-## If you squint hard enough, you might understand
-## why exponentation is used for quantity.
-so 'abc' ~~ / a b**1 c /; # `True` (exactly one time)
-so 'abc' ~~ / a b**1..3 c /; # `True` (one to three times)
-so 'abbbc' ~~ / a b**1..3 c /; # `True`
-so 'abbbbbbc' ~~ / a b**1..3 c /; # `False` (too much)
-so 'abbbbbbc' ~~ / a b**3..* c /; # `True` (infinite ranges are okay)
-
-## - `<[]>` - Character classes
-## Character classes are the equivalent of PCRE's `[]` classes, but
-## they use a more perl6-ish syntax:
-say 'fooa' ~~ / f <[ o a ]>+ /; #=> 'fooa'
+## `+` - one or more matches
+so 'ac' ~~ / a b+ c /; #=> `False`, `+` wants at least one matching
+so 'abc' ~~ / a b+ c /; #=> `True`, one is enough
+so 'abbbbc' ~~ / a b+ c /; #=> `True`, matched 4 "b"s
+
+## `*` - zero or more matches
+so 'ac' ~~ / a b* c /; #=> `True`, they're all optional.
+so 'abc' ~~ / a b* c /; #=> `True`
+so 'abbbbc' ~~ / a b* c /; #=> `True`
+so 'aec' ~~ / a b* c /; #=> `False`. "b"(s) are optional, not replaceable.
+
+## `**` - (Unbound) Quantifier
+## If you squint hard enough, you might understand why exponentation is used
+## for quantity.
+so 'abc' ~~ / a b**1 c /; #=> `True`, (exactly one time)
+so 'abc' ~~ / a b**1..3 c /; #=> `True`, (one to three times)
+so 'abbbc' ~~ / a b**1..3 c /; #=> `True`
+so 'abbbbbbc' ~~ / a b**1..3 c /; #=> `False, (too much)
+so 'abbbbbbc' ~~ / a b**3..* c /; #=> `True`, (infinite ranges are okay)
+
+## `<[]>` - Character classes
+## Character classes are the equivalent of PCRE's `[]` classes, but they use a
+## more perl6-ish syntax:
+say 'fooa' ~~ / f <[ o a ]>+ /; #=> 'fooa'
## You can use ranges:
say 'aeiou' ~~ / a <[ e..w ]> /; #=> 'ae'
-## Just like in normal regexes, if you want to use a special character,
-## escape it (the last one is escaping a space)
+## Just like in normal regexes, if you want to use a special character, escape
+## it (the last one is escaping a space which would be equivalent to using
+## ' '):
say 'he-he !' ~~ / 'he-' <[ a..z \! \ ]> + /; #=> 'he-he !'
-## You'll get a warning if you put duplicate names
-## (which has the nice effect of catching the wrote quoting:)
-'he he' ~~ / <[ h e ' ' ]> /; # Warns "Repeated characters found in characters
- # class"
+## You'll get a warning if you put duplicate names (which has the nice effect
+## of catching the raw quoting):
+'he he' ~~ / <[ h e ' ' ]> /;
+# Warns "Repeated character (') unexpectedly found in character class"
-## You can also negate them ... (equivalent to `[^]` in PCRE)
-so 'foo' ~~ / <-[ f o ]> + /; # False
+## You can also negate character classes... (`<-[]>` equivalent to `[^]` in PCRE)
+so 'foo' ~~ / <-[ f o ]> + /; #=> False
-## ... and compose them: :
-so 'foo' ~~ / <[ a..z ] - [ f o ]> + /; # False (any letter except f and o)
-so 'foo' ~~ / <-[ a..z ] + [ f o ]> + /; # True (no letter except f and o)
-so 'foo!' ~~ / <-[ a..z ] + [ f o ]> + /; # True (the + doesn't replace the
+## ... and compose them:
+so 'foo' ~~ / <[ a..z ] - [ f o ]> + /; #=> `False`, (any letter except f and o)
+so 'foo' ~~ / <-[ a..z ] + [ f o ]> + /; #=> `True`, (no letter except f and o)
+so 'foo!' ~~ / <-[ a..z ] + [ f o ]> + /; #=> `True`, (the + doesn't replace the
# left part)
```
### Grouping and capturing
```perl6
-## Group: you can group parts of your regexp with `[]`.
-## These groups are *not* captured (like PCRE's `(?:)`).
-so 'abc' ~~ / a [ b ] c /; # `True`. The grouping does pretty much nothing
+## Group: you can group parts of your regexp with `[]`. Unlike PCRE's `(?:)`,
+## these groups are *not* captured.
+so 'abc' ~~ / a [ b ] c /; # `True`. The grouping does pretty much nothing
so 'foo012012bar' ~~ / foo [ '01' <[0..9]> ] + bar /;
-## The previous line returns `True`.
-## We match the "012" 1 or more time (the `+` was applied to the group).
+
+## The previous line returns `True`. The regex matches "012" 1 or more time
+## (achieved by the the `+` applied to the group).
## But this does not go far enough, because we can't actually get back what
## we matched.
-## Capture: We can actually *capture* the results of the regexp,
-## using parentheses.
+
+## Capture: The results of a regexp can be *captured* by using parentheses.
so 'fooABCABCbar' ~~ / foo ( 'A' <[A..Z]> 'C' ) + bar /; # `True`. (using `so`
# here, `$/` below)
## So, starting with the grouping explanations.
-## As we said before, our `Match` object is available as `$/`:
-say $/; # Will print some weird stuff (we'll explain) (or "Nil" if
- # nothing matched).
+## As we said before, our `Match` object is stored inside the `$/` variable:
+say $/; # Will either print some weird stuff or `Nil` if nothing matched.
## As we also said before, it has array indexing:
say $/[0]; #=> 「ABC」 「ABC」
- # These weird brackets are `Match` objects.
+ # These corner brackets are `Match` objects.
# Here, we have an array of these.
-say $0; # The same as above.
+say $0; # The same as above.
-## Our capture is `$0` because it's the first and only one capture in the
+## Our capture is `$0` because it's the first and only one capture in the
## regexp. You might be wondering why it's an array, and the answer is simple:
-## Some capture (indexed using `$0`, `$/[0]` or a named one) will be an array
-## IFF it can have more than one element
-## (so, with `*`, `+` and `**` (whatever the operands), but not with `?`).
+## Some captures (indexed using `$0`, `$/[0]` or a named one) will be an array
+## if and only if they can have more than one element. Thus any capture with
+## `*`, `+` and `**` (whatever the operands), but not with `?`.
## Let's use examples to see that:
## Note: We quoted A B C to demonstrate that the whitespace between them isn't
-## significant. If we want the whitespace to *be* significant there, we
+## significant. If we want the whitespace to *be* significant there, we
## can use the :sigspace modifier.
-so 'fooABCbar' ~~ / foo ( "A" "B" "C" )? bar /; # `True`
-say $/[0]; #=> 「ABC」
+say so 'fooABCbar' ~~ / foo ( "A" "B" "C" )? bar /; #=> `True`
+say $/[0]; #=> 「ABC」
say $0.WHAT; #=> (Match)
# There can't be more than one, so it's only a single match object.
-so 'foobar' ~~ / foo ( "A" "B" "C" )? bar /; #=> True
+say so 'foobar' ~~ / foo ( "A" "B" "C" )? bar /; #=> True
say $0.WHAT; #=> (Any)
# This capture did not match, so it's empty
-so 'foobar' ~~ / foo ( "A" "B" "C" ) ** 0..1 bar /; # `True`
+so 'foobar' ~~ / foo ( "A" "B" "C" ) ** 0..1 bar /; #=> `True`
say $0.WHAT; #=> (Array)
# A specific quantifier will always capture an Array,
- # may it be a range or a specific value (even 1).
+ # be a range or a specific value (even 1).
-## The captures are indexed per nesting. This means a group in a group will be
+## The captures are indexed per nesting. This means a group in a group will be
## nested under its parent group: `$/[0][0]`, for this code:
'hello-~-world' ~~ / ( 'hello' ( <[ \- \~ ]> + ) ) 'world' /;
-say $/[0].Str; #=> hello~
+say $/[0].Str; #=> hello~
say $/[0][0].Str; #=> ~
-## This stems from a very simple fact: `$/` does not contain strings, integers
-## or arrays, it only contains match objects. These contain the `.list`, `.hash`
-## and `.Str` methods. (but you can also just use `match<key>` for hash access
-## and `match[idx]` for array access)
+## This stems from a very simple fact: `$/` does not contain strings, integers
+## or arrays, it only contains Match objects. These contain the `.list`, `.hash`
+## and `.Str` methods but you can also just use `match<key>` for hash access
+## and `match[idx]` for array access.
say $/[0].list.perl; #=> (Match.new(...),).list
- # We can see it's a list of Match objects. Those contain
- # a bunch of infos: where the match started/ended,
- # the "ast" (see actions later), etc.
+ # We can see it's a list of Match objects. These contain
+ # a bunch of info: where the match started/ended,
+ # the "ast" (see actions later), etc.
# You'll see named capture below with grammars.
-## Alternatives - the `or` of regexps
+## Alternation - the `or` of regexps
## WARNING: They are DIFFERENT from PCRE regexps.
-so 'abc' ~~ / a [ b | y ] c /; # `True`. Either "b" or "y".
-so 'ayc' ~~ / a [ b | y ] c /; # `True`. Obviously enough ...
-
-## The difference between this `|` and the one you're used to is LTM.
-## LTM means "Longest Token Matching". This means that the engine will always
-## try to match as much as possible in the strng
-'foo' ~~ / fo | foo /; # `foo`, because it's longer.
-## To decide which part is the "longest", it first splits the regex in
+say so 'abc' ~~ / a [ b | y ] c /; #=> `True`. Either "b" or "y".
+say so 'ayc' ~~ / a [ b | y ] c /; #=> `True`. Obviously enough...
+
+## The difference between this `|` and the one you're used to is
+## LTM ("Longest Token Matching"). This means that the engine will always
+## try to match as much as possible in the string.
+say 'foo' ~~ / fo | foo /; #=> `foo`, instead of `fo`, because it's longer.
+
+## To decide which part is the "longest", it first splits the regex in
## two parts:
## The "declarative prefix" (the part that can be statically analyzed)
-## and the procedural parts.
-## Declarative prefixes include alternations (`|`), conjunctions (`&`),
-## sub-rule calls (not yet introduced), literals, characters classes and
+## and the procedural parts:
+## - The declarative prefixes include alternations (`|`), conjunctions (`&`),
+## sub-rule calls (not yet introduced), literals, characters classes and
## quantifiers.
-## The latter include everything else: back-references, code assertions,
-## and other things that can't traditionnaly be represented by normal regexps.
+## - The procedural part include everything else: back-references,
+## code assertions, and other things that can't traditionnaly be represented
+## by normal regexps.
##
## Then, all the alternatives are tried at once, and the longest wins.
## Examples:
@@ -1639,109 +1807,110 @@ so 'ayc' ~~ / a [ b | y ] c /; # `True`. Obviously enough ...
## DECLARATIVE (nested groups are not a problem)
/ \s* [ \w & b ] [ c | d ] /;
## However, closures and recursion (of named regexps) are procedural.
-## ... There are also more complicated rules, like specificity
-## (literals win over character classes)
+## There are also more complicated rules, like specificity (literals win over
+## character classes).
## Note: the first-matching `or` still exists, but is now spelled `||`
-'foo' ~~ / fo || foo /; # `fo` now.
+say 'foo' ~~ / fo || foo /; #=> `fo` now.
```
## Extra: the MAIN subroutine
```perl6
-## The `MAIN` subroutine is called when you run a Perl 6 file directly.
-## It's very powerful, because Perl 6 actually parses the arguments
-## and pass them as such to the sub. It also handles named argument (`--foo`)
-## and will even go as far as to autogenerate a `--help`
-sub MAIN($name) { say "Hello, $name !" }
+## The `MAIN` subroutine is called when you run a Perl 6 file directly. It's
+## very powerful, because Perl 6 actually parses the arguments and pass them
+## as such to the sub. It also handles named argument (`--foo`) and will even
+## go as far as to autogenerate a `--help` flag.
+sub MAIN($name) {
+ say "Hello, $name!";
+}
## This produces:
-## $ perl6 cli.pl
-## Usage:
-## t.pl <name>
+## $ perl6 cli.pl
+## Usage:
+## t.pl <name>
## And since it's a regular Perl 6 sub, you can have multi-dispatch:
## (using a "Bool" for the named argument so that we can do `--replace`
-## instead of `--replace=1`)
+## instead of `--replace=1`. The presence of `--replace` indicates truthness
+## while its absence falseness).
+
subset File of Str where *.IO.d; # convert to IO object to check the file exists
multi MAIN('add', $key, $value, Bool :$replace) { ... }
multi MAIN('remove', $key) { ... }
multi MAIN('import', File, Str :$as) { ... } # omitting parameter name
+
## This produces:
-## $ perl6 cli.pl
-## Usage:
-## t.pl [--replace] add <key> <value>
-## t.pl remove <key>
-## t.pl [--as=<Str>] import (File)
-## As you can see, this is *very* powerful.
-## It even went as far as to show inline the constants.
-## (the type is only displayed if the argument is `$`/is named)
+## $ perl6 cli.pl
+## Usage:
+## cli.p6 [--replace] add <key> <value>
+## cli.p6 remove <key>
+## cli.p6 [--as=<Str>] import <File>
+
+## As you can see, this is *very* powerful. It even went as far as to show inline
+## the constants (the type is only displayed if the argument is `$`/is named).
```
## APPENDIX A:
### List of things
```perl6
-## It's considered by now you know the Perl6 basics.
-## This section is just here to list some common operations,
-## but which are not in the "main part" of the tutorial to bloat it up
+## It's assumed by now you know the Perl6 basics. This section is just here to
+## list some common operations, but which are not in the "main part" of the
+## tutorial to avoid bloating it up.
## Operators
-
-## * Sort comparison
-## They return one value of the `Order` enum : `Less`, `Same` and `More`
-## (which numerify to -1, 0 or +1).
-1 <=> 4; # sort comparison for numerics
-'a' leg 'b'; # sort comparison for string
-$obj eqv $obj2; # sort comparison using eqv semantics
-
-## * Generic ordering
-3 before 4; # True
-'b' after 'a'; # True
-
-## * Short-circuit default operator
-## Like `or` and `||`, but instead returns the first *defined* value :
-say Any // Nil // 0 // 5; #=> 0
-
-## * Short-circuit exclusive or (XOR)
-## Returns `True` if one (and only one) of its arguments is true
-say True ^^ False; #=> True
-## * Flip Flop
-## The flip flop operators (`ff` and `fff`, equivalent to P5's `..`/`...`).
-## are operators that take two predicates to test:
-## They are `False` until their left side returns `True`, then are `True` until
-## their right side returns `True`.
-## Like for ranges, you can exclude the iteration when it became `True`/`False`
-## by using `^` on either side.
-## Let's start with an example :
+## Sort comparison - they return one value of the `Order` enum: `Less`, `Same`
+## and `More` (which numerify to -1, 0 or +1 respectively).
+1 <=> 4; # sort comparison for numerics
+'a' leg 'b'; # sort comparison for string
+$obj eqv $obj2; # sort comparison using eqv semantics
+
+## Generic ordering
+3 before 4; # True
+'b' after 'a'; # True
+
+## Short-circuit default operator - similar to `or` and `||`, but instead
+## returns the first *defined* value:
+say Any // Nil // 0 // 5; #=> 0
+
+## Short-circuit exclusive or (XOR) - returns `True` if one (and only one) of
+## its arguments is true
+say True ^^ False; #=> True
+
+## Flip flops - these operators (`ff` and `fff`, equivalent to P5's `..`
+## and `...`) are operators that take two predicates to test: They are `False`
+## until their left side returns `True`, then are `True` until their right
+## side returns `True`. Similar to ranges, you can exclude the iteration when
+## it become `True`/`False` by using `^` on either side. Let's start with an
+## example :
for <well met young hero we shall meet later> {
- # by default, `ff`/`fff` smart-match (`~~`) against `$_`:
- if 'met' ^ff 'meet' { # Won't enter the if for "met"
- # (explained in details below).
- .say
- }
+ # by default, `ff`/`fff` smart-match (`~~`) against `$_`:
+ if 'met' ^ff 'meet' { # Won't enter the if for "met"
+ .say # (explained in details below).
+ }
- if rand == 0 ff rand == 1 { # compare variables other than `$_`
- say "This ... probably will never run ...";
- }
+ if rand == 0 ff rand == 1 { # compare variables other than `$_`
+ say "This ... probably will never run ...";
+ }
}
-## This will print "young hero we shall meet" (excluding "met"):
-## the flip-flop will start returning `True` when it first encounters "met"
-## (but will still return `False` for "met" itself, due to the leading `^`
-## on `ff`), until it sees "meet", which is when it'll start returning `False`.
-
-## The difference between `ff` (awk-style) and `fff` (sed-style) is that
-## `ff` will test its right side right when its left side changes to `True`,
-## and can get back to `False` right away
-## (*except* it'll be `True` for the iteration that matched) -
-## While `fff` will wait for the next iteration to
-## try its right side, once its left side changed:
+
+## This will print "young hero we shall meet" (excluding "met"): the flip-flop
+## will start returning `True` when it first encounters "met" (but will still
+## return `False` for "met" itself, due to the leading `^` on `ff`), until it
+## sees "meet", which is when it'll start returning `False`.
+
+## The difference between `ff` (awk-style) and `fff` (sed-style) is that `ff`
+## will test its right side right when its left side changes to `True`, and can
+## get back to `False` right away (*except* it'll be `True` for the iteration
+## that matched) while `fff` will wait for the next iteration to try its right
+## side, once its left side changed:
.say if 'B' ff 'B' for <A B C B A>; #=> B B
# because the right-hand-side was tested
# directly (and returned `True`).
- # "B"s are printed since it matched that
- # time (it just went back to `False`
+ # "B"s are printed since it matched that
+ # time (it just went back to `False`
# right away).
.say if 'B' fff 'B' for <A B C B A>; #=> B C B
# The right-hand-side wasn't tested until
@@ -1750,50 +1919,49 @@ for <well met young hero we shall meet later> {
## A flip-flop can change state as many times as needed:
for <test start print it stop not printing start print again stop not anymore> {
- .say if $_ eq 'start' ^ff^ $_ eq 'stop'; # exclude both "start" and "stop",
- #=> "print it print again"
+ .say if $_ eq 'start' ^ff^ $_ eq 'stop'; # exclude both "start" and "stop",
+ #=> "print it print again"
}
-## You might also use a Whatever Star,
-## which is equivalent to `True` for the left side or `False` for the right:
+## You might also use a Whatever Star, which is equivalent to `True` for the
+## left side or `False` for the right:
for (1, 3, 60, 3, 40, 60) { # Note: the parenthesis are superfluous here
# (sometimes called "superstitious parentheses")
- .say if $_ > 50 ff *; # Once the flip-flop reaches a number greater than 50,
- # it'll never go back to `False`
- #=> 60 3 40 60
+ .say if $_ > 50 ff *; # Once the flip-flop reaches a number greater
+ # than 50, it'll never go back to `False`
+ #=> 60 3 40 60
}
-## You can also use this property to create an `If`
-## that'll not go through the first time :
+## You can also use this property to create an `if` that'll not go through the
+## first time:
for <a b c> {
- .say if * ^ff *; # the flip-flop is `True` and never goes back to `False`,
- # but the `^` makes it *not run* on the first iteration
- #=> b c
+ .say if * ^ff *; # the flip-flop is `True` and never goes back to `False`,
+ # but the `^` makes it *not run* on the first iteration
+ #=> b c
}
-
-## - `===` is value identity and uses `.WHICH` on the objects to compare them
-## - `=:=` is container identity and uses `VAR()` on the objects to compare them
-
+## The `===` operator is the value identity operator and uses `.WHICH` on the
+## objects to compare them while `=:=` is the container identity operator
+## and uses `VAR()` on the objects to compare them.
```
If you want to go further, you can:
- Read the [Perl 6 Docs](https://docs.perl6.org/). This is a great
- resource on Perl6. If you are looking for something, use the search bar.
+ resource on Perl6. If you are looking for something, use the search bar.
This will give you a dropdown menu of all the pages referencing your search
- term (Much better than using Google to find Perl 6 documents!)
+ term (Much better than using Google to find Perl 6 documents!).
- Read the [Perl 6 Advent Calendar](http://perl6advent.wordpress.com/). This
- is a great source of Perl 6 snippets and explanations. If the docs don't
+ is a great source of Perl 6 snippets and explanations. If the docs don't
describe something well enough, you may find more detailed information here.
This information may be a bit older but there are many great examples and
- explanations. Posts stopped at the end of 2015 when the language was declared
+ explanations. Posts stopped at the end of 2015 when the language was declared
stable and Perl 6.c was released.
- - Come along on `#perl6` at `irc.freenode.net`. The folks here are
+ - Come along on `#perl6` at `irc.freenode.net`. The folks here are
always helpful.
- - Check the [source of Perl 6's functions and
- classes](https://github.com/rakudo/rakudo/tree/nom/src/core). Rakudo is
+ - Check the [source of Perl 6's functions and
+ classes](https://github.com/rakudo/rakudo/tree/nom/src/core). Rakudo is
mainly written in Perl 6 (with a lot of NQP, "Not Quite Perl", a Perl 6 subset
easier to implement and optimize).
- - Read [the language design documents](http://design.perl6.org). They explain
+ - Read [the language design documents](http://design.perl6.org). They explain
P6 from an implementor point-of-view, but it's still very interesting.
diff --git a/pl-pl/java-pl.html.markdown b/pl-pl/java-pl.html.markdown
new file mode 100644
index 00000000..0da449c5
--- /dev/null
+++ b/pl-pl/java-pl.html.markdown
@@ -0,0 +1,1026 @@
+---
+language: java
+filename: LearnJavaPl.java
+contributors:
+ - ["Jake Prather", "https://github.com/JakeHP"]
+ - ["Jakukyo Friel", "https://weakish.github.io"]
+ - ["Madison Dickson", "https://github.com/mix3d"]
+ - ["Simon Morgan", "https://sjm.io/"]
+ - ["Zachary Ferguson", "https://github.com/zfergus2"]
+ - ["Cameron Schermerhorn", "https://github.com/cschermerhorn"]
+ - ["Rachel Stiyer", "https://github.com/rstiyer"]
+ - ["Michael Dähnert", "https://github.com/JaXt0r"]
+ - ["Rob Rose", "https://github.com/RobRoseKnows"]
+ - ["Sean Nam", "https://github.com/seannam"]
+ - ["Shawn M. Hanes", "https://github.com/smhanes15"]
+filename: LearnJava.java
+translators:
+ - ["Jacek Wachowiak", "https://github.com/jacekwachowiak"]
+lang: pl-pl
+---
+
+Java jest współbieżnym, opartym na klasach, obiektowym językiem programowania
+ogólnego zastosowania.
+[Tu znajdziesz więcej informacji po angielsku.]
+(https://docs.oracle.com/javase/tutorial/java/)
+
+```java
+// Pojedyncze komentarze oznaczamy //
+
+/*
+Komentarze wieloliniowe wyglądają tak
+*/
+
+/**
+ * Komentarze JavaDoc wygladają w ten sposób. Używane są do opisu klas lub
+ * różnych właściwości klas.
+ * Główne właściwości:
+ *
+ * @author Imię i nazwisko (i kontakt np. email) autora.
+ * @version Aktualna wersja programu.
+ * @since Kiedy ta część programu została dodana.
+ * @param Służy do opisu parametrów metody.
+ * @return Służy do opisu zwracanej wartości.
+ * @deprecated Służy do oznaczenia nieaktualnego lub niezalecanego kodu.
+ * @see Linki do innej cześci dokumentacji.
+*/
+
+// Import klasy ArrayList z paczki java.util
+import java.util.ArrayList;
+// Import wszystkich klas z paczki java.security
+import java.security.*;
+
+public class LearnJava {
+
+ // Aby móc uruchomić program w języku java musi on mieć główną metodę jako
+ // punkt wejścia.
+ public static void main(String[] args) {
+
+ ///////////////////////////////////////
+ // Operacje wejścia/wyjścia (input/output)
+ ///////////////////////////////////////
+
+ /*
+ * Wyjście
+ */
+
+ // System.out.println() służy do wyświetlania linii tekstu.
+ System.out.println("Hello World!");
+ System.out.println(
+ "Integer: " + 10 +
+ " Double: " + 3.14 +
+ " Boolean: " + true);
+
+ // Aby wyświetlić bez nowej linii użyj System.out.print().
+ System.out.print("Hello ");
+ System.out.print("World");
+
+ // System.out.printf() służy do łatwego formatowania wyświetlanego elementu.
+ System.out.printf("pi = %.5f", Math.PI); // => pi = 3.14159
+
+ /*
+ * Wejście
+ */
+
+ // Scanner służy do wczytywania danych
+ // niezbędny jest import java.util.Scanner;
+ Scanner scanner = new Scanner(System.in);
+
+ // zczytaj string (tekst)
+ String name = scanner.next();
+
+ // zczytaj zmienną typu bajt
+ byte numByte = scanner.nextByte();
+
+ // zczytaj zmienną typu integer - liczba całkowita
+ int numInt = scanner.nextInt();
+
+ // zczytaj zmienną typu float - liczba zmiennoprzecinkowa
+ float numFloat = scanner.nextFloat();
+
+ // zczytaj zmienna typu double -liczba zmiennoprzecinkowa
+ double numDouble = scanner.nextDouble();
+
+ // zczytaj zmienną typu boolowskiego -
+ boolean bool = scanner.nextBoolean();
+
+ ///////////////////////////////////////
+ // Zmienne
+ ///////////////////////////////////////
+
+ /*
+ * Deklaracja zmiennych
+ */
+ // Zmienną deklaruje się poprzez <rodzaj> <nazwa>
+ int fooInt;
+ // Dozwolona jest deklaracja wielu zmiennych tego samego typu na raz
+ // rodzaj <nazwa1>, <nazwa2>, <nazwa3>
+ int fooInt1, fooInt2, fooInt3;
+
+ /*
+ * Inicjalizacja zmiennych
+ */
+
+ // Zmienną inicjalizuje się poprzez <rodzaj> <nazwa> = <wartość>
+ int barInt = 1;
+ // Możliwe jest zainicjalizowanie wielu zmiennych tego samego typu tą samą wartością
+ // rodzaj <nazwa1>, <nazwa2>, <nazwa3>
+ // <nazwa1> = <nazwa2> = <nazwa3> = <wartość>
+ int barInt1, barInt2, barInt3;
+ barInt1 = barInt2 = barInt3 = 1;
+
+ /*
+ * Rodzaje zmiennych
+ */
+ // Bajt - 8-bitowa, zawierająca ujemne wartości zmienna w dwójkowym
+ // systemie pozycyjnym
+ // (-128 <= byte <= 127)
+ byte fooByte = 100;
+
+ // Jeśli chcemy zinterpretować bajt jako zmienną typu unsigned integer
+ // - liczbę całkowitą z wartościami ujemnymi ta operacja może pomóc:
+ int unsignedIntLessThan256 = 0xff & fooByte;
+ // jako kontrast operacja zmiany typu która może zwrócić wartość ujemną.
+ int signedInt = (int) fooByte;
+
+ // Short - 16-bitowa, zawierająca ujemne wartości zmienna w dwójkowym
+ // systemie pozycyjnym (-32,768 <= short <= 32,767)
+ short fooShort = 10000;
+
+ // Integer - 32-bitowa, zawierająca ujemne wartości zmienna w dwójkowym systemie pozycyjnym
+ // (-2,147,483,648 <= int <= 2,147,483,647)
+ int bazInt = 1;
+
+ // Long - 64-bitowa, zawierająca ujemne wartości zmienna w dwójkowym
+ // systemie pozycyjnym
+ // (-9,223,372,036,854,775,808 <= long <= 9,223,372,036,854,775,807)
+ long fooLong = 100000L;
+ // L jest używane do zaznaczenia, że wartość zmiennej jest typu Long;
+ // bez L wszystko inne będzie traktowane z założenia jako integer.
+
+ // Uwaga: byte, short, int and long zawierają ujemne wartości.
+ // Nie istnieją odpowiedniki z jedynie pozytywnymi wartościami.
+ // Jedynie char jest 16-bitowym typem zmiennej, który akceptuje tylko
+ // wartości nieujemne.
+
+ // Float - 32-bitowy typ zmiennoprzecinkowy zgodnie z IEEE 754
+ // Floating Point 2^-149 <= float <= (2-2^-23) * 2^127
+ float fooFloat = 234.5f;
+ // f or F jest używane aby zaznaczyć, że dana zmienna jest typu float;
+ // w przeciwnym razie będzie ona traktowana jako double.
+
+ // Double - 64-bitowy typ zmiennoprzecinkowy zgodnie z IEEE 754
+ // Floating Point 2^-1074 <= x <= (2-2^-52) * 2^1023
+ double fooDouble = 123.4;
+
+ // Typ boolowski - true/prawda & false/fałsz
+ boolean fooBoolean = true;
+ boolean barBoolean = false;
+
+ // Char - pojedynczy 16-bitowy symbol Unicode
+ char fooChar = 'A';
+
+ // zmienne zadeklarowane z użyciem final nie mogą być edytowane,
+ final int HOURS_I_WORK_PER_WEEK = 9001;
+ // ale możliwa jest późniejsza inicjalizacja.
+ final double E;
+ E = 2.71828;
+
+ // BigInteger - Nieedytowalny typ zmiennej o nieograniczonej długości
+ // dla liczb całkowitych
+ //
+ // BigInteger jest typem zmiennej, który pozwala na operacje na liczbach całkowitych dłuższych niż 64 bity.
+ // Liczby są przechowywane jako tablica bajtów
+ // i modyfikowane za pomocą funkcji wbudowanych w BigInteger
+ //
+ // BigInteger może być zainicjalizowany za pomocą tablicy bajtów lub jako string.
+ BigInteger fooBigInteger = new BigInteger(fooByteArray);
+
+ // BigDecimal - Nieedytowalny typ zmiennej o nieograniczonej długości dla
+ // liczb zmiennoprzecinkowych
+ //
+ // BigDecimal zaiwera 2 części: typ integer o arbitralnej precyzji bez skalowania
+ // oraz 32-bitową skalę
+ //
+ // BigDecimal pozwala programiście na całkowitą kontrolę zaokrąglenia dziesiętnego.
+ // Zalecane jest używanie BigDecimal z wartościami walut.
+ // oraz tam, gdzie absolutna dokładność jest niezbędna.
+ //
+ // BigDecimal można zainicjalizowac używając int, long, double or String
+ // a także inicjalizując nieprzeskalowaną wartość (BigInteger) i skalę (int).
+ BigDecimal fooBigDecimal = new BigDecimal(fooBigInteger, fooInt);
+
+ // Uwaga na konstruktor, który przyjmuje float lub double jako, że
+ // niedokładność float/double będzie przeniesiona do BigDecimal.
+ // Zalecane jest uzywanie konstruktora typu String gdy konieczne jest
+ // uzyskanie absolutnej precyzji.
+ BigDecimal tenCents = new BigDecimal("0.1");
+
+ // String - zmienna tekstowa
+ String fooString = "Tutaj jest mój string!";
+
+ // \n jest symbolem karetki, która rozpoczyna nową linę
+ String barString = "Wyświetlanie w nowej linii?\nNie ma problemu!";
+ // \t jest symbolem tabulatora, który dodaje odstęp.
+ String bazString = "Chesz dodać tabulator?\tBez problemu!";
+ System.out.println(fooString);
+ System.out.println(barString);
+ System.out.println(bazString);
+
+ // Budowanie Stringów
+ // #1 - za pomocą operatora dodawania
+ // To jest podstawowy sposób (zoptymalizowany)
+ String plusConcatenated = "Stringi mogą " + "być łączone " + "operatorem +.";
+ System.out.println(plusConcatenated);
+ // Wyjście: Stringi będą połączone operatorem +.
+
+ // #2 - za pomocą StringBuilder
+ // Ten sposób nie tworzy żadnych pośrednich stringów, jedynie zachowuje
+ // części i wiąże je po kolei gdy wywołane jest toString().
+ // Wskazówka: Ta klasa nie jest bezpieczna z punktu widzenia wątków.
+ // Bezpieczną alternatywą jest (wiążąca się ze spadkiem wydajności)
+ // StringBuffer.
+ StringBuilder builderConcatenated = new StringBuilder();
+ builderConcatenated.append("Możesz ");
+ builderConcatenated.append("użyć ");
+ builderConcatenated.append("klasy StringBuilder.");
+ System.out.println(builderConcatenated.toString()); // dopiero tutaj
+ //budowany jest string
+ // Wyjście: Używany jest StringBuilder.
+
+ // StringBuilder jest wydajny, gdy połączony string nie jest używany aż do końcowego przetworzenia.
+ StringBuilder stringBuilder = new StringBuilder();
+ String inefficientString = "";
+ for (int i = 0 ; i < 10; i++) {
+ stringBuilder.append(i).append(" ");
+ inefficientString += i + " ";
+ }
+ System.out.println(inefficientString);
+ System.out.println(stringBuilder.toString());
+ // inefficientString wymaga dużo więcej pracy przy stworzeniu ponieważ
+ // tworzy string przy każdej iteracji.
+ // Proste łączenie za pomocą + jest kompilowane do StringBuilder i
+ // toString(). Unikaj łączenia stringów w pętlach.
+
+ // #3 - za pomocą String formatter
+ // Inna możliwość, szybka i czytelna.
+ String.format("%s wolisz %s.", "A może", "String.format()");
+ // Wyjście: Być może wolisz String.format().
+
+ // Tablice
+ // Rozmiar tablicy musi być określony przy stworzeniu.
+ // Podane poniżej sposoby są dozwolone prz deklaracji tablicy
+ // <rodzaj>[] <nazwa> = new <rodzaj>[<rozmiar>];
+ // <rodzaj> <nazwa>[] = new <rodzaj>[<rozmiar>];
+ int[] intArray = new int[10];
+ String[] stringArray = new String[1];
+ boolean boolArray[] = new boolean[100];
+
+ // Inny sposób deklaracji i inicjalizacji tablicy
+ int[] y = {9000, 1000, 1337};
+ String names[] = {"Bob", "John", "Fred", "Juan Pedro"};
+ boolean bools[] = {true, false, false};
+
+ // Indeksowanie tablicy - dostęp do elementów
+ System.out.println("intArray @ 0: " + intArray[0]);
+
+ // Tablice zaczynają się z indeksem 0 i są edytowalne.
+ intArray[1] = 1;
+ System.out.println("intArray @ 1: " + intArray[1]); // => 1
+
+ // Inny typ zmiennej, z którymi warto się zapoznać
+ // ArrayLists - Tablice z większą funkcjonalnością
+ // i zmiennym rozmiarem.
+ // LinkedLists - Dwustronnie połączone listy. Wszystkie operacje
+ // na listach zaimpllementowane.
+ // Maps - Mapy zawierające klucz i wartość. Mapa jest interfejsem
+ // i nie może zostać zainicjalizowana.
+ // Rodzaj klucza i wartości dla mapy musi zostać określony
+ // przy inicjalizacji implementującej mapę klasy
+ // Każdy klucz przypisany jest do tylko jednej wartości,
+ // każdy klucz może wystąpić tylko raz (brak duplikatów).
+ // HashMaps - Używa tablicy hashów do implementacji interfejsu mapy
+ // Pozwala to na użycie podstawowych operacji, jak
+ // get i insert, które pozostają niezmiennie wydajne
+ // czasowo nawet dla dużych zestawów danych
+ // TreeMap - Mapa posortowana przez klucze. Każda modyfikacja
+ // utrzymuje sortowanie, zdefiniowane przez komparator
+ // dodany przy inicjalizacji lub porównanie każdego obiektu
+ // jeśli zaimplementowany jest interfejs Comparable.
+ // Niepowodzenie kluczy wimplemntacji Comparable połączone
+ // z niepowodzeniem dostarczenia komparatora spowoduje
+ // ClassCastExceptions.
+ // Dodawanie i usuwanie kosztuje O(log(n)) czasu,
+ // zalecane jest nieużywanie tego typu jeżeli sortowanie
+ // nie jest przydatne.
+
+ ///////////////////////////////////////
+ // Operatory
+ ///////////////////////////////////////
+ System.out.println("\n->Operatory");
+
+ int i1 = 1, i2 = 2; // Skrót dla wielokrotnych deklaracji
+
+ // Arytmetyka jest prosta
+ 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 (int/int zwraca int)
+ System.out.println("1/2.0 = " + (i1 / (double)i2)); // => 0.5
+
+ // Modulo
+ System.out.println("11%3 = "+(11 % 3)); // => 2
+
+ // Porównania
+ 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
+
+ // Operacje boolowskie
+ System.out.println("3 > 2 && 2 > 3? " + ((3 > 2) && (2 > 3))); // => false
+ System.out.println("3 > 2 || 2 > 3? " + ((3 > 2) || (2 > 3))); // => true
+ System.out.println("!(3 == 2)? " + (!(3 == 2))); // => true
+
+ // Operacje na bitach!
+ /*
+ ~ Odwrócenie bitów
+ << Przesunięcie w lewo
+ >> Przesunięcie w prawo, arytmetyczne/dla wartości ujemnych -signed
+ >>> Przesunięcie w prawo, logiczne/dla wartości dodatnich - unsigned
+ & Bitowe AND
+ ^ Bitowe XOR
+ | Bitowe OR
+ */
+
+ // Operatory inkrementacji
+ int i = 0;
+ System.out.println("\n->In/De-krementacja");
+ // Operatory ++ i -- zwiększają lub zmniejszają o 1 daną wartość.
+ // Jeżeli używane są przed zmienną, wykonywane są przed powrotem zmiennej.
+ // Użyte po zmiennej najpierw zwracają zmienną a następnie dokonują
+ // zmiany wartości.
+ System.out.println(i++); // i = 1, wyświetli 0 (post-increment)
+ System.out.println(++i); // i = 2, wyświetli 2 (pre-increment)
+ System.out.println(i--); // i = 1, wyświetli 2 (post-decrement)
+ System.out.println(--i); // i = 0, wyświetli 0 (pre-decrement)
+
+ ///////////////////////////////////////
+ // Przepływ sterowania
+ ///////////////////////////////////////
+ System.out.println("\n->Przepływ sterowania");
+
+ // Instrukcja if wygląda jak w c
+ int j = 10;
+ if (j == 10) {
+ System.out.println("Wyświetlam się");
+ } else if (j > 10) {
+ System.out.println("A ja nie");
+ } else {
+ System.out.println("Ja też nie");
+ }
+
+ // Pętla while
+ int fooWhile = 0;
+ while(fooWhile < 100) {
+ System.out.println(fooWhile);
+ // Licznik jest zwiększany
+ // Iteruje 100 razy, fooWhile 0,1,2...99
+ fooWhile++;
+ }
+ System.out.println("Wartość fooWhile: " + fooWhile);
+
+ // Pętla do while
+ int fooDoWhile = 0;
+ do {
+ System.out.println(fooDoWhile);
+ // Licznik jest zwiększany
+ // Iteruje 99 razy, fooDoWhile 0->99
+ fooDoWhile++;
+ } while(fooDoWhile < 100);
+ System.out.println("Wartość fooDoWhile: " + fooDoWhile);
+
+ // Pętla for
+ // struktura pętli for => for(<początek>; <warunek>; <krok>)
+ for (int fooFor = 0; fooFor < 10; fooFor++) {
+ System.out.println(fooFor);
+ // Iteruje 10 razy, fooFor 0->9
+ }
+ System.out.println("Wartość fooFor: " + fooFor);
+
+ // Wyjście z zagnieżdżonej, oznaczonej pętli for
+ outer:
+ for (int i = 0; i < 10; i++) {
+ for (int j = 0; j < 10; j++) {
+ if (i == 5 && j ==5) {
+ break outer;
+ // wychodzi z zewnętrznej pętli zamiast jednynie z aktualnej z
+ // powodu oznaczenia
+ }
+ }
+ }
+
+ // Pętla for each
+ // Pętla for each może iterować tablice jak i obiekty
+ // które implementują interfejs Iterable.
+ int[] fooList = {1, 2, 3, 4, 5, 6, 7, 8, 9};
+ // Struktura for each => for (<element> : <obiekt iterowany>)
+ // należy rozumieć jako: dla każdego elementu w obiekcie iterowanym
+ // uwaga: typ zdefiniowango elementu musi się zgadzać z typem w
+ //obiekcie iterowanym.
+ for (int bar : fooList) {
+ System.out.println(bar);
+ //Iteruje 9 razy i wyświetla 1-9 w nowych liniach
+ }
+
+ // Switch Case
+ // Switch (przełącznik) działa z zmiennymi typu byte, short, char, int.
+ // Działa również z enumeratorami (zobacz typ Enum),
+ // klasą String, i kilkoma specjalnymi klasami które zawierają typy
+ // podstawowe: Character, Byte, Short, and Integer.
+ // Z wersją Java 7 i wyższymi możliwe jest użycie typu String.
+ // Uwagga: Pamiętaj, że nie dodając "break" na końcu danego case
+ // spowoduje przejście do następnego (jeżeli spełniony jest warunek).
+ int month = 3;
+ String monthString;
+ switch (month) {
+ case 1: monthString = "Styczeń";
+ break;
+ case 2: monthString = "Luty";
+ break;
+ case 3: monthString = "Marzec";
+ break;
+ default: monthString = "Inny miesiąc";
+ break;
+ }
+ System.out.println("Wynik Switch Case : " + monthString);
+
+
+ // Try-with-resources (Java 7+)
+ // Try-catch-finally działa zgodnie z oczekiwaniami jednakże w Java 7+
+ // dodatkowo jest dostępny try-with-resources statement.
+ // Try-with-resources upraszcza try-catch-finally automatycznie
+ // usuwając zasoby.
+
+ // Aby użyć try-with-resources, użyj instancji klasy
+ // w części "try". Klasa musi implementować java.lang.AutoCloseable.
+ try (BufferedReader br = new BufferedReader(new FileReader("foo.txt"))) {
+ // Tutaj możesz spróbować wywołac wyjątek.
+ System.out.println(br.readLine());
+ // W Java 7 zasoby będą zawsze usuwane nawet jeśli nastąpi wyjątek.
+ } catch (Exception ex) {
+ // Zasób będzie usunięty zanim wykona się catch.
+ System.out.println("readLine() nie powiódł się.");
+ }
+ // Nie ma potrzeby używać sekcji "finally", jako że BufferedReader
+ // został już zamknięty. Ten sposób może zostać użyty aby uniknąć
+ // pewnych wartości brzegowych gdzie "finally" nie zostałoby wywołane
+ // Więcej na ten temat po angielsku:
+ // https://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html
+
+
+ // Skrócone instrukcje warunkowe
+ // Dozwolone jest użycie operatora '?' aby szybko sprawdzić warunek
+ // logiczny. Rozumiane jest to jako "Jeśli (warunek) jest spełniony, użyj
+ // <pierwszej wartości>, inaczej, użyj <drugiej wartości>"
+ int foo = 5;
+ String bar = (foo < 10) ? "A" : "B";
+ System.out.println("bar : " + bar); // Wyśwletli "bar : A", poineważ
+ // warunke jest spełniony.
+ // Lub prościej
+ System.out.println("bar : " + (foo < 10 ? "A" : "B"));
+
+
+ ////////////////////////////////////////
+ // Konwersja typów danych
+ ////////////////////////////////////////
+
+ // Konwersja danych
+
+ // Konwersja String do Integer
+ Integer.parseInt("123");//zwraca zmienna typu Integer o wartości "123"
+
+ // Konwersja Integer do String
+ Integer.toString(123);//zwraca zmienną typu String o wartości 123
+
+ // Inne konwersje możesz sprawdzić dla klas:
+ // Double
+ // Long
+ // String
+
+ ///////////////////////////////////////
+ // Klasy i funkcje
+ ///////////////////////////////////////
+
+ System.out.println("\n->Klasy & Funkcje");
+
+ // (definicja klasy Rower nieco niżej)
+
+ // Użyj new aby zainstancjonować klasę
+ Rower trek = new Rower();
+
+ // Wywoływanie metod klasy
+ trek.predkoscZwieksz(3); // Zawsze używaj settera i gettera jako metod
+ trek.setPedalowanie(100);
+
+ // toString zwraca reprezentację typu String tego obiektu.
+ System.out.println("trek info: " + trek.toString());
+
+ // Inicjalizacja za pomocą podwójnego nawiasu
+ // Język Java nie zawiera możliwości stworzenia statycznej kolekcji
+ // Dlatego zwykle odbywa się to w ten sposób:
+ private static final Set<String> KRAJE = new HashSet<String>();
+ static {
+ KRAJE.add("DANIA");
+ KRAJE.add("SZWECJA");
+ KRAJE.add("FINLANDIA");
+ }
+
+ // Jest jednak sprytny sposób aby łatwiej osiągnąc ten sam efekt
+ // używając czegoś nazywanego Double Brace Initialization -
+ // inicjalizacja za pomocą podwójnego nawiasu.
+ private static final Set<String> KRAJE = new HashSet<String>() {{
+ add("DANIA");
+ add("SZWECJA");
+ add("FINLANDIA");
+ }}
+
+ // Pierwszy nawias tworzy nową klasę AnonymousInnerClass,
+ // drugi deklaruje instancję bloku inicjalizacji. Blok ten
+ // jest wywoływany gdy wewnętrzna, anonimowa klasa jest tworzona.
+ // Dany sposób działa nie tylko dla kolekcji, ale również dla
+ // wszystkich nie-finalnych klas.
+
+ } // Koniec metody main
+} // Koniec klasy LearnJava
+
+// Możesz zawrzeć inne, niepubliczne, zewnętrzne klasy w pliku .java,
+// jednak nie jest to zalecane. Zalecane jest dzielenie klas na osobne pliki.
+
+// Składnia deklaracji klasy:
+// <public/private/protected> class <nazwa klasy> {
+// // pola danych, konstruktory, funkcje.
+// // w jężyku Java funkcje są wywoływane jako metody.
+// }
+
+class Rower {
+
+ // Zmienne klasy
+ public int pedalowanie; // Public: Dostępne wszędzie
+ private int predkosc; // Private: Dostępne tylko w klasie
+ protected int przerzutka; // Protected: Dostępne w klasie i podklasach
+ String nazwa; // domyślnie: Dostępne tlyko w danej paczce
+ static String nazwaKlasy; // Zmienna statyczna
+
+ // Blok statyczny
+ // Java nie posiada implemntacji konstruktorów staycznych, ale
+ // posiada blok stayczny, który może być użyty aby zainicjalizować
+ // statyczne zmienne klasy
+ // Ten blok będzie wywołane gdy klasa jest ładowana.
+ static {
+ nazwaKlasy = "Rower";
+ }
+
+ // Konstruktory służą do stworzenia instancji klas
+ // Too jest konstruktor
+ public Rower() {
+ // Możesz wywołać także inny konstruktor:
+ // this(1, 50, 5, "Bontrager");
+ przerzutka = 1;
+ pedalowanie = 50;
+ predkosc = 5;
+ nazwa = "Bontrager";
+ }
+ // To jest konstruktor, który przyjmuje argumenty
+ public Rower(int poczatkowePedalowanie, int poczatkowaPredkosc, int początkowaPrzerzutka,
+ String nazwa) {
+ this.przerzutka = początkowaPrzerzutka;
+ this.pedalowanie = poczatkowePedalowanie;
+ this.predkosc = poczatkowaPredkosc;
+ this.nazwa = nazwa;
+ }
+
+ // Składnia metod:
+ // <public/private/protected> <zwracany rodzaj> <nazwa funkcji>(<argumenty>)
+
+ // Klasy często implementują metody getter i setter dla danych wewnątrz
+
+ // Składnia deklaracji metody:
+ // <dostępność> <zwracany rodzaj> <nawa metody>(<argumenty>)
+ public int getPedalowanie() {
+ return pedalowanie;
+ }
+
+ // metody void nie wymagają słowa kluczowego return, nic nie zwracają
+ public void setPedalowanie(int newValue) {
+ pedalowanie = newValue;
+ }
+ public void setPrzerzutka(int newValue) {
+ przerzutka = newValue;
+ }
+ public void predkoscZwieksz(int inkrement) {
+ predkosc += inkrement;
+ }
+ public void predkoscZmniejsz(int dekrement) {
+ predkosc -= dekrement;
+ }
+ public void nadajNazwe(String nowaNazwa) {
+ nazwa = nowaNazwa;
+ }
+ public String zwrocNazwe() {
+ return nazwa;
+ }
+
+ // Metoda do wyświetlenia wartości atrybutów danego obiektu.
+ @Override // Dziedziczy z klasy obiektu.
+ public String toString() {
+ return "przerzutka: " + przerzutka + " pedalowanie: " + pedalowanie + " predkosc: " + predkosc +
+ " nazwa: " + nazwa;
+ }
+} // koniec klasy Rower
+
+// PennyFarthing jest podklasą klasy Rower
+class PennyFarthing extends Rower {
+ // (Penny Farthing to rower z wielkim przednim kołem.
+ // Nie ma przerzutek.)
+
+ public PennyFarthing(int poczatkowePedalowanie, int poczatkowaPredkosc) {
+ // Wywołanie kostruktora klasy z której dziedziczymy za pomocą super
+ super(poczatkowePedalowanie, poczatkowaPredkosc, 0, "PennyFarthing");
+ }
+
+ // Używamy annotacji @annotation przy przeciążaniu metod.
+ // Aby dowiedzieć się więcej o annotacjach przydatne jest przejrzenie
+ // (w języku angielskim):
+ // http://docs.oracle.com/javase/tutorial/java/annotations/
+ @Override
+ public void setPrzerzutka(int przerzutka) {
+ this.przerzutka = 0;
+ }
+}
+
+// Rzutowanie
+// Jako, że klasa PennyFarthing dziedziczy z klasy Rower, możemy uznać, że
+// instancja PennyFarthing jest typu Rower i napisać :
+// Rower rower = new PennyFarthing();
+// Dana operacja jest rzutowaniem obiektu, gdzie jego domyślna klasa jest inna niż docelowa.
+// Więcej szczegółów i przykładów oraz ciekawych konceptów (po angielsku):
+// https://docs.oracle.com/javase/tutorial/java/IandI/subclasses.html
+
+// Interfejsy
+// Składnia deklaracji interfejsu
+// <dostępność> interface <nazwa interfejsu> extends <super-interfaces> {
+// // Zmienne typu constant
+// // Deklaracje metod
+// }
+
+// Przykład - Jedzenie:
+public interface Jadalne {
+ public void jedz(); // Każda klasa która implemetuje ten interfejs musi
+ // implementować tę metodę.
+}
+
+public interface Przetrawialne {
+ public void przetrawiaj();
+ // Wraz z Java 8, interfejsy mogą mieć metodę domyślną.
+ public default void defaultMethod() {
+ System.out.println("Hej z metody domyślnej ...");
+ }
+}
+
+// Teraz stworzymy klasę, która zaimplementuje oba interfejsy.
+public class Owoc implements Jadalne, Przetrawialne {
+ @Override
+ public void jedz() {
+ // ...
+ }
+
+ @Override
+ public void przetrawiaj() {
+ // ...
+ }
+}
+
+// W Javie możesz dziedziczyć jedynie z jednej klasy, jednak implementować
+// wiele interfejsów. Na przykład:
+public class Przyklad extends Przodek implements Interfejs1,
+ Interfejs2 {
+ @Override
+ public void Interfejs1Metoda() {
+ }
+
+ @Override
+ public void Interfejs2Metoda() {
+ }
+
+}
+
+// Klasy abstrakcyjne
+
+// Składnia deklaracji klasy abstrakcyjnej
+// <dostępność> abstract class <nawa klasy abstrakcyjnej> extends
+// <superklasy, z których dziedziczy> {
+// // Zmienne i stałe
+// // Deklaracje metod
+// }
+
+// Klasy abstrakcyjne nie mogą posiadać instancji.
+// Klasy abstrakcyjne mogą definiować metody abstrakcyjne.
+// Metody abstrakcyjne nie mają ciała funkcji i są oznaczone jako abstrakcyjne.
+// Nieabstrakcyjne klasy-dzieci muszą przeciążać wszystkie abstrakcyjne metody
+// superklasy.
+// Klasy abstrakcyjne są użyteczne gdy wymagana jest powtarzalna logika działania,
+// jednak należy zaauważyć, że jako, że wymagają dziedziczenia, łamią
+// zasadę "Composition over inheritance". Rozważ inne podejścia używając
+// kompozycji. https://en.wikipedia.org/wiki/Composition_over_inheritance
+
+public abstract class Zwierze
+{
+ private int wiek;
+
+ public abstract void dajGlos();
+
+ // Metody mogą mieć ciało
+ public void jedz()
+ {
+ System.out.println("Jestem zwierzeciem i jem.");
+ // Uwaga: Możliwy jest dostęp do zmiennych prywatnych.
+ wiek = 30;
+ }
+
+ public void wyswietlWiek()
+ {
+ System.out.println(wiek);
+ }
+
+ // Klasy abstrakcyjne mogą mieć metodę główną.
+ public static void main(String[] args)
+ {
+ System.out.println("Jestem abstrakcyjna");
+ }
+}
+
+class Pies extends Zwierze
+{
+ // Musimy przeciążyć wszystkie abstrakcyjne metody z klasy abstrakcyjnej
+ @Override
+ public void dajGlos()
+ {
+ System.out.println("Hau");
+ // wiek = 30; ==> BLAD! wiek jest typu private dla Zwierze
+ }
+
+ // NOTE: Wystąpi błąd jeżeli użyto annotacji @Override jako, że Java
+ // nie pozwala na przeciążanie metod statycznych.
+ // Występuje tutaj METHOD HIDING - ukrywanie metod.
+ // Więcej w poście na SO: http://stackoverflow.com/questions/16313649/
+ public static void main(String[] args)
+ {
+ Pies pluto = new Pies();
+ pluto.dajGLos();
+ pluto.jedz();
+ pluto.wyswietlWiek();
+ }
+}
+
+// Klasy finalne
+
+// Składnia deklaracji klasy finalnej
+// <dostępność> final <nazwa klasy finalnej> {
+// // Zmienne i stałe
+// // Deklaracje Metody
+// }
+
+// Klasy finalne są klasami, które nie mogą być użyte do dziedziczenia, są więc
+// z założenia ostatnim elementem dziedziczenia. W ten sposób są przeciwnością
+// klas abstrakcyjnych, które z założenia muszą być dziedziczone.
+public final class TygrysSzablozebny extends Zwierze
+{
+ // Nadal musimy przeciążyć metody abstrakcyjne klasy abstrakcyjnej Zwierze
+ @Override
+ public void dajGlos()
+ {
+ System.out.println("Roar");
+ }
+}
+
+// Metody finalne
+public abstract class Ssak
+{
+ // Składnia metody finalnej:
+ // <dostępność> final <zwracany rodzaj> <nazwa funkcji>(<argumenty>)
+
+ // Metody finalne, jak klasy finalne nie mogą być przeciążane
+ // i są w ten sposób ostatecznymi implementacjami danej metody.
+ public final boolean jestStalocieplny()
+ {
+ return true;
+ }
+}
+
+// Enumeratory
+//
+// Enumerator jest specjalnym tyme danej, która pozwala zmiennej na bycie
+// zestawem wcześniej zdefiniowanych stałych. Zmienna musi być równa jednej z
+// wartości wcześniej zdefiniowanych. Jako, że są to stałe, nazwy pól typu enum
+// są pisane wielkimi literami. W języku Java typ enum definiujemy przez użycie
+// słowa enum. Na przykład aby zdefiniować dni tygodnia:
+public enum Dzien {
+ PONIEDZIALEK, WTOREK, SRODA, CZWARTEK,
+ PIATEK, SOBOTA, NIEDZIELA
+}
+
+// We can use our enum Day like that:
+public class EnumTest {
+ // Zmienna typu enum
+ Dzien dzien;
+
+ public EnumTest(Dzien dzien) {
+ this.dzien = dzien;
+ }
+
+ public void opiszDzien() {
+ switch (dzien) {
+ case PONIEDZIALEK:
+ System.out.println("Nie lubię poniedziałku!");
+ break;
+ case PIATEK:
+ System.out.println("Piątki są dużo lepsze.");
+ break;
+ case SOBOTA:
+ case NIEDZIELA:
+ System.out.println("Weekendy są najlepsze.");
+ break;
+ default:
+ System.out.println("Środek tygodnia jest taki sobie.");
+ break;
+ }
+ }
+
+ public static void main(String[] args) {
+ EnumTest pierwszyDzien = new EnumTest(Dzien.PONIEDZIALEK);
+ pierwszyDzien.opiszDzien(); // => Nie lubię poniedziałku!
+ EnumTest trzeciDzien = new EnumTest(Dzien.SRODA);
+ trzeciDzien.opiszDzien(); // => Środek tygodnia jest taki sobie.
+ }
+}
+
+// Typ enum jest bardziej wszechstronny niż powyższa demostracja.
+// Ciało typu enum może zawierać metody i inne pola.
+// Rzuć okiem na (angielski) https://docs.oracle.com/javase/tutorial/java/javaOO/enum.html
+
+// Wprowadzenie do wyrażeń lambda
+//
+// Nowe w Javie 8 są wyrażenia lambda. Lambdy znajdujemy zwykle w funkcyjnych
+// językach programowania, co oznacza, że są metodami, które potrafią być
+// stowrzone bez klasy i przekazywane jak gdyby były obiektem oraz wykonywane
+// gdy zajdzie potrzeba.
+//
+// Ostatnia uwaga - lambdy muszą implementować funcjonalny interfejs.
+// Interfels funkcjonalny to taki, który ma jedynie jedną zadeklarowaną metodę
+// abstrakcyjną, ale może mieć dowolną ilość domyślnych metod. Wyrażenia lambda
+// mogą być używane jako instancje tego interfejsu. Każdy inteferjs, który
+// spełnia wymagania jest traktowany jako funkcjonalny. Więcej o interfejsach
+// znajdziesz powyżej, w odpowiedniej sekcji.
+//
+import java.util.Map;
+import java.util.HashMap;
+import java.util.function.*;
+import java.security.SecureRandom;
+
+public class Lambdas {
+ public static void main(String[] args) {
+ // Składnia deklaracji lambdy:
+ // <zero lub więcej parametrów> -> <ciało wyrażenia lub blok instrukcji>
+
+ // Poniżej w przykładzie użyjemy tablicy z hashowaniem.
+ Map<String, String> planety = new HashMap<>();
+ planety.put("Merkury", "87.969");
+ planety.put("Wenus", "224.7");
+ planety.put("Ziemia", "365.2564");
+ planety.put("Mars", "687");
+ planety.put("Jowisz", "4,332.59");
+ planety.put("Saturn", "10,759");
+ planety.put("Uran", "30,688.5");
+ planety.put("Neptun", "60,182");
+
+ // Lambda z zerową liczbą parametrów używając funkcjonalnego interfejsu
+ // Supplier z java.util.function.Supplier. Faktyczną lambdą jest częśc
+ // po numPlanets =.
+ Supplier<String> numPlanety = () -> Integer.toString(planety.size());
+ System.out.format("Liczba planet: %s\n\n", numPlanety.get());
+
+ // Lambda z jednym parametrem używająca funkcjonalnego interfejsu
+ // Consumer z java.util.function.Consumer.planety jest mapą, która
+ // wimplementuje Collection jak i Iterable. Użyty forEach pochodzi z
+ // Iterable i jest użyty w lambdzie na każdym elemencie kolekcji
+ // Domyślna implementacja forEach wygląda tak:
+ /*
+ for (T t : this)
+ action.accept(t);
+ */
+
+ // Faktyczna lambda jest parametrem przekazywanym do forEach.
+ planety.keySet().forEach((p) -> System.out.format("%s\n", p));
+
+ // Jeżeli przekazujemy tyklo pojedynczy argumentpowyższy zapis możemy
+ // przekształcić do (zauważ brak nawiasów dookoła p):
+ planety.keySet().forEach(p -> System.out.format("%s\n", p));
+
+ // Śledząc powyższe widzimy, że planety jest typu HashMap, a keySet()
+ // zwraca zestaw kluczy, forEach stosuje o każdego elementu lambdę:
+ // (parameter p) -> System.out.format("%s\n", p). Za każdym razem
+ // element jest uznawany jako "konsumowany" i wyrażenie (wyrażenia)
+ // w lambdzie są wykonywane. Pamiętaj, że ciało lambdy to część po
+ // symbolu ->.
+
+ // Powyższy przykład bez użycia lambdy wyglądałby tradycyjnie tak:
+ for (String planeta : planety.keySet()) {
+ System.out.format("%s\n", planeta);
+ }
+
+ // Poniższy przykład różni się od powyższego sposobem implementacji
+ // forEach: forEach użyty w klasie HashMap implementuje intefejs Map.
+ // Poniższy forEach przyjmuje BiConsumer, który ogólnie ujmując jest
+ // wymyślnym sposobem stwierdzenia, że zajmuje się zestawem par
+ // klucz-wartość Key -> Value dla każdego klucza. Ta domyślna
+ // implementacja działa jak:
+ /*
+ for (Map.Entry<K, V> entry : map.entrySet())
+ action.accept(entry.getKey(), entry.getValue());
+ */
+
+ // Faktyczna lambda jest parametrem przekazywanym do forEach.
+ String orbity = "%s okrąża Słońce w %s dni.\n";
+ planety.forEach((K, V) -> System.out.format(orbity, K, V));
+
+ // Powyższe bez użycia lambdy wyglądałoby tradycyjnie tak:
+ for (String planet : planety.keySet()) {
+ System.out.format(orbity, planet, planety.get(planet));
+ }
+
+ // Lub jeżeli postępujemy zgodnie ze specyfikacją domyślnej implementacji:
+ for (Map.Entry<String, String> planeta : planety.entrySet()) {
+ System.out.format(orbity, planeta.getKey(), planeta.getValue());
+ }
+
+ // Podane przykłady pokrywają jedynie podstawowe zastosowanie wyrażeń
+ // lambda. Być może wydają się one niezbyt przydatne, jednak należy
+ // pamiętać, że lambdy można stworzyć jako obiekty, które nastepnie mogą
+ // zostać przekazane jako parametry do innych metod.
+ }
+}
+```
+
+## Dalsze materiały
+
+Linki zamieszczone poniżej służą pomocą w zrozumieniu wybranego tematu, w razie braku rozwiązania wyszukanie w Google zwykle służy pomocą
+
+**Oficjalne poradniki Oracle po angielsku**:
+
+* [Tutorial w Javie od Sun / Oracle](https://docs.oracle.com/javase/tutorial/index.html)
+
+* [Modyfikacje poziomu dostępu w Java](https://docs.oracle.com/javase/tutorial/java/javaOO/accesscontrol.html)
+
+* [Koncepty programowania obiektowego](https://docs.oracle.com/javase/tutorial/java/concepts/index.html):
+ * [Dziedziczenie](https://docs.oracle.com/javase/tutorial/java/IandI/subclasses.html)
+ * [Polimorfizm](https://docs.oracle.com/javase/tutorial/java/IandI/polymorphism.html)
+ * [Abstrakcja](https://docs.oracle.com/javase/tutorial/java/IandI/abstract.html)
+
+* [Wyjątki](https://docs.oracle.com/javase/tutorial/essential/exceptions/index.html)
+
+* [Interfejsy](https://docs.oracle.com/javase/tutorial/java/IandI/createinterface.html)
+
+* [Uogólnianie](https://docs.oracle.com/javase/tutorial/java/generics/index.html)
+
+* [Konwencja kodu Java](https://www.oracle.com/technetwork/java/codeconvtoc-136057.html)
+
+* Nowości z Java 8:
+ * [Funkcje Lambda (programowanie funkcyjne)](https://docs.oracle.com/javase/tutorial/java/javaOO/lambdaexpressions.html)
+ * [Data y czas API (java.time package)](http://www.oracle.com/technetwork/articles/java/jf14-date-time-2125367.html)
+
+**Kursy po polsku**
+
+* [PJWSTK - Podstawy programowania w języku Java](http://edu.pjwstk.edu.pl/wyklady/ppj/scb/)
+
+* [PJWSTK - Programowanie obiektowe w języku Java](http://edu.pjwstk.edu.pl/wyklady/poj/scb/)
+
+**Tutoriale i ćwiczenia online po angielsku**
+
+* [Learneroo.com - Learn Java](http://www.learneroo.com)
+
+* [Codingbat.com](http://codingbat.com/java)
+
+* [Codewars - Java Katas](https://www.codewars.com/?language=java)
+
+**Książki po angielsku**:
+
+* [Head First Java](http://www.headfirstlabs.com/books/hfjava/)
+
+* [Thinking in Java](http://www.mindview.net/Books/TIJ/)
+
+* [Objects First with Java](https://www.amazon.com/Objects-First-Java-Practical-Introduction/dp/0132492660)
+
+* [Java The Complete Reference](https://www.amazon.com/gp/product/0071606300)
diff --git a/pl-pl/python-pl.html.markdown b/pl-pl/python-pl.html.markdown
index 023c3e6b..222f753f 100644
--- a/pl-pl/python-pl.html.markdown
+++ b/pl-pl/python-pl.html.markdown
@@ -532,7 +532,7 @@ Czlowiek.grunt() # => "*grunt*"
# Tak importuje się moduły:
import math
-print(math.sqrt(16)) # => 4
+print(math.sqrt(16)) # => 4.0
# Można podać konkretne funkcje, np. ceil, floor z modułu math
from math import ceil, floor
diff --git a/powershell.html.markdown b/powershell.html.markdown
index 5a5050b4..db29bf96 100644
--- a/powershell.html.markdown
+++ b/powershell.html.markdown
@@ -68,6 +68,7 @@ $aString="Some string"
# Or like this:
$aNumber = 5 -as [double]
$aList = 1,2,3,4,5
+$anEmptyList = @()
$aString = $aList -join '--' # yes, -split exists also
$aHashtable = @{name1='val1'; name2='val2'}
@@ -244,7 +245,7 @@ function New-Website() {
'string' | gm
# Syntax for calling static .NET methods
-\[System.Reflection.Assembly]::LoadWithPartialName('Microsoft.VisualBasic')
+[System.Reflection.Assembly]::LoadWithPartialName('Microsoft.VisualBasic')
# Note that .NET functions MUST be called with parentheses
# while PS functions CANNOT be called with parentheses.
diff --git a/processing.html.markdown b/processing.html.markdown
index fc5dc997..e437ee95 100644
--- a/processing.html.markdown
+++ b/processing.html.markdown
@@ -3,16 +3,22 @@ language: processing
filename: learnprocessing.pde
contributors:
- ["Phone Thant Ko", "http://github.com/phonethantko"]
+ - ["Divay Prakash", "https://github.com/divayprakash"]
---
+
## Introduction
-Processing is a programming language for creation of digital arts and multimedia content, allowing non-programmers to
-learn fundamentals of computer programming in a visual context.
-While the language is based on Java language,
-its syntax has been largely influenced by both Java and Javascript syntaxes. [See more here](https://processing.org/reference/)
-The language is statically typed, and also comes with its official IDE to compile and run the scripts.
+Processing is a programming language for creation of digital arts and
+multimedia content, allowing non-programmers to learn fundamentals of computer
+programming in a visual context.
+
+While the language is based on Java language, its syntax has been largely
+influenced by both Java and Javascript syntaxes. [See more here](https://processing.org/reference/)
+
+The language is statically typed, and also comes with its official IDE to
+compile and run the scripts.
-```processing
+```
/* ---------
Comments
---------
@@ -29,23 +35,28 @@ The language is statically typed, and also comes with its official IDE to compil
/* ---------------------------------------
Writing and Running Processing Programs
---------------------------------------
- */
+*/
-// In Processing, your program's entry point is a function named setup() with a void return type.
+// In Processing, the program entry point is a function named setup() with a
+// void return type.
// Note! The syntax looks strikingly similar to that of C++.
void setup() {
// This prints out the classic output "Hello World!" to the console when run.
- println("Hello World!"); // Another language with a semi-column trap, ain't it?
+ println("Hello World!"); // Another language with a semi-column trap, aint it?
}
-// Normally, we put all the static codes inside the setup() method as the name suggest since it only runs once.
+// Normally, we put all the static codes inside the setup() method as the name
+// suggest since it only runs once.
// It can range from setting the background colours, setting the canvas size.
background(color); // setting the background colour
-size(width,height,[renderer]); // setting the canvas size with optional parameter defining renderer
+size(width,height,[renderer]); // setting the canvas size with optional
+// parameter defining renderer
// You will see more of them throughout this document.
-// If you want to run the codes indefinitely, it has to be placed in draw() method.
-// draw() must exist if you want the code to run continuously and obviously, there can only be one draw() method.
+// If you want to run the codes indefinitely, it has to be placed in draw()
+// method.
+// draw() must exist if you want the code to run continuously and obviously,
+// there can only be one draw() method.
int i = 0;
void draw() {
// This block of code loops forever until stopped
@@ -54,22 +65,25 @@ void draw() {
}
// Now that we know how to write the working script and how to run it,
-// we will proceed to explore what data types and collections are supported in Processing.
+// we will proceed to explore what data types and collections are supported in
+// Processing.
/* ------------------------
Datatypes & collections
------------------------
*/
-// According to Processing References, Processing supports 8 primitive datatypes as follows.
+// According to Processing References, Processing supports 8 primitive
+// datatypes as follows.
boolean booleanValue = true; // Boolean
byte byteValueOfA = 23; // Byte
char charValueOfA = 'A'; // Char
-color colourValueOfWhiteM = color(255, 255, 255); // Colour (Specified using color() method)
+color colourValueOfWhiteM = color(255, 255, 255); // Colour (Specified using
+// color() method)
color colourValueOfWhiteH = #FFFFFF; // Colour (Specified using hash value)
int intValue = 5; // Integer (Number without decimals)
-long longValue = 2147483648L; // "L" is added to the number to mark it as a long
+long longValue = 2147483648L; // "L" is added to number to mark it as a long
float floatValue = 1.12345; // Float (32-bit floating-point numbers)
double doubleValue = 1.12345D; // Double (64-bit floating-point numbers)
@@ -79,13 +93,15 @@ double doubleValue = 1.12345D; // Double (64-bit floating-point numbers)
// they need to be converted into "int" and "float" datatypes respectively,
// using (int) and (float) syntax before passing into a function.
-// There is a whole bunch of default composite datatypes available for use in Processing.
+// There is a whole bunch of default composite datatypes available for use in
+// Processing.
// Primarily, I will brief through the most commonly used ones to save time.
// String
// While char datatype uses '', String datatype uses "" - double quotes.
String sampleString = "Hello, Processing!";
-// String can be constructed from an array of char datatypes as well. We will discuss array very soon.
+// String can be constructed from an array of char datatypes as well. We will
+// discuss array very soon.
char source = {'H', 'E', 'L', 'L', 'O'};
String stringFromSource = new String(source); // HELLO
// As in Java, strings can be concatenated using the "+" operator.
@@ -93,27 +109,29 @@ print("Hello " + "World!"); // Hello World!
// Array
// Arrays in Processing can hold any datatypes including Objects themselves.
-// Since arrays are similar to objects, they must be created with the keyword "new".
+// Since arrays are similar to objects, they must be created with the keyword
+// "new".
int[] intArray = new int[5];
int[] intArrayWithValues = {1, 2, 3}; // You can also populate with data.
// ArrayList
// Functions are similar to those of array; arraylists can hold any datatypes.
-// The only difference is arraylists resize dynamically,
-// as it is a form of resizable-array implementation of the Java "List" interface.
+// The only difference is arraylists resize dynamically, as it is a form of
+// resizable-array implementation of the Java "List" interface.
ArrayList<Integer> intArrayList = new ArrayList<Integer>();
// Object
// Since it is based on Java, Processing supports object-oriented programming.
-// That means you can basically define any datatypes of your own and manipulate them to your needs.
+// That means you can basically define any datatypes of your own and manipulate
+// them to your needs.
// Of course, a class has to be defined before for the object you want.
// Format --> ClassName InstanceName
SomeRandomClass myObject // then instantiate later
//or
SomeRandomClass myObjectInstantiated = new SomeRandomClass();
-// Processing comes up with more collections (eg. - Dictionaries and Lists) by default,
-// for the simplicity sake, I will leave them out of discussion here.
+// Processing comes up with more collections (eg. - Dictionaries and Lists) by
+// default, for the simplicity sake, I will leave them out of discussion here.
/* ------------
Maths
@@ -128,7 +146,8 @@ SomeRandomClass myObjectInstantiated = new SomeRandomClass();
3.0 / 2 // 1.5
3.0 % 2 // 1.0
-// Processing also comes with a set of functions that simplify mathematical operations.
+// Processing also comes with a set of functions that simplify mathematical
+// operations.
float f = sq(3); // f = 9.0
float p = pow(3, 3); // p = 27.0
int a = abs(-13) // a = 13
@@ -137,18 +156,21 @@ int r2 = round(3.7); // r2 = 4
float sr = sqrt(25); // sr = 5.0
// Vectors
-// Processing provides an easy way to implement vectors in its environment using PVector class.
-// It can describe a two or three dimensional vector and
+// Processing provides an easy way to implement vectors in its environment
+// using PVector class. It can describe a two or three dimensional vector and
// comes with a set of methods which are useful for matrices operations.
// You can find more information on PVector class and its functions here.
// (https://processing.org/reference/PVector.html)
// Trigonometry
-// Processing also supports trigonometric operations by supplying a set of functions.
-// sin(), cos(), tan(), asin(), acos(), atan() and also degrees() and radians() for convenient conversion.
-// However, those functions take angle in radians as the parameter so it has to be converted beforehand.
+// Processing also supports trigonometric operations by supplying a set of
+// functions. sin(), cos(), tan(), asin(), acos(), atan() and also degrees()
+// and radians() for convenient conversion.
+// However, those functions take angle in radians as the parameter so it has
+// to be converted beforehand.
float one = sin(PI/2); // one = 1.0
-// As you may have noticed, there exists a set of constants for trigonometric uses;
+// As you may have noticed, there exists a set of constants for trigonometric
+// uses;
// PI, HALF_PI, QUARTER_PI and so on...
/* -------------
@@ -168,14 +190,14 @@ if (author.getAppearance().equals("hot")) {
int i = 3;
String value = (i > 5) ? "Big" : "Small"; // "Small"
-// Switch-case structure can be used to check multiple conditions more concisely.
+// Switch-case structure can be used to check multiple conditions concisely.
int value = 2;
switch(value) {
case 0:
- print("Nought!"); // This doesn't get executed.
+ print("Nought!"); // This does not get executed.
break; // Jumps to the next statement
case 1:
- print("Getting there..."); // This again doesn't get executed.
+ print("Getting there..."); // This again does not get executed.
break;
case 2:
print("Bravo!"); // This line gets executed.
@@ -203,13 +225,16 @@ while(j > 0) {
loop(); // allows the draw() method to run forever while
noLoop(); // only allows it to run once.
redraw(); // runs the draw() method once more.
-exit(); // This stops the program. It is useful for programs with draw() running continuously.
+exit(); // This stops the program. It is useful for programs with draw()
+// running continuously.
```
+
## Drawing with Processing
-Since you will have understood the basics of the language by now, we will now look into the best part of Processing; DRAWING.
-```processing
+Since you will have understood the basics of the language by now, we will now
+look into the best part of Processing - DRAWING.
+```
/* ------
Shapes
------
@@ -233,12 +258,15 @@ triangle(x1, y1, x2, y2, x3, y3);
// Rectangle
rect(a, b, c, d, [r]); // With optional parameter defining the radius of all corners
-rect(a, b, c, d, [tl, tr, br, bl]); // With optional set of parameters defining radius of each corner
-// Draws a rectangle with {a, b} as a top left coordinate and c and d as width and height respectively.
+rect(a, b, c, d, [tl, tr, br, bl]); // With optional set of parameters defining
+// radius of each corner
+// Draws a rectangle with {a, b} as a top left coordinate and c and d as width
+// and height respectively.
// Quad
quad(x, y, x2, y2, x3, y3, x4, y4);
-// Draws a quadrilateral with parameters defining coordinates of each corner point.
+// Draws a quadrilateral with parameters defining coordinates of each corner
+// point.
// Ellipse
ellipse(x, y, width, height);
@@ -249,19 +277,23 @@ arc(x, y, width, height, start, stop, [mode]);
// While the first four parameters are self-explanatory,
// start and end defined the angles the arc starts and ends (in radians).
// Optional parameter [mode] defines the filling;
-// PIE gives pie-like outline, CHORD gives the chord-like outline and OPEN is CHORD without strokes
+// PIE gives pie-like outline, CHORD gives the chord-like outline and OPEN is
+// CHORD without strokes
// Curves
// Processing provides two implementation of curves; using curve() and bezier().
-// Since I plan to keep this simple I won't be discussing any further details.
+// Since I plan to keep this simple I wont be discussing any further details.
// However, if you want to implement it in your sketch, here are the references:
-// (https://processing.org/reference/curve_.html)(https://processing.org/reference/bezier_.html)
+// (https://processing.org/reference/curve_.html)
+// (https://processing.org/reference/bezier_.html)
// 3D Shapes
-// 3D space can be configured by setting "P3D" to the renderer parameter in size() method.
+// 3D space can be configured by setting "P3D" to the renderer parameter in
+// size() method.
size(width, height, P3D);
-// In 3D space, you will have to translate to the particular coordinate to render the 3D shapes.
+// In 3D space, you will have to translate to the particular coordinate to
+// render the 3D shapes.
// Box
box(size); // Cube with same length defined by size
@@ -270,27 +302,32 @@ box(w, h, d); // Box with width, height and depth separately defined
// Sphere
sphere(radius); // Its size is defined using the radius parameter
// Mechanism behind rendering spheres is implemented by tessellating triangles.
-// That said, how much detail being rendered is controlled by function sphereDetail(res)
+// That said, how much detail being rendered is controlled by function
+// sphereDetail(res)
// More information here: (https://processing.org/reference/sphereDetail_.html)
// Irregular Shapes
-// What if you wanted to draw something that's not made available by Processing's functions?
-// You can use beginShape(), endShape(), vertex(x,y) to define shapes by specifying each point.
-// More information here: (https://processing.org/reference/beginShape_.html)
-// You can also use custom made shapes using PShape class.(https://processing.org/reference/PShape.html)
+// What if you wanted to draw something thats not made available by Processing
+// functions?
+// You can use beginShape(), endShape(), vertex(x,y) to define shapes by
+// specifying each point. More information here:
+// (https://processing.org/reference/beginShape_.html)
+// You can also use custom made shapes using PShape class:
+// (https://processing.org/reference/PShape.html)
/* ---------------
Transformations
---------------
*/
-// Transformations are particularly useful to keep track of the coordinate space
-// and the vertices of the shapes you have drawn.
-// Particularly, matrix stack methods; pushMatrix(), popMatrix() and translate(x,y)
+// Transformations are particularly useful to keep track of the coordinate
+// space and the vertices of the shapes you have drawn. Particularly;
+// matrix stack methods; pushMatrix(), popMatrix() and translate(x,y)
pushMatrix(); // Saves the current coordinate system to the stack
// ... apply all the transformations here ...
popMatrix(); // Restores the saved coordinate system
-// Using them, the coordinate system can be preserved and visualized without causing any conflicts.
+// Using them, the coordinate system can be preserved and visualized without
+// causing any conflicts.
// Translate
translate(x, y); // Translates to point{x, y} i.e. - setting origin to that point
@@ -310,51 +347,63 @@ scale(s); // Scale the coordinate system by either expanding or contracting it.
*/
// Colours
-// As I have discussed earlier, the background colour can be configured using background() function.
-// You can define a color object beforehand and then pass it to the function as an argument.
+// As I have discussed earlier, the background colour can be configured using
+// background() function. You can define a color object beforehand and then
+// pass it to the function as an argument.
color c = color(255, 255, 255); // WHITE!
-// By default, Processing uses RGB colour scheme but it can be configured to HSB using colorMode().
-// Read here: (https://processing.org/reference/colorMode_.html)
+// By default, Processing uses RGB colour scheme but it can be configured to
+// HSB using colorMode(). Read more here:
+// (https://processing.org/reference/colorMode_.html)
background(color); // By now, the background colour should be white.
// You can use fill() function to select the colour for filling the shapes.
-// It has to be configured before you start drawing shapes so the colours gets applied.
+// It has to be configured before you start drawing shapes so the colours gets
+// applied.
fill(color(0, 0, 0));
-// If you just want to colour the outlines of the shapes then you can use stroke() function.
-stroke(255, 255, 255, 200); // stroke colour set to yellow with transparency set to a lower value.
+// If you just want to colour the outlines of the shapes then you can use
+// stroke() function.
+stroke(255, 255, 255, 200); // stroke colour set to yellow with transparency
+// set to a lower value.
// Images
-// Processing can render images and use them in several ways. Mostly stored as PImage datatype.
+// Processing can render images and use them in several ways. Mostly stored as
+// PImage datatype.
filter(shader); // Processing supports several filter functions for image manipulation.
texture(image); // PImage can be passed into arguments for texture-mapping the shapes.
+```
+
+If you want to take things further, there are more things Processing is powered
+for. Rendering models, shaders and whatnot. There's too much to cover in a
+short documentation, so I will leave them out here. Shoud you be interested,
+please check out the references.
```
-If you want to take things further, there are more things Processing is powered for. Rendering models, shaders and whatnot.
-There's too much to cover in a short documentation, so I will leave them out here. Shoud you be interested, please check out the references.
-```processing
// Before we move on, I will touch a little bit more on how to import libraries
-// so you can extend Processing's functionality to another horizon.
+// so you can extend Processing functionality to another horizon.
/* -------
Imports
-------
*/
-// The power of Processing can be further visualized when we import libraries and packages into our sketches.
+// The power of Processing can be further visualized when we import libraries
+// and packages into our sketches.
// Import statement can be written as below at the top of the source code.
import processing.something.*;
-
```
+
## DTC?
-Down To Code? Let's get our hands dirty!
+Down To Code? Let's get our hands dirty!
-Let us see an example from openprocessing to visualize how much Processing is capable of within few lines of code.
-Copy the code below into your Processing IDE and see the magic.
+Let us see an example from openprocessing to visualize how much Processing is
+capable of within few lines of code.
-```processing
+Copy the code below into your Processing IDE and see the magic.
-// Disclaimer: I did not write this program since I currently am occupied with internship and
-// this sketch is adapted from openprocessing since it shows something cool with simple codes.
+```
+// Disclaimer: I did not write this program since I currently am occupied with
+// internship and this sketch is adapted from openprocessing since it shows
+// something cool with simple codes.
// Retrieved from: (https://www.openprocessing.org/sketch/559769)
float theta;
@@ -380,8 +429,6 @@ void draw() {
}
-
-
void branch(float len) {
col=map(len, 0, 90, 150, 255);
fill(col, 0, 74);
@@ -390,7 +437,6 @@ void branch(float len) {
ellipse(0, -len, 3, 3);
len *= 0.7;
-
if (len>30) {
pushMatrix();
translate(0, -30);
@@ -406,16 +452,16 @@ void branch(float len) {
}
}
-
```
-Processing is easy to learn and is particularly useful to create multimedia contents (even in 3D) without
-having to type a lot of codes. It is so simple that you can read through the code and get a rough idea of
-the program flow.
-However, that does not apply when you introduce external libraries, packages and even your own classes.
-(Trust me! Processing projects can get real humongous...)
+Processing is easy to learn and is particularly useful to create multimedia
+contents (even in 3D) without having to type a lot of codes. It is so simple
+that you can read through the code and get a rough idea of the program flow.
+
+However, that does not apply when you introduce external libraries, packages
+and even your own classes. (Trust me! Processing projects can get real humongous...)
-## Some useful resources:
+## Some useful resources
- [Processing Website](http://processing.org)
- [Processing Sketches](http://openprocessing.org)
diff --git a/prolog.html.markdown b/prolog.html.markdown
index f7b55ac6..d4c28cba 100644
--- a/prolog.html.markdown
+++ b/prolog.html.markdown
@@ -75,7 +75,7 @@ magicNumber(42).
?- 2 = 3. % False - equality test
?- X = 3. % X = 3 - assignment
?- X = 2, X = Y. % X = Y = 2 - two assignments
- % Note Y is assigned to, even though it is
+ % Note Y is assigned too, even though it is
% on the right hand side, because it is free
?- X = 3, X = 2. % False
% First acts as assignment and binds X=3
diff --git a/protocol-buffer-3.html.markdown b/protocol-buffer-3.html.markdown
new file mode 100644
index 00000000..46065536
--- /dev/null
+++ b/protocol-buffer-3.html.markdown
@@ -0,0 +1,247 @@
+---
+language: protocol-buffers
+filename: protocol-buffers.proto
+contributors:
+ - ["Shankar Shastri", "https://github.com/shankarshastri"]
+---
+# Protocol Buffers
+
+## Why Protocol Buffers
+
+Protocol buffers are Google's language-neutral, platform-neutral, extensible mechanism for serializing structured data – think XML, but smaller, faster, and simpler.
+You define how you want your data to be structured once, then you can use special generated source code to easily write and read your structured data to and from a variety of data streams and using a variety of languages.
+Protocol Buffers are Schema Of Messages. They are language agnostic.
+They can be converted to binary and converted back to message formats using the code generated by the protoc compiler for various languages.
+
+```
+/*
+* Language Syntax
+*/
+
+/*
+* Specifying Syntax Of Protocol Buffer Version
+* Specifying Which Protocol Buffer Version To Use
+* It can be usually proto3 or proto2
+*/
+syntax = "proto3";
+
+/*
+* Declaring Message In Protocol Buffer:
+* As you can see, each field in the message definition has a unique number.
+* These field numbers are used to identify your fields in the message binary format,
+* and should not be changed once your message type is in use.
+* Note that field numbers in the range 1 through 15 take one byte to encode, including the field number and the field's type (you can find out more about this in Protocol Buffer Encoding).
+* Field numbers in the range 16 through 2047 take two bytes. So you should reserve the numbers 1 through 15 for very frequently occurring message elements.
+* Remember to leave some room for frequently occurring elements that might be added in the future.
+* The smallest field number you can specify is 1, and the largest is 2^29 - 1, or 536,870,911.
+* You also cannot use the numbers 19000 through 19999 (FieldDescriptor::kFirstReservedNumber through FieldDescriptor::kLastReservedNumber),
+* as they are reserved for the Protocol Buffers implementation - the protocol buffer compiler will complain if you use one of these reserved numbers in your .proto.
+* Similarly, you cannot use any previously reserved field numbers.
+*
+*/
+
+/*
+Syntax For Declaring Message:
+ message ${MessageName} {
+ ${Scalar Value Type} ${FieldName1} = ${Tag Number1};
+ .
+ .
+ .
+ ${Scalar Value Type} ${FieldNameN} = ${Tag NumberN};
+ }
+
+Default Values Will be applied any case if the message doesn't contain a existing field defined
+in the message definition
+*/
+
+message MessageTypes {
+ /*
+ * Scalar Value Types
+ */
+ string stringType = 1; // A string must always contain UTF-8 encoded or 7-bit ASCII text. Default value = ""
+
+ // Number Types, Default Value = 0
+ int32 int32Type = 2; // Uses Variable Length Encoding. Inefficient For Negative Numbers, Instead Use sint32.
+ int64 int64Type = 3; // Uses Variable Length Encoding. Inefficient For Negative Numbers, Instead Use sint64.
+ uint32 uInt32Type = 4; // Uses Variable Length Encoding
+ uint64 uInt64Type = 5; // Uses Variable Length Encoding
+ sint32 sInt32Type = 6; // Uses Variable Length Encoding. They are efficient in encoding for negative numbers.
+ // Use this instead of int32 for negative numbers
+ sint64 sInt64Type = 7; // Uses Variable Length Encoding. They are efficient in encoding for negative numbers.
+ // Use this instead of int64 for negative numbers.
+
+ fixed32 fixed32Type = 8; // Always four bytes. More efficient than uint32 if values are often greater than 2^28.
+ fixed64 fixed64Type = 9; // Always eight bytes. More efficient than uint64 if values are often greater than 2^56
+
+ sfixed32 sfixed32Type = 10; // Always four bytes.
+ sfixed64 sfixed64Type = 11; // Always Eight bytes.
+
+ bool boolType = 12; // Boolean Type. Default Value = false
+
+ bytes bytesType = 13; // May contain any arbitrary sequence of bytes. Default Value = Empty Bytes
+
+ double doubleType = 14;
+ float floatType = 15;
+
+ enum Week {
+ UNDEFINED = 0; // Tag 0 is always used as default in case of enum
+ SUNDAY = 1;
+ MONDAY = 2;
+ TUESDAY = 3;
+ WEDNESDAY = 4;
+ THURSDAY = 5;
+ FRIDAY = 6;
+ SATURDAY = 7;
+ }
+ Week wkDayType = 16;
+
+ /*
+ * Defining Collection Of Scalar Value Type
+ * Syntax: repeated ${ScalarType} ${name} = TagValue
+ */
+ repeated string listOfString = 17; // List[String]
+}
+
+/*
+* Defining Defined Message Types In Other Message Definition
+*/
+message Person {
+ string fname = 1;
+ string sname = 2;
+}
+
+message City {
+ Person p = 1;
+}
+
+/*
+* Nested Message Definitions
+*/
+
+message NestedMessages {
+ message FirstLevelNestedMessage {
+ string firstString = 1;
+ message SecondLevelNestedMessage {
+ string secondString = 2;
+ }
+ }
+ FirstLevelNestedMessage msg = 1;
+ FirstLevelNestedMessage.SecondLevelNestedMessage msg2 = 2;
+}
+
+/*
+* Importing Message From A File
+*/
+
+// one.proto
+// message One {
+// string oneMsg = 1;
+// }
+
+// two.proto
+// import "myproject/one.proto"
+// message Two {
+// string twoMsg = 2;
+// }
+
+
+/*
+* Advanced Topics
+*/
+
+/*
+* Handling Message Type Changes:
+* Never Change/Use The TagNumber Of A Message Field Which Was Removed
+* We should use reserved in case of message definition update.
+* (https://developers.google.com/protocol-buffers/docs/proto3#updating)
+*/
+
+/*
+* Reserved Fields
+* It's used in case if we need to add/remove new fields into message.
+* Using Reserved Backward and Forward Compatibility Of Messages can be achieved
+*/
+
+
+message ReservedMessage {
+ reserved 0, 1, 2, 3 to 10; // Set Of Tag Numbers Which Can't be reused.
+ reserved "firstMsg", "secondMsg", "thirdMsg"; // Set Of Labels Which Can't Be reused.
+}
+
+/*
+* Any
+* The Any message type lets you use messages as embedded types without having their .proto definition.
+* An Any contains an arbitrary serialized message as bytes,
+* along with a URL that acts as a globally unique identifier for and resolves to that message's type.
+* For Any to work we need to import it as shown below.
+*/
+/*
+ import "google/protobuf/any.proto";
+ message AnySampleMessage {
+ repeated google.protobuf.Any.details = 1;
+ }
+
+*/
+
+
+/*
+* OneOf
+* There are cases, wherein only one field at-most might be present as part of the message.
+* Note: OneOf messages can't be repeated.
+*/
+
+message OneOfMessage {
+ oneof msg {
+ string fname = 1;
+ string sname = 2;
+ };
+}
+
+/*
+* Maps
+* Map fields cannot be repeated.
+* Ordering Of A Map Is Not Guaranteed.
+*/
+
+message MessageWithMaps {
+ map<string, string> mapOfMessages = 1;
+}
+
+
+/*
+* Packages
+* Used for preventing name clashes between protocol message types
+* Syntax:
+ package ${packageName};
+
+ To Access the package;
+ ${packageName}.${messageName} = ${tagNumber};
+*/
+
+/*
+* Services
+* Message Types Defined For Using In RPC system.
+* When protoc compiler generates for various languages it generates stub methods for the services.
+*/
+
+message SearchRequest {
+ string queryString = 1;
+}
+
+message SearchResponse {
+ string queryResponse = 1;
+}
+service SearchService {
+ rpc Search (SearchRequest) returns (SearchResponse);
+}
+```
+
+## Generating Classes In Various Languages For Protocol Buffers
+
+```shell
+protoc --proto_path=IMPORT_PATH --cpp_out=DST_DIR --java_out=DST_DIR --python_out=DST_DIR --go_out=DST_DIR --ruby_out=DST_DIR --objc_out=DST_DIR --csharp_out=DST_DIR path/to/file.proto
+```
+
+## References
+
+[Google Protocol Buffers](https://developers.google.com/protocol-buffers/)
diff --git a/pt-br/asymptotic-notation-pt.html.markdown b/pt-br/asymptotic-notation-pt.html.markdown
index 2f179f96..b70d26b7 100644
--- a/pt-br/asymptotic-notation-pt.html.markdown
+++ b/pt-br/asymptotic-notation-pt.html.markdown
@@ -13,7 +13,7 @@ lang: pt-br
## O que é?
Notação Assintótica é uma linguagem que nos permite analisar o tempo de execução
- de um algoritmo através da indentificação de seu comportamento com o
+ de um algoritmo através da identificação de seu comportamento com o
crescimento da entrada oferecida. Isso também é conhecido como taxa de
crescimento do algoritmo. O algoritmo de repente torna-se lento quando o
tamanho da entrada cresce? O algoritmo mantém, em geral, seu tempo de execução
@@ -33,12 +33,12 @@ Um modo seria contar o número de operações primitivas com diferentes tamanhos
## Tipos de Notação Assintótica
-Na primeira seção desse documento, descrevemos como Notação Assintótica identifica o comportamento de um algoritmo
+Na primeira seção deste documento, descrevemos como Notação Assintótica identifica o comportamento de um algoritmo
a medida que o tamanho da entrada cresce. Imaginemos um algoritmo como uma função
*f*, *n* como o tamanho da entrada e *f(n)* sendo o tempo de execução. Então,
para dado algoritmo *f*, com entrada de tamanho *n*, você terá tempo de execução
- *f(n)*. Isto resulta em um gráfico onde a coordernada Y é o tempo de execução
-, a coordernada X representa o tamanho da entrada e os pontos representam o tempo
+ *f(n)*. Isto resulta em um gráfico onde a coordenada Y é o tempo de execução,
+ a coordenada X representa o tamanho da entrada e os pontos representam o tempo
de execução para dado tamanho de entrada.
Você pode representar a função, ou o algoritmo, com Notação Assintótica de várias
@@ -49,7 +49,7 @@ não avalia o melhor caso, porque essas condições não são atingidas com freq
Um bom exemplo disto seria em algoritmos de ordenação; especificamente, na adição
de elementos à árvores. O melhor caso na maioria de algoritmos pode ser de apenas
uma operação. Entretanto, na maioria dos casos, o elemento a ser adicionado terá
-que percorrer a árvore de forma apropriada, o que pode causar a analise de um
+que percorrer a árvore de forma apropriada, o que pode causar a análise de um
ramo inteiro.
Este é o pior caso, e isto é o que você está se preparando.
@@ -63,16 +63,16 @@ Função Polinomial - an^z + . . . + an^2 + a*n^1 + a*n^0, onde *z* é uma const
Função Exponencial - a^n, onde a é alguma constante
```
Estas são as funções básicas de crescimento usadas em várias notações. A lista
- começa com a de crescimento mais lento (logarítima, a de execução mais rápida)
+ começa com a de crescimento mais lento (logarítmica, a de execução mais rápida)
e segue para a de crescimento mais rápido (exponencial, de execução mais lenta).
-Repare que enquando *n*, a entrada, cresce, cada uma dessas funções cresce mais
-rápido que quadrático, polinimial e exponencial, comparadas com logaritma e linear.
+Repare que enquanto *n*, a entrada, cresce, cada uma dessas funções cresce mais
+rápido que quadrático, polinomial e exponencial, comparadas com logarítmica e linear.
Uma nota extremamente importante para notações é tentar usar os termos mais simples.
Isto significa descartar constantes e termos de ordem mais baixa, pois quando o
tamanho da entrada cresce para o infinito (limites matemáticos), os termos de ordem
mais baixa e constantes tornam-se irrelevantes. Por exemplo, se você tiver uma
-constante muito grande, 2^9001, a simplificação não afeterá sua notação.
+constante muito grande, 2^9001, a simplificação não afetará sua notação.
Já que queremos as formas mais simples, mudemos nossa tabela um pouco...
@@ -87,7 +87,7 @@ Função Exponencial - a^n, onde *a* é uma constante
### Big-O
Big-O, também escrita como O, é uma Notação Assintótica para o pior caso. Digamos
-*f(n)* seja o tempo de exeução de um algoritmo e *g(n)) um tempo de complexidade
+*f(n)* seja o tempo de execução de um algoritmo e *g(n)) um tempo de complexidade
arbitrário que você quer relacionar com seu algoritmo. *f(n)* é O(g(n)), se, para
quando constante real c (c > 0), *f(n)* <= *c g(n)* para todo tamanho de entrada
n (n > 0).
@@ -116,7 +116,7 @@ Há alguma constante c que satisfaça a definição para todo n?
3log n + 100 <= 150 * log n, n > 2 (Indefinido em n = 1)
```
-Sim! A definição de Big-I for atentida, portante `f(n)` é `O(g(n))`.
+Sim! A definição de Big-O foi atendida, portanto `f(n)` é `O(g(n))`.
*Exemplo 2*
@@ -146,7 +146,7 @@ Big-Omega, também escrita como Ω, é uma Notação Assintótica para o melhor
Sinta-se livre para adicionar mais exemplos. Big-O é a notação primária usada para medir complexidade de algoritmos.
### Notas Finais
-É difícil manter esse tipo de tópico curto e você deveria ler os livros e artigos listados abaixo. Eles cobrem muito mais profundamente definições e exemplos. Mais x='Algoritms & Data Structures' virá; teremos um documento sobre analisar código em breve.
+É difícil manter esse tipo de tópico curto e você deveria ler os livros e artigos listados abaixo. Eles cobrem muito mais profundamente definições e exemplos. Mais x='Algorithms & Data Structures' virá; teremos um documento sobre analisar código em breve.
## Livros
diff --git a/pt-br/awk-pt.html.markdown b/pt-br/awk-pt.html.markdown
index 761f5294..9bf770fd 100644
--- a/pt-br/awk-pt.html.markdown
+++ b/pt-br/awk-pt.html.markdown
@@ -1,5 +1,6 @@
---
-language: awk
+category: tool
+tool: awk
filename: learnawk-pt.awk
contributors:
- ["Marshall Mason", "http://github.com/marshallmason"]
diff --git a/pt-br/clojure-pt.html.markdown b/pt-br/clojure-pt.html.markdown
index 7e8b3f7b..b88d4eec 100644
--- a/pt-br/clojure-pt.html.markdown
+++ b/pt-br/clojure-pt.html.markdown
@@ -340,7 +340,7 @@ keymap ; => {:a 1, :b 2, :c 3}
(def my-atom (atom {}))
; Atualize o atom com um swap!.
-; swap! pega uma funçnao and chama ela com o valor atual do atom
+; swap! pega uma função e chama ela com o valor atual do atom
; como primeiro argumento, e qualquer argumento restante como o segundo
(swap! my-atom assoc :a 1) ; Coloca o valor do átomo my-atom como o resultado de (assoc {} :a 1)
(swap! my-atom assoc :b 2) ; Coloca o valor do átomo my-atom como o resultado de (assoc {:a 1} :b 2)
diff --git a/pt-br/cmake-pt.html.markdown b/pt-br/cmake-pt.html.markdown
index bc3e7050..d11fe4f4 100644
--- a/pt-br/cmake-pt.html.markdown
+++ b/pt-br/cmake-pt.html.markdown
@@ -1,8 +1,9 @@
---
-language: cmake
+category: tool
+tool: cmake
contributors:
- ["Bruno Alano", "https://github.com/brunoalano"]
-filename: CMake
+filename: CMake-br
translators:
- ["Lucas Pugliesi", "https://github.com/fplucas"]
lang: pt-br
diff --git a/pt-br/coffeescript-pt.html.markdown b/pt-br/coffeescript-pt.html.markdown
index 8b1094b1..7129a463 100644
--- a/pt-br/coffeescript-pt.html.markdown
+++ b/pt-br/coffeescript-pt.html.markdown
@@ -3,19 +3,20 @@ language: coffeescript
contributors:
- ["Tenor Biel", "http://github.com/L8D"]
- ["Xavier Yao", "http://github.com/xavieryao"]
+ - ["Claudio Busatto", "http://github.com/cjcbusatto"]
translators:
- ["Miguel Araújo", "https://github.com/miguelarauj1o"]
lang: pt-br
filename: learncoffeescript-pt.coffee
---
-CoffeeScript é uma pequena linguagem que compila um-para-um para o JavaScript
-equivalente, e não há interpretação em tempo de execução. Como um dos sucessores
-de JavaScript, CoffeeScript tenta o seu melhor para exibir uma saída legível,
-bem-impressa e bom funcionamento dos códigos JavaScript em todo o tempo de
+CoffeeScript é uma pequena linguagem que compila um-para-um para o JavaScript
+equivalente, e não há interpretação em tempo de execução. Como um dos sucessores
+de JavaScript, CoffeeScript tenta o seu melhor para exibir uma saída legível,
+bem-impressa e bom funcionamento dos códigos JavaScript em todo o tempo de
execução JavaScript.
-Veja também [site do CoffeeScript](http://coffeescript.org/), que tem um tutorial
+Veja também [site do CoffeeScript](http://coffeescript.org/), que tem um tutorial
completo sobre CoffeeScript.
``` coffeescript
@@ -23,35 +24,35 @@ completo sobre CoffeeScript.
#Segue as tendências de muitas linguagens modernas
#Assim, os comentários são iguais a Ruby e Python, eles usam símbolos numéricos.
-###
-Os comentários em bloco são como estes, e eles traduzem diretamente para '/ *'s e
+###
+Os comentários em bloco são como estes, e eles traduzem diretamente para '/ *'s e
'* /'s para o código JavaScript que resulta...
-Você deveria entender mais de semântica de JavaScript antes de continuar...
+Você deveria entender mais de semântica de JavaScript antes de continuar...
###
-# Tarefa:
-numero = 42 #=> número var = 42;
+# Tarefa:
+numero = 42 #=> var numero = 42;
oposto = true #=> var oposto = true;
-# Condições:
-numero = -42 if oposto #=> if (oposto) {número = -42;}
+# Condições:
+numero = -42 if oposto #=> if (oposto) {numero = -42;}
-# Funções:
+# Funções:
quadrado = (x) -> x * x #=> var quadrado = function (x) {return x * x;}
-preencher = (recipiente, líquido = "coffee") ->
- "Preenchendo o #{recipiente} with #{líquido}..."
+preencher = (recipiente, liquido = "coffee") ->
+ "Preenchendo o #{recipiente} with #{liquido}..."
#=>var preencher;
#
-#preencher = function(recipiente, líquido) {
-# if (líquido == null) {
-# líquido = "coffee";
+#preencher = function(recipiente, liquido) {
+# if (liquido == null) {
+# liquido = "coffee";
# }
-# return "Preenchendo o " + recipiente + " with " + líquido + "...";
+# return "Preenchendo o " + recipiente + " with " + liquido + "...";
#};
-# Alcances:
+# Alcances:
list = [1 .. 5] #=> lista var = [1, 2, 3, 4, 5];
# Objetos:
@@ -79,7 +80,7 @@ alert "Eu sabia!" if elvis?
#=> if(typeof elvis !== "undefined" && elvis !== null) { alert("Eu sabia!"); }
# Compressão de Matrizes:
-cubes = (math.cube num for num in list)
+cubes = (math.cube num for num in list)
#=>cubes = (function() {
# var _i, _len, _results;
# _results = [];
@@ -99,8 +100,9 @@ eat alimento for alimento in comidas when alimento isnt 'chocolate'
# if (alimento !== 'chocolate') {
# eat(alimento);
# }
+```
## Recursos adicionais
- [Smooth CoffeeScript](http://autotelicum.github.io/Smooth-CoffeeScript/)
-- [CoffeeScript Ristretto](https://leanpub.com/coffeescript-ristretto/read) \ No newline at end of file
+- [CoffeeScript Ristretto](https://leanpub.com/coffeescript-ristretto/read)
diff --git a/pt-br/cypher-pt.html.markdown b/pt-br/cypher-pt.html.markdown
index 7cfd8dcd..9b60f771 100644
--- a/pt-br/cypher-pt.html.markdown
+++ b/pt-br/cypher-pt.html.markdown
@@ -1,6 +1,6 @@
---
language: cypher
-filename: LearnCypher.cql
+filename: LearnCypher-br.cql
contributors:
- ["Théo Gauchoux", "https://github.com/TheoGauchoux"]
diff --git a/pt-br/factor-pt.html.markdown b/pt-br/factor-pt.html.markdown
index e3c8f4a9..b4b5c7f5 100644
--- a/pt-br/factor-pt.html.markdown
+++ b/pt-br/factor-pt.html.markdown
@@ -2,7 +2,7 @@
language: factor
contributors:
- ["hyphz", "http://github.com/hyphz/"]
-filename: learnfactor.factor
+filename: learnfactor-br.factor
lang: pt-br
---
diff --git a/pt-br/html-pt.html.markdown b/pt-br/html-pt.html.markdown
index 5a4bc3bc..22b7836e 100644
--- a/pt-br/html-pt.html.markdown
+++ b/pt-br/html-pt.html.markdown
@@ -1,6 +1,6 @@
---
language: html
-filename: learnhtml.txt
+filename: learnhtml-br.txt
contributors:
- ["Christophe THOMAS", "https://github.com/WinChris"]
translators:
diff --git a/pt-br/less-pt.html.markdown b/pt-br/less-pt.html.markdown
index 679a2ed2..f6cf2d71 100644
--- a/pt-br/less-pt.html.markdown
+++ b/pt-br/less-pt.html.markdown
@@ -1,6 +1,6 @@
---
language: less
-filename: learnless.less
+filename: learnless-br.less
contributors:
- ["Saravanan Ganesh", "http://srrvnn.me"]
diff --git a/pt-br/make-pt.html.markdown b/pt-br/make-pt.html.markdown
index 8e7603cc..cbdebde7 100644
--- a/pt-br/make-pt.html.markdown
+++ b/pt-br/make-pt.html.markdown
@@ -1,5 +1,6 @@
---
-language: make
+category: tool
+tool: make
contributors:
- ["Robert Steed", "https://github.com/robochat"]
- ["Stephan Fuhrmann", "https://github.com/sfuhrm"]
diff --git a/pt-br/pascal-pt.html.markdown b/pt-br/pascal-pt.html.markdown
new file mode 100644
index 00000000..3a37271a
--- /dev/null
+++ b/pt-br/pascal-pt.html.markdown
@@ -0,0 +1,253 @@
+---
+language: Pascal
+filename: learnpascal-pt.pas
+contributors:
+ - ["Ganesha Danu", "https://github.com/blinfoldking"]
+ - ["Keith Miyake", "https//github.com/kaymmm"]
+translators:
+ - ["Raul Almeida", "https://github.com/almeidaraul"]
+lang: pt-br
+---
+
+
+>Pascal é uma linguagem de programação estruturada, que recebeu este nome em homenagem ao matemático e físico Blaise Pascal. Foi criada em 1970 pelo suíço Niklaus Wirth,tendo em mente encorajar o uso de código estruturado.
+fonte : [wikipédia](https://pt.wikipedia.org/wiki/Pascal_(linguagem_de_programa%C3%A7%C3%A3o))
+
+
+
+Para compilar e executar um programa em Pascal, você pode usar o freepascal,
+um compilador gratuito. [Faça o download aqui](https://www.freepascal.org/)
+
+```pascal
+//Corpo de um programa em Pascal
+//isso é um comentário
+{
+ isso também é um comentário,
+ mas com várias linhas
+}
+
+//cabeçalho do programa
+PROGRAM aprendendo_pascal; //<-- não esqueça o ponto e vírgula. O nome do
+programa deve começar com uma letra.
+
+CONST
+ {
+ aqui você declara valores constantes
+ }
+TYPE
+ {
+ aqui você declara tipos não nativos
+ }
+VAR
+ {
+ aqui você declara variáveis
+ }
+
+//programa de fato
+BEGIN
+ 80
+ aqui ficam todas as instruções que não pertencem nem a funções
+ nem a procedimentos
+
+ blocos de código começam com BEGIN e terminam com END
+ (como as chaves em C)
+ }
+END. //o "end" no final do programa requer um ponto final.
+```
+
+```pascal
+//formas de declarar uma variável
+VAR a:INTEGER;
+VAR b:INTEGER;
+
+VAR
+ a : INTEGER;
+ b : INTEGER;
+
+VAR a,b : INTEGER;
+```
+
+```pascal
+PROGRAM Learn_More;
+//agora, mais sobre tipos de dados e operações
+
+CONST
+ PI = 3.141592654;
+ GNU = 'GNU''s Not Unix';
+ { a convenção é usar caixa alta para constantes
+
+ constantes têm valores fixos que só podem ser alterados
+ antes da compilação
+
+ constantes podem ser de qualquer tipo nativo (integer, real, boolean,
+ char, string)
+
+TYPE
+ vet_char : array [0..255] of CHAR;
+ // isso declara um novo tipo de variável, vet_char, com 256 caracteres
+ vet_multd : array of array of INTEGER;
+ // vetores de vetores são vetores multidimensionais
+ // use vetores de tamanho 0 (daí, usa-se alocação dinâmica)
+ // vetores do tipo vet_multd são de duas dimensões
+
+//declarando variáveis
+VAR
+ int, c, d : INTEGER;
+ // três variáveis que guardam valores inteiros
+ // inteiros têm 16 bits (vão de -32768 a 32767)
+ r : REAL;
+ // uma variável que guarda um valor real
+ // reais vão de 3.4E-38 a 3.4E38
+ bool : BOOLEAN;
+ // uma variável que guarda um valor booleano (verdadeiro ou falso)
+ ch : CHAR;
+ // uma variável que guarda um caractere
+ // caracteres têm 8 bits
+ str : STRING;
+ // STRING não é um tipo padrão, mas vem na maioria dos compiladores
+ // string é um vetor de caracteres com tamanho padrão de 255 elementos
+ s : STRING[50];
+ // especificar o tamanho de uma string assim otimiza o uso de memória
+ my_str: vet_char;
+ // aqui, uma variável de um tipo personalizado declarado acima
+ my_2d : vet_multd;
+ // defina o tamanho de vetores dinâmicos antes de usá-los
+
+// outros tipos de dados (pascal é uma linguagem fortemente tipada)
+
+ // tipos adicionais de inteiros
+ b : BYTE; // faixa [0..255]
+ shi : SHORTINT; // faixa [-128..127]
+ smi : SMALLINT; // faixa [-32,768..32,767] (inteiro padrão)
+ w : WORD; // faixa [0..65,535]
+ li : LONGINT; // faixa [-2,147,483,648..2,147,483,647]
+ lw : LONGWORD; // faixa [0..4,294,967,295]
+ c : CARDINAL; // longword
+ i64 : INT64; // faixa [-9223372036854775808..9223372036854775807]
+ qw : QWORD; // faixa [0..18,446,744,073,709,551,615]
+
+ // tipos adicionais de reais
+ rr : REAL; // faixa depende da plataforma (8 bits, 16 bits, etc)
+ rs : SINGLE; // faixa [1.5E-45..3.4E38]
+ rd : DOUBLE; // faixa [5.0E-324 .. 1.7E308]
+ re : EXTENDED; // faixa [1.9E-4932..1.1E4932]
+ rc : COMP; // faixa [-2E64+1 .. 2E63-1]
+
+BEGIN
+ int := 1;// usa-se := para atribuir valores a variáveis
+ r := 3.14;
+ ch := 'a';
+ str := 'apple';
+ bool := true;
+ //pascal não é case-sensitive (não diferencia maiúsculas de minúsculas)
+ // uma opção de organização é usar maiúsculas para termos da linguagem
+ // (BEGIN, END, INTEGER, etc) e constantes
+ // aritmética
+ int := 1 + 1; // int deixa de ser 1 e passa a ser 2
+ int := int + 1; // int = 2 + 1 = 3;
+ int := 4 DIV 2; //int = 2 (DIV é uma divisão inteira - ignora o resto)
+ int := 3 DIV 2; //int = 1
+ int := 1 DIV 2; //int = 0
+
+ bool := true OR false; // bool = true
+ bool := false AND true; // bool = false
+ bool := true XOR true; // bool = false
+
+ r := 3 / 2; // usa-se a "/" para divisões entre inteiros
+ r := int; // um real pode receber um valor inteiro (mas não o contrário)
+
+ c := str[1]; //acessando elementos de um vetor: vetor[índice do elemento]
+ str := 'hello' + 'world'; //concatenção de strings
+
+ my_str[0] := 'a'; { só se pode atribuir valores a vetores elemento
+ por elemento (não o vetor inteiro de uma vez) }
+
+ // LAÇOS
+ WHILE (ch != 'a') DO
+ BEGIN
+ writeln('ch é diferente de a');
+ IF (ch = 'c') THEN
+ writeln('ch é igual a c');
+ END;
+
+ SETLENGTH(my_2d,10,10);
+ // inicialização de um vetor com alocação dinâmica; my_2d vira um 10x10
+ FOR c := 0 to 9 DO
+ { vetores começam em 0 e terminam em tamanho-1
+ (exceto se, declarando o tipo, forem especificados valores diferentes) }
+ FOR d := 0 to 9 DO
+ // a variável usada em um laço FOR deve ter sido declarada no cabeçalho
+ my_2d[c,d] := c * d;
+ // acessam-se elementos de vetores multidimensionais com [d1, d2, d3...]
+
+
+END.
+```
+
+```pascal
+PROGRAM programacao_com_funcoes;
+
+VAR
+ i, inutil : INTEGER;
+
+{ OBS: diferença entre procedimento e função
+ função: realiza operações e retorna valor
+ procedimento: só realiza operações
+}
+//declarando e descrevendo uma função
+FUNCTION fatorial_recursiva(CONST a: INTEGER) : INTEGER;
+{ calcula a! recursivamente }
+
+// pode-se declarar variáveis locais para funções e procedimentos
+// exemplo:
+// VAR
+// local_a : INTEGER;
+
+BEGIN
+ { O bloco ELSE só funciona se não houver ponto e vírgula no bloco do IF
+ exemplo:
+ IF a THEN
+ writeln('a');
+ ELSE
+ writeln('b');
+ Isso não permitiria que o programa compilasse }
+
+ IF a >= 1 THEN
+ // o valor de retorno é atribuído como se a função fosse uma variável
+ fatorial_recursiva := a * fatorial_recursiva(a-1)
+ ELSE
+ fatorial_recursiva := 1;
+END; // o END de funções e procedimentos recebe ponto e vírgula
+
+//declarando e descrevendo um procedimento
+PROCEDURE salvainteiro(VAR i : INTEGER; inutil : INTEGER);
+{ recebe entrada do usuário e salva na variável i
+ passagem de valor:
+
+ POR REFERÊNCIA - "VAR i: integer"; implica que alterações na variável i
+ dentro da função são guardadas para o escopo de todo o programa
+
+ POR VALOR - "inutil: integer"; implica que o valor do argumento é copiado
+ e alterações na variável inutil não são guardadas
+}
+
+BEGIN
+ WRITE('Insira um inteiro: '); //escreve sem quebrar linha
+ READLN(i); //lê i com quebra de linha
+ inutil := 4; // inutil não terá seu valor alterado fora do procedimento.
+END;
+
+BEGIN // programa principal
+ inutil := 3;
+ salvainteiro(i, inutil);
+
+ // escrevendo i!
+ WRITELN(i, '! = ', factorial_recursion(i)); // escreve e quebra linha
+ // valores numéricos são automaticamente convertidos para texto na escrita
+
+ // escrever valor de inutil (sempre 3, já que salvainteiro não a altera)
+ WRITELN('inutil = ', inutil);
+END.
+
+```
+
diff --git a/pt-br/python-pt.html.markdown b/pt-br/python-pt.html.markdown
index 5afd46d0..82b70117 100644
--- a/pt-br/python-pt.html.markdown
+++ b/pt-br/python-pt.html.markdown
@@ -464,7 +464,7 @@ Humano.ronca() #=> "*arrrrrrr*"
# Você pode importar módulos
import math
-print math.sqrt(16) #=> 4
+print math.sqrt(16) #=> 4.0
# Você pode importar funções específicas de um módulo
from math import ceil, floor
diff --git a/pt-br/python3-pt.html.markdown b/pt-br/python3-pt.html.markdown
index ea0617f4..b72c732a 100644
--- a/pt-br/python3-pt.html.markdown
+++ b/pt-br/python3-pt.html.markdown
@@ -647,7 +647,7 @@ Human.grunt() # => "*grunt*"
# Você pode importar módulos
import math
-print(math.sqrt(16)) # => 4
+print(math.sqrt(16)) # => 4.0
# Você pode importar apenas funções específicas de um módulo
from math import ceil, floor
diff --git a/pt-br/stylus-pt.html.markdown b/pt-br/stylus-pt.html.markdown
new file mode 100755
index 00000000..804fa806
--- /dev/null
+++ b/pt-br/stylus-pt.html.markdown
@@ -0,0 +1,228 @@
+---
+language: stylus
+filename: learnStylus-pt.styl
+contributors:
+ - ["Salomão Neto", "https://github.com/salomaosnff"]
+ - ["Isaac Henrique", "https://github.com/Isaachi1"]
+lang: pt-br
+---
+
+Stylus tem como propósito, adicionar funcionalidades às suas folhas de estilos CSS que te ajudam no desenvolvimento, sem que haja a quebra de compartibilidade entre os navegadores Web.
+Entre elas estão variáveis, aninhamento, mixins, funções e muito mais.
+
+A sintaxe do Stylus é muito flexivel podendo utilizar a sintaxe padrão do CSS e deixando opcional o ponto e vírgula (;), dois pontos (:) e até mesmo as chaves ({ e }), tornando assim o seu código ainda mais legível.
+
+Stylus não fornece novas opções de estilos, mas dá funcionalidades que permitem deixar seu CSS muito mais dinâmico.
+
+
+```scss
+
+/* Estilo de código
+==============================*/
+
+/* As chaves, ponto e vírgula, e dois pontos são opcionais no Stylus. */
+
+body {
+ background: #000;
+}
+
+body {
+ background: #000
+}
+
+body {
+ background #000
+}
+
+body
+ background #000
+
+body
+ background: #000;
+
+body
+ background: #000
+
+
+// Comentários de linha única são removidos quando Stylus é compilado para CSS.
+
+/* Comentários multi-line são preservados. */
+
+
+/* Seletores
+==============================*/
+
+/* Selecionando elementos dentro de outro elemento */
+body {
+ background: #000000;
+ h1 {
+ color: #FF0000;
+ }
+}
+
+/* Ou se preferir... */
+body
+ background #000000
+ h1
+ color #FF0000
+
+
+/* Obtendo a referência do elemento pai
+==============================*/
+a {
+ color: #0088dd;
+ &:hover {
+ color: #DD8800;
+ }
+}
+
+
+/*Variáveis
+==============================*/
+
+
+/*
+ É possível armazenar um valor CSS (tais como a cor) de uma variável.
+ Embora seja opcional, é recomendado adicionar $ antes de um nome de variável
+ para que você possa distinguir uma variável de outro valor CSS.
+*/
+
+$primary-color = #A3A4FF
+$secondary-color = #51527F
+$body-font = 'Roboto', sans-serif
+
+/* Você pode usar as variáveis em toda a sua folha de estilo.
+Agora, se você quer mudar a cor, você só tem que fazer a mudança uma vez. */
+
+body
+ background-color $primary-color
+ color $secondary-color
+ font-family $body-font
+
+/* Quando compilar ficaria assim: */
+body {
+ background-color: #A3A4FF;
+ color: #51527F;
+ font-family: 'Roboto', sans-serif;
+}
+
+/ *
+Este é muito mais fácil de manter do que ter de mudar a cor
+cada vez que aparece em toda a sua folha de estilo.
+* /
+
+
+
+/*Mixins
+==============================*/
+
+/* Se você achar que você está escrevendo o mesmo código para mais de um
+elemento, você pode querer armazenar esse código em um mixin.
+
+center()
+ display block
+ margin-left auto
+ margin-right auto
+ left 0
+ right 0
+
+/* Utilizando um mixin */
+body {
+ center()
+ background-color: $primary-color
+}
+
+/* Apoś compilar ficaria assim: */
+div {
+ display: block;
+ margin-left: auto;
+ margin-right: auto;
+ left: 0;
+ right: 0;
+ background-color: #A3A4FF;
+}
+
+/* Você pode usar mixins para criar uma propriedade estenográfica. */
+
+size($width, $height)
+ width $width
+ height $height
+
+.rectangle
+ size(100px, 60px)
+
+.square
+ size(40px, 40px)
+
+/* Você pode usar um mixin como uma propriedade CSS. */
+circle($ratio)
+ width $ratio * 2
+ height $ratio * 2
+ border-radius $ratio
+
+.ball
+ circle 25px
+
+
+/* Interpolação
+==============================*/
+
+vendor(prop, args)
+ -webkit-{prop} args
+ -moz-{prop} args
+ {prop} args
+
+border-radius()
+ vendor('border-radius', arguments)
+
+box-shadow()
+ vendor('box-shadow', arguments)
+
+button
+ border-radius 1px 2px / 3px 4px
+
+/* Funções
+==============================*/
+
+/* Funções no Stylus permitem fazer uma variedade de tarefas, como por exemplo, menipular algum dado. */
+
+body {
+ background darken(#0088DD, 50%) // Escurece a cor #0088DD em 50%
+}
+
+/** Criando sua própria função */
+somar(a, b)
+ a + b
+
+body
+ padding somar(10px, 5)
+
+/* Condições
+==============================*/
+comparar(a, b)
+ if a > b
+ maior
+ else if a < b
+ menor
+ else
+ igual
+
+comparar(5, 2) // => maior
+comparar(1, 5) // => menor
+comparar(10, 10) // => igual
+
+/* Iterações
+==============================*/
+
+/**
+Sintaxe de laço de repetição for:
+for <val-name> [, <key-name>] in <expression>
+**/
+
+for $item in (1..2) /* Repete o bloco 12 vezes */
+ .col-{$item}
+ width ($item / 12) * 100% /* Calcula a largula pelo número da coluna*
+
+```
+
+Agora que você conhece um pouco sobre esse poderoso pré-processador de CSS, você está pronto para criar folhas de estilos mais dinâmicas. Para aprofundar seus conhecimentos visite a documentação oficial do stylus em http://stylus-lang.com.
diff --git a/pug.html.markdown b/pug.html.markdown
new file mode 100644
index 00000000..0187f1e0
--- /dev/null
+++ b/pug.html.markdown
@@ -0,0 +1,204 @@
+---
+language: Pug
+contributors:
+ - ["Michael Warner", "https://github.com/MichaelJGW"]
+filename: index.pug
+---
+
+## Getting Started with Pug
+
+Pug is a little language that compiles into the HTML. It has cleaner syntax
+with additional features like if statements and loops. It can also be used
+as a server side templating language for server languages like NodeJS.
+
+### The Language
+```pug
+
+//- Single Line Comment
+
+//- Multi Line
+ Comment
+
+//- ---TAGS---
+//- Basic
+div
+//- <div></div>
+h1
+//- <h1></h1>
+my-customTag
+//- <my-customTag></my-customTag>
+
+//- Sibling
+div
+div
+//- <div></div>
+ <div></div>
+
+//- Child
+div
+ div
+//- <div>
+ <div></div>
+ </div>
+
+//- Text
+h1 Hello there
+//- <h1>Hello there</h1>
+
+//- Multi Line Text
+div.
+ Hello
+ There
+//- <div>
+ Hello
+ There
+ </div>
+
+//- ---ATTRIBUTES---
+div(class="my-class" id="my-id" my-custom-attrs="data" enabled)
+//- <div class="my-class" id="my-id" my-custom-attrs="data" enabled></div>
+
+//- Short Hand
+span.my-class
+//- <span class="my-class"></span>
+.my-class
+//- <div class="my-class"></div>
+div#my-id
+//- <div id="my-id"></div>
+div#my-id.my-class
+//- <div class="my-class" id="my-id"></div>
+
+
+//- ---JS---
+- const lang = "pug";
+
+//- Multi Line JS
+-
+ const lang = "pug";
+ const awesome = true;
+
+//- JS Classes
+- const myClass = ['class1', 'class2', 'class3']
+div(class=myClass)
+//- <div class="class1 class2 class3"></div>
+
+//- JS Styles
+- const myStyles = {'color':'white', 'background-color':'blue'}
+div(styles=myStyles)
+//- <div styles="{&quot;color&quot;:&quot;white&quot;,&quot;background-color&quot;:&quot;blue&quot;}"></div>
+
+//- JS Attributes
+- const myAttributes = {"src": "photo.png", "alt": "My Photo"}
+img&attributes(myAttributes)
+//- <img src="photo.png" alt="My Photo">
+- let disabled = false
+input(type="text" disabled=disabled)
+//- <input type="text">
+- disabled = true
+input(type="text" disabled=disabled)
+//- <input type="text" disabled>
+
+//- JS Templating
+- const name = "Bob";
+h1 Hi #{name}
+h1= name
+//- <h1>Hi Bob</h1>
+//- <h1>Bob</h1>
+
+//- ---LOOPS---
+
+//- 'each' and 'for' do the same thing we will use 'each' only.
+
+each value, i in [1,2,3]
+ p=value
+//-
+ <p>1</p>
+ <p>2</p>
+ <p>3</p>
+
+each value, index in [1,2,3]
+ p=value + '-' + index
+//-
+ <p>1-0</p>
+ <p>2-1</p>
+ <p>3-2</p>
+
+each value in []
+ p=value
+//-
+
+each value in []
+ p=value
+else
+ p No Values are here
+
+//- <p>No Values are here</p>
+
+//- ---CONDITIONALS---
+
+- const number = 5
+if number < 5
+ p number is less then 5
+else if number > 5
+ p number is greater then 5
+else
+ p number is 5
+//- <p>number is 5</p>
+
+- const orderStatus = "Pending";
+case orderStatus
+ when "Pending"
+ p.warn Your order is pending
+ when "Completed"
+ p.success Order is Completed.
+ when -1
+ p.error Error Occurred
+ default
+ p No Order Record Found
+//- <p class="warn">Your order is pending</p>
+
+//- --INCLUDE--
+//- File path -> "includes/nav.png"
+h1 Company Name
+nav
+ a(href="index.html") Home
+ a(href="about.html") About Us
+
+//- File path -> "index.png"
+html
+ body
+ include includes/nav.pug
+//-
+ <html>
+ <body>
+ <h1>Company Name</h1>
+ <nav><a href="index.html">Home</a><a href="about.html">About Us</a></nav>
+ </body>
+ </html>
+
+//- Importing JS and CSS
+script
+ include scripts/index.js
+style
+ include styles/theme.css
+
+//- ---MIXIN---
+mixin basic()
+ div Hello
++basic("Bob")
+//- <div>Hello</div>
+
+mixin comment(name, comment)
+ div
+ span.comment-name= name
+ div.comment-text= comment
++comment("Bob", "This is Awesome")
+//- <div>Hello</div>
+
+```
+
+
+### Additional Resources
+- [The Site](https://pugjs.org/)
+- [The Docs](https://pugjs.org/api/getting-started.html)
+- [Github Repo](https://github.com/pugjs/pug)
diff --git a/python.html.markdown b/python.html.markdown
index df1ca6f2..0cc33a80 100644
--- a/python.html.markdown
+++ b/python.html.markdown
@@ -328,7 +328,8 @@ filled_dict["four"] = 4 # now, filled_dict["four"] => 4
filled_dict.setdefault("five", 5) # filled_dict["five"] is set to 5
filled_dict.setdefault("five", 6) # filled_dict["five"] is still 5
-# Sets store ... well sets (which are like lists but can contain no duplicates)
+# You can declare sets (which are like unordered lists that cannot contain
+# duplicate values) using the set object.
empty_set = set()
# Initialize a "set()" with a bunch of values
some_set = set([1, 2, 2, 3, 4]) # some_set is now set([1, 2, 3, 4])
@@ -661,7 +662,7 @@ i.age # => raises an AttributeError
# You can import modules
import math
-print math.sqrt(16) # => 4
+print math.sqrt(16) # => 4.0
# You can get specific functions from a module
from math import ceil, floor
diff --git a/python3.html.markdown b/python3.html.markdown
index c7fbf342..ef78ce37 100644
--- a/python3.html.markdown
+++ b/python3.html.markdown
@@ -41,10 +41,10 @@ Note: This article applies to Python 3 specifically. Check out [here](http://lea
10 * 2 # => 20
35 / 5 # => 7.0
-# Result of integer division truncated down both for positive and negative.
+# Integer division rounds down for both positive and negative numbers.
5 // 3 # => 1
-5.0 // 3.0 # => 1.0 # works on floats too
-5 // 3 # => -2
+5.0 // 3.0 # => 1.0 # works on floats too
-5.0 // 3.0 # => -2.0
# The result of division is always a float
@@ -72,15 +72,24 @@ not False # => True
True and False # => False
False or True # => True
-# Note using Bool operators with ints
-# False is 0 and True is 1
+# True and False are actually 1 and 0 but with different keywords
+True + True # => 2
+True * 8 # => 8
+False - 5 # => -5
+
+# Comparison operators look at the numerical value of True and False
+0 == False # => True
+1 == True # => True
+2 == True # => False
+-5 != False # => True
+
+# Using boolean logical operators on ints casts them to booleans for evaluation, but their non-cast value is returned
# Don't mix up with bool(ints) and bitwise and/or (&,|)
+bool(0) # => False
+bool(4) # => True
+bool(-6) # => True
0 and 2 # => 0
-5 or 0 # => -5
-0 == False # => True
-2 == True # => False
-1 == True # => True
--5 != False != True #=> True
# Equality is ==
1 == 1 # => True
@@ -96,7 +105,10 @@ False or True # => True
2 <= 2 # => True
2 >= 2 # => True
-# Comparisons can be chained!
+# Seeing whether a value is in a range
+1 < 2 and 2 < 3 # => True
+2 < 3 and 3 < 2 # => False
+# Chaining makes this look nicer
1 < 2 < 3 # => True
2 < 3 < 2 # => False
@@ -143,7 +155,7 @@ len("This is a string") # => 16
name = "Reiko"
f"She said her name is {name}." # => "She said her name is Reiko"
# You can basically put any Python statement inside the braces and it will be output in the string.
-f"{name} is {len(name)} characters long."
+f"{name} is {len(name)} characters long." # => "Reiko is 5 characters long."
# None is an object
@@ -302,16 +314,19 @@ valid_dict = {(1,2,3):[1,2,3]} # Values can be of any type, however.
filled_dict["one"] # => 1
# Get all keys as an iterable with "keys()". We need to wrap the call in list()
-# to turn it into a list. We'll talk about those later. Note - Dictionary key
-# ordering is not guaranteed. Your results might not match this exactly.
-list(filled_dict.keys()) # => ["three", "two", "one"]
+# to turn it into a list. We'll talk about those later. Note - for Python
+# versions <3.7, dictionary key ordering is not guaranteed. Your results might
+# not match the example below exactly. However, as of Python 3.7, dictionary
+# items maintain the order at which they are inserted into the dictionary.
+list(filled_dict.keys()) # => ["three", "two", "one"] in Python <3.7
+list(filled_dict.keys()) # => ["one", "two", "three"] in Python 3.7+
# Get all values as an iterable with "values()". Once again we need to wrap it
# in list() to get it out of the iterable. Note - Same as above regarding key
# ordering.
-list(filled_dict.values()) # => [3, 2, 1]
-
+list(filled_dict.values()) # => [3, 2, 1] in Python <3.7
+list(filled_dict.values()) # => [1, 2, 3] in Python 3.7+
# Check for existence of keys in a dictionary with "in"
"one" in filled_dict # => True
@@ -447,8 +462,19 @@ prints:
"""
for i in range(4, 8, 2):
print(i)
+
"""
+To loop over a list, and retrieve both the index and the value of each item in the list
+prints:
+ 0 dog
+ 1 cat
+ 2 mouse
+"""
+list = ["dog", "cat", "mouse"]
+for i, value in enumerate(list):
+ print(i, value)
+"""
While loops go until a condition is no longer met.
prints:
0
@@ -793,6 +819,7 @@ class Superhero(Human):
# add additional class attributes:
self.fictional = True
self.movie = movie
+ # be aware of mutable default values, since defaults are shared
self.superpowers = superpowers
# The "super" function lets you access the parent class's methods
diff --git a/r.html.markdown b/r.html.markdown
index a8b04be2..3e855602 100644
--- a/r.html.markdown
+++ b/r.html.markdown
@@ -664,7 +664,7 @@ require(plyr)
# "pets.csv" is a file on the internet
# (but it could just as easily be a file on your own computer)
require(RCurl)
-pets <- read.csv(textConnection(getURL("http://learnxinyminutes.com/docs/pets.csv")))
+pets <- read.csv(textConnection(getURL("https://learnxinyminutes.com/docs/pets.csv")))
pets
head(pets, 2) # first two rows
tail(pets, 1) # last row
diff --git a/racket.html.markdown b/racket.html.markdown
index c6b1deba..60a895e0 100644
--- a/racket.html.markdown
+++ b/racket.html.markdown
@@ -249,7 +249,7 @@ m ; => '#hash((b . 2) (a . 1) (c . 3)) <-- no `d'
(hash-remove m 'a) ; => '#hash((b . 2) (c . 3))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;; 3. Functions
+;; 4. Functions
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Use `lambda' to create functions.
@@ -319,7 +319,7 @@ m ; => '#hash((b . 2) (a . 1) (c . 3)) <-- no `d'
; => "Hi Finn, 6 extra args"
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;; 4. Equality
+;; 5. Equality
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; for numbers use `='
@@ -369,7 +369,7 @@ m ; => '#hash((b . 2) (a . 1) (c . 3)) <-- no `d'
(equal? (list 3) (list 3)) ; => #t
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;; 5. Control Flow
+;; 6. Control Flow
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; Conditionals
@@ -505,7 +505,7 @@ m ; => '#hash((b . 2) (a . 1) (c . 3)) <-- no `d'
(+ 1 (raise 2))) ; => 2
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;; 6. Mutation
+;; 7. Mutation
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Use `set!' to assign a new value to an existing variable
@@ -541,7 +541,7 @@ vec ; => #(1 2 3 4)
(hash-remove! m3 'a)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;; 7. Modules
+;; 8. Modules
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Modules let you organize code into multiple files and reusable
@@ -568,7 +568,7 @@ vec ; => #(1 2 3 4)
; (show "~a" 1 #\A) ; => error, `show' was not exported
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;; 8. Classes and Objects
+;; 9. Classes and Objects
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Create a class fish% (-% is idiomatic for class bindings)
@@ -609,7 +609,7 @@ vec ; => #(1 2 3 4)
(send (new (add-color fish%) [size 10] [color 'red]) get-color)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;; 9. Macros
+;; 10. Macros
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Macros let you extend the syntax of the language
@@ -651,7 +651,7 @@ vec ; => #(1 2 3 4)
;; it, the compiler will get in an infinite loop
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;; 10. Contracts
+;; 11. Contracts
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Contracts impose constraints on values exported from modules
@@ -678,7 +678,7 @@ vec ; => #(1 2 3 4)
;; more details....
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;; 11. Input & output
+;; 12. Input & output
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Racket has this concept of "port", which is very similar to file
diff --git a/reason.html.markdown b/reason.html.markdown
new file mode 100644
index 00000000..62d809cf
--- /dev/null
+++ b/reason.html.markdown
@@ -0,0 +1,544 @@
+---
+language: reason
+filename: reason.re
+contributors:
+ - ["Seth Corker", "https://sethcorker.com"]
+---
+
+Reason is a syntax over OCaml that is easier to get started for programmers who are familiar with C-style syntax like JavaScript. BuckleScript is part of the toolchain which compiles Reason to JavaScript so you can write statically typed code for anywhere that JavaScript runs.
+
+```javascript
+/* Comments start with slash-star, and end with star-slash */
+
+/*----------------------------------------------
+ * Variable and function declaration
+ *----------------------------------------------
+ * Variables and functions use the let keyword and end with a semi-colon
+ * `let` bindings are immutable
+ */
+
+let x = 5;
+/* - Notice we didn't add a type, Reason will infer x is an int */
+
+/* A function like this, take two arguments and add them together */
+let add = (a, b) => a + b;
+/* - This doesn't need a type annotation either! */
+
+/*----------------------------------------------
+ * Type annotation
+ *----------------------------------------------
+ * Types don't need to be explicitly annotated in most cases but when you need
+ * to, you can add the type after the name
+ */
+
+/* A type can be explicitly written like so */
+let x: int = 5;
+
+/* The add function from before could be explicitly annotated too */
+let add2 = (a: int, b: int): int => a + b;
+
+/* A type can be aliased using the type keyword */
+type companyId = int;
+let myId: companyId = 101;
+
+/* Mutation is not encouraged in Reason but it's there if you need it
+ If you need to mutate a let binding, the value must be wrapped in a `ref()`*/
+let myMutableNumber = ref(120);
+
+/* To access the value (and not the ref container), use `^` */
+let copyOfMyMutableNumber = myMutableNumber^;
+
+/* To assign a new value, use the `:=` operator */
+myMutableNumber := 240;
+
+/*----------------------------------------------
+ * Basic types and operators
+ *----------------------------------------------
+ */
+
+/* > String */
+
+/* Use double quotes for strings */
+let greeting = "Hello world!";
+
+/* A string can span multiple lines */
+let aLongerGreeting = "Look at me,
+I'm a multi-line string
+";
+
+/* A quoted string can be used for string interpolation and special chars
+ Use the `js` annotation for unicode */
+let world = {js|🌍|js};
+
+/* The `j` annotation is used for string interpolation */
+let helloWorld = {j|hello, $world|j};
+
+/* Concatenate strings with ++ */
+let name = "John " ++ "Wayne";
+let emailSubject = "Hi " ++ name ++ ", you're a valued customer";
+
+/* > Char */
+
+/* Use a single character for the char type */
+let lastLetter = 'z';
+/* - Char doesn't support Unicode or UTF-8 */
+
+/* > Boolean */
+
+/* A boolean can be either true or false */
+let isLearning = true;
+
+true && false; /* - : bool = false; Logical and */
+true || true; /* - : bool = true; Logical or */
+!true; /* - : bool = false; Logical not */
+
+/* Greater than `>`, or greater than or equal to `>=` */
+'a' > 'b'; /* - bool : false */
+
+/* Less than `<`, or less than or equal to `<=` */
+1 < 5; /* - : bool = true */
+
+/* Structural equal */
+"hello" == "hello"; /* - : bool = true */
+
+/* Referential equal */
+"hello" === "hello"; /* - : bool = false */
+/* - This is false because they are two different "hello" string literals */
+
+/* Structural unequal */
+lastLetter != 'a'; /* -: bool = true */
+
+/* Referential unequal */
+lastLetter !== lastLetter; /* - : bool = false */
+
+/* > Integer */
+/* Perform math operations on integers */
+
+1 + 1; /* - : int = 2 */
+25 - 11; /* - : int = 11 */
+5 * 2 * 3; /* - : int = 30 */
+8 / 2; /* - : int = 4 */
+
+/* > Float */
+/* Operators on floats have a dot after them */
+
+1.1 +. 1.5; /* - : float = 2.6 */
+18.0 -. 24.5; /* - : float = -6.5 */
+2.5 *. 2.0; /* - : float = 5. */
+16.0 /. 4.0; /* - : float = 4. */
+
+/* > Tuple
+ * Tuples have the following attributes
+ - immutable
+ - ordered
+ - fix-sized at creation time
+ - heterogeneous (can contain different types of values)
+ A tuple is 2 or more values */
+
+let teamMember = ("John", 25);
+
+/* Type annotation matches the values */
+let position2d: (float, float) = (9.0, 12.0);
+
+/* Pattern matching is a great tool to retrieve just the values you care about
+ If we only want the y value, let's use `_` to ignore the value */
+let (_, y) = position2d;
+y +. 1.0; /* - : float = 13. */
+
+/* > Record */
+
+/* A record has to have an explicit type */
+type trainJourney = {
+ destination: string,
+ capacity: int,
+ averageSpeed: float,
+};
+
+/* Once the type is declared, Reason can infer it whenever it comes up */
+let firstTrip = {destination: "London", capacity: 45, averageSpeed: 120.0};
+
+/* Access a property using dot notation */
+let maxPassengers = firstTrip.capacity;
+
+/* If you define the record type in a different file, you have to reference the
+ filename, if trainJourney was in a file called Trips.re */
+let secondTrip: Trips.firstTrip = {
+ destination: "Paris",
+ capacity: 50,
+ averageSpeed: 150.0,
+};
+
+/* Records are immutable by default */
+/* But the contents of a record can be copied using the spread operator */
+let newTrip = {...secondTrip, averageSpeed: 120.0};
+
+/* A record property can be mutated explicitly with the `mutable` keyword */
+type breakfastCereal = {
+ name: string,
+ mutable amount: int,
+};
+
+let tastyMuesli = {name: "Tasty Muesli TM", amount: 500};
+
+tastyMuesli.amount = 200;
+/* - tastyMuesli now has an amount of 200 */
+
+/* Punning is used to avoid redundant typing */
+let name = "Just As Good Muesli";
+let justAsGoodMuesli = {name, amount: 500};
+/* - justAsGoodMuesli.name is now "Just As Good Muesli", it's equivalent
+ to { name: name, amount: 500 } */
+
+/* > Variant
+ Mutually exclusive states can be expressed with variants */
+
+type authType =
+ | GitHub
+ | Facebook
+ | Google
+ | Password;
+/* - The constructors must be capitalized like so */
+/* - Like records, variants should be named if declared in a different file */
+
+let userPreferredAuth = GitHub;
+
+/* Variants work great with a switch statement */
+let loginMessage =
+ switch (userPreferredAuth) {
+ | GitHub => "Login with GitHub credentials."
+ | Facebook => "Login with your Facebook account."
+ | Google => "Login with your Google account"
+ | Password => "Login with email and password."
+ };
+
+/* > Option
+ An option can be None or Some('a) where 'a is the type */
+
+let userId = Some(23);
+
+/* A switch handles the two cases */
+let alertMessage =
+ switch (userId) {
+ | Some(id) => "Welcome, your ID is" ++ string_of_int(id)
+ | None => "You don't have an account!"
+ };
+/* - Missing a case, `None` or `Some`, would cause an error */
+
+/* > List
+ * Lists have the following attributes
+ - immutable
+ - ordered
+ - fast at prepending items
+ - fast at splitting
+
+ * Lists in Reason are linked lists
+ */
+
+/* A list is declared with square brackets */
+let userIds = [1, 4, 8];
+
+/* The type can be explicitly set with list('a) where 'a is the type */
+type idList = list(int);
+type attendanceList = list(string);
+
+/* Lists are immutable */
+/* But the contents of a list can be copied using the spread operator */
+let newUserIds = [101, 102, ...userIds];
+
+/* > Array
+ * Arrays have the following attributes
+ - mutable
+ - fast at random access & updates */
+
+/* An array is declared with `[|` and ends with `|]` */
+let languages = [|"Reason", "JavaScript", "OCaml"|];
+
+/*----------------------------------------------
+ * Function
+ *----------------------------------------------
+ */
+
+/* Reason functions use the arrow syntax, the expression is returned */
+let signUpToNewsletter = email => "Thanks for signing up " ++ email;
+
+/* Call a function like this */
+signUpToNewsletter("hello@reason.org");
+
+/* For longer functions, use a block */
+let getEmailPrefs = email => {
+ let message = "Update settings for " ++ email;
+ let prefs = ["Weekly News", "Daily Notifications"];
+
+ (message, prefs);
+};
+/* - the final tuple is implicitly returned */
+
+/* > Labeled Arguments */
+
+/* Arguments can be labeled with the ~ symbol */
+let moveTo = (~x, ~y) => {/* Move to x,y */};
+
+moveTo(~x=7.0, ~y=3.5);
+
+/* Labeled arguments can also have a name used within the function */
+let getMessage = (~message as msg) => "==" ++ msg ++ "==";
+
+getMessage(~message="You have a message!");
+/* - The caller specifies ~message but internally the function can make use */
+
+/* The following function also has explicit types declared */
+let showDialog = (~message: string): unit => {
+ () /* Show the dialog */;
+};
+/* - The return type is `unit`, this is a special type that is equivalent to
+ specifying that this function doesn't return a value
+ the `unit` type can also be represented as `()` */
+
+/* > Currying
+ Functions can be curried and are partially called, allowing for easy reuse */
+
+let div = (denom, numr) => numr / denom;
+let divBySix = div(6);
+let divByTwo = div(2);
+
+div(3, 24); /* - : int = 8 */
+divBySix(128); /* - : int = 21 */
+divByTwo(10); /* - : int = 5 */
+
+/* > Optional Labeled Arguments */
+
+/* Use `=?` syntax for optional labeled arguments */
+let greetPerson = (~name, ~greeting=?, ()) => {
+ switch (greeting) {
+ | Some(greet) => greet ++ " " ++ name
+ | None => "Hi " ++ name
+ };
+};
+/* - The third argument, `unit` or `()` is required because if we omitted it,
+ the function would be curried so greetPerson(~name="Kate") would create
+ a partial function, to fix this we add `unit` when we declare and call it */
+
+/* Call greetPerson without the optional labeled argument */
+greetPerson(~name="Kate", ());
+
+/* Call greetPerson with all arguments */
+greetPerson(~name="Marco", ~greeting="How are you today,");
+
+/* > Pipe */
+/* Functions can be called with the pipeline operator */
+
+/* Use `->` to pass in the first argument (pipe-first) */
+3->div(24); /* - : int = 8 */
+/* - This is equivalent to div(3, 24); */
+
+36->divBySix; /* - : int = 6 */
+/* - This is equivalent to divBySix(36); */
+
+/* Use `|>` to pass in the last argument (pipe-last) */
+24 |> div(3); /* - : int = 8 */
+/* - This is equivalent to div(3, 24); */
+
+36 |> divBySix; /* - : int = 6 */
+/* - This is equivalent to divBySix(36); */
+
+/* Pipes make it easier to chain code together */
+let addOne = a => a + 1;
+let divByTwo = a => a / 2;
+let multByThree = a => a * 3;
+
+let pipedValue = 3->addOne->divByTwo->multByThree; /* - : int = 6 */
+
+/*----------------------------------------------
+ * Control Flow & Pattern Matching
+ *----------------------------------------------
+ */
+
+/* > If-else */
+/* In Reason, `If` is an expression when evaluate will return the result */
+
+/* greeting will be "Good morning!" */
+let greeting = if (true) {"Good morning!"} else {"Hello!"};
+
+/* Without an else branch the expression will return `unit` or `()` */
+if (false) {
+ showDialog(~message="Are you sure you want to leave?");
+};
+/* - Because the result will be of type `unit`, both return types should be of
+ the same type if you want to assign the result. */
+
+/* > Destructuring */
+/* Extract properties from data structures easily */
+
+let aTuple = ("Teacher", 101);
+
+/* We can extract the values of a tuple */
+let (name, classNum) = aTuple;
+
+/* The properties of a record can be extracted too */
+type person = {
+ firstName: string,
+ age: int,
+};
+let bjorn = {firstName: "Bjorn", age: 28};
+
+/* The variable names have to match with the record property names */
+let {firstName, age} = bjorn;
+
+/* But we can rename them like so */
+let {firstName: bName, age: bAge} = bjorn;
+
+let {firstName: cName, age: _} = bjorn;
+
+/* > Switch
+ Pattern matching with switches is an important tool in Reason
+ It can be used in combination with destructuring for an expressive and
+ concise tool */
+
+/* Lets take a simple list */
+let firstNames = ["James", "Jean", "Geoff"];
+
+/* We can pattern match on the names for each case we want to handle */
+switch (firstNames) {
+| [] => "No names"
+| [first] => "Only " ++ first
+| [first, second] => "A couple of names " ++ first ++ "," ++ second
+| [first, second, third] =>
+ "Three names, " ++ first ++ ", " ++ second ++ ", " ++ third
+| _ => "Lots of names"
+};
+/* - The `_` is a catch all at the end, it signifies that we don't care what
+ the value is so it will match every other case */
+
+/* > When clause */
+
+let isJohn = a => a == "John";
+let maybeName = Some("John");
+
+/* When can add more complex logic to a simple switch */
+let aGreeting =
+ switch (maybeName) {
+ | Some(name) when isJohn(name) => "Hi John! How's it going?"
+ | Some(name) => "Hi " ++ name ++ ", welcome."
+ | None => "No one to greet."
+ };
+
+/* > Exception */
+
+/* Define a custom exception */
+exception Under_Age;
+
+/* Raise an exception within a function */
+let driveToTown = (driver: person) =>
+ if (driver.age >= 15) {
+ "We're in town";
+ } else {
+ raise(Under_Age);
+ };
+
+let evan = {firstName: "Evan", age: 14};
+
+/* Pattern match on the exception Under_Age */
+switch (driveToTown(evan)) {
+| status => print_endline(status)
+| exception Under_Age =>
+ print_endline(evan.firstName ++ " is too young to drive!")
+};
+
+/* Alternatively, a try block can be used */
+/* - With Reason exceptions can be avoided with optionals and are seldom used */
+let messageToEvan =
+ try (driveToTown(evan)) {
+ | Under_Age => evan.firstName ++ " is too young to drive!"
+ };
+
+/*----------------------------------------------
+ * Object
+ *----------------------------------------------
+ * Objects are similar to Record types but aren't as rigid
+ * An object resembles a class
+ */
+
+/* An object may be typed like a record but contains a dot */
+type surfaceComputer = {
+ .
+ color: string,
+ capacity: int,
+};
+/* - A single dot signifies a closed object, an object that uses this type
+ must have the exact shape */
+
+let surfaceBook: surfaceComputer = {pub color = "blue"; pub capacity = 512};
+
+/* But an object doesn't require a type */
+let house = {
+ /* A private property */
+ val temp = ref(18.0);
+ /* Public properties */
+ pub temperature = temp;
+ /* A private method only accessible from within house */
+ pri setThermostat = v => temp := v;
+ /* A public method that calls the private setThermostat method */
+ pub arriveHome = () => this#setThermostat(22.0)
+};
+
+house#temperature; /* - : float = 18. */
+house#arriveHome();
+house#temperature; /* - : float = 22. */
+
+/*----------------------------------------------
+ * Module
+ *----------------------------------------------
+ * Modules are used to organize your code and provide namespacing.
+ * Each file is a module by default
+ */
+
+/* Create a module */
+module Staff = {
+ type role =
+ | Delivery
+ | Sales
+ | Other;
+ type member = {
+ name: string,
+ role,
+ };
+
+ let getRoleDirectionMessage = staff =>
+ switch (staff.role) {
+ | Delivery => "Deliver it like you mean it!"
+ | Sales => "Sell it like only you can!"
+ | Other => "You're an important part of the team!"
+ };
+};
+
+/* A module can be accessed with dot notation */
+let newEmployee: Staff.member = {name: "Laura", role: Staff.Delivery};
+
+/* Using the module name can be tiresome so the module's contents can be opened
+ into the current scope with `open` */
+open Staff;
+
+let otherNewEmployee: member = {name: "Fred", role: Other};
+
+/* A module can be extended using the `include` keyword, include copies
+ the contents of the module into the scope of the new module */
+module SpecializedStaff = {
+ include Staff;
+
+ /* `member` is included so there's no need to reference it explicitly */
+ let ceo: member = {name: "Reggie", role: Other};
+
+ let getMeetingTime = staff =>
+ switch (staff) {
+ | Other => 11_15 /* - : int = 1115; Underscores are for formatting only */
+ | _ => 9_30
+ };
+};
+```
+
+## Further Reading
+
+- [Official Reason Docs](https://reasonml.github.io/docs/en/what-and-why)
+- [Official BuckleScript Docs](https://bucklescript.github.io/docs/en/what-why)
+- [Try Reason](https://reasonml.github.io/en/try)
+- [Get Started with Reason by Nik Graf](https://egghead.io/courses/get-started-with-reason)
diff --git a/red.html.markdown b/red.html.markdown
index 73baf462..74538bd7 100644
--- a/red.html.markdown
+++ b/red.html.markdown
@@ -114,12 +114,12 @@ i2 * i1 ; result 2
i1 / i2 ; result 0 (0.5, but truncated towards 0)
; Comparison operators are probably familiar, and unlike in other languages
-; you only need a single '=' sign for comparison.
+; you only need a single '=' sign for comparison. Inequality is '<>' like in Pascal.
; There is a boolean like type in Red. It has values true and false, but also
; the values on/off or yes/no can be used
3 = 2 ; result false
-3 != 2 ; result true
+3 <> 2 ; result true
3 > 2 ; result true
3 < 2 ; result false
2 <= 2 ; result true
@@ -129,8 +129,8 @@ i1 / i2 ; result 0 (0.5, but truncated towards 0)
; Control Structures
;
; if
-; Evaluate a block of code if a given condition is true. IF does not return
-; any value, so cannot be used in an expression.
+; Evaluate a block of code if a given condition is true. IF returns
+; the resulting value of the block or 'none' if the condition was false.
if a < 0 [print "a is negative"]
; either
@@ -165,7 +165,7 @@ print ["a is " msg lf]
; until
; Loop over a block of code until the condition at end of block, is met.
-; UNTIL does not return any value, so it cannot be used in an expression.
+; UNTIL always returns the 'true' value from the final evaluation of the last expression.
c: 5
until [
prin "o"
diff --git a/ro-ro/python-ro.html.markdown b/ro-ro/python-ro.html.markdown
index c96e30dc..ada0c034 100644
--- a/ro-ro/python-ro.html.markdown
+++ b/ro-ro/python-ro.html.markdown
@@ -449,7 +449,7 @@ Om.exclama() #=> "*Aaaaaah*"
# Pentru a folosi un modul, trebuie importat
import math
-print math.sqrt(16) #=> 4
+print math.sqrt(16) #=> 4.0
# Putem importa doar anumite funcţii dintr-un modul
from math import ceil, floor
diff --git a/rst.html.markdown b/rst.html.markdown
index 01595fe4..2423622e 100644
--- a/rst.html.markdown
+++ b/rst.html.markdown
@@ -47,19 +47,27 @@ Title are underlined with equals signs too
Subtitles with dashes
---------------------
-You can put text in *italic* or in **bold**, you can "mark" text as code with double backquote ``print()``.
+You can put text in *italic* or in **bold**, you can "mark" text as code with double backquote ``print()``.
-Lists are as simple as in Markdown:
+Lists are similar to Markdown, but a little more involved.
+
+Remember to line up list symbols (like - or *) with the left edge of the previous text block, and remember to use blank lines to separate new lists from parent lists:
- First item
- Second item
- - Sub item
+
+ - Sub item
+
+- Third item
or
* First item
* Second item
- * Sub item
+
+ * Sub item
+
+* Third item
Tables are really easy to write:
diff --git a/ru-ru/asymptotic-notation-ru.html.markdown b/ru-ru/asymptotic-notation-ru.html.markdown
index 73ad80ba..7fd02c47 100644
--- a/ru-ru/asymptotic-notation-ru.html.markdown
+++ b/ru-ru/asymptotic-notation-ru.html.markdown
@@ -1,225 +1,225 @@
----
-category: Algorithms & Data Structures
-name: Asymptotic Notation
-contributors:
- - ["Jake Prather", "http://github.com/JakeHP"]
- - ["Divay Prakash", "http://github.com/divayprakash"]
-translators:
- - ["pru-mike", "http://gihub.com/pru-mike"]
-lang: ru-ru
----
-
-# О-cимволика
-
-## Что это такое?
-
-О-cимволика или асимптотическая запись это система символов позволяющая оценить
-время выполнения алгоритма, устанавливая зависимость времени выполнения от
-увеличения объема входных данных, так же известна как оценка
-сложности алгоритмов. Быстро-ли алгоритм станет невероятно медленным, когда
-объем входных данных увеличится? Будет-ли алгоритм выполняться достаточно быстро,
-если объем входных данных возрастет? О-символика позволяет ответить на эти
-вопросы.
-
-## Можно-ли по-другому найти ответы на эти вопросы?
-
-Один способ это подсчитать число элементарных операций в зависимости от
-различных объемов входных данных. Хотя это и приемлемое решение, тот объем
-работы которого оно потребует, даже для простых алгоритмов, делает его
-использование неоправданным.
-
-Другой способ это измерить какое время алгоритм потребует для завершения на
-различных объемах входных данных. В тоже время, точность и относительность
-(полученное время будет относиться только к той машине на которой оно
-вычислено) этого метода зависит от среды выполнения: компьютерного аппаратного
-обеспечения, мощности процессора и т.д.
-
-## Виды О-символики
-
-В первом разделе этого документа мы определили, что О-символика
-позволяет оценивать алгоритмы в зависимости от изменения размера входных
-данных. Представим что алгоритм это функция f, n размер входных данных и
-f(n) время выполнения. Тогда для данного алгоритма f c размером входных
-данных n получим какое-то результирующее время выполнения f(n).
-Из этого можно построить график, где ось Y время выполнения, ось X размер входных
-данных и точки на графике это время выполнения для заданного размера входных
-данных.
-
-С помощью О-символики можно оценить функцию или алгоритм
-несколькими различными способами. Например можно оценить алгоритм исходя
-из нижней оценки, верхней оценки, тождественной оценки. Чаще всего встречается
-анализ на основе верхней оценки. Как правило не используется нижняя оценка,
-потому что она не подходит под планируемые условия. Отличный пример алгоритмы
-сортировки, особенно добавление элементов в древовидную структуру. Нижняя оценка
-большинства таких алгоритмов может быть дана как одна операция. В то время как в
-большинстве случаев, добавляемые элементы должны быть отсортированы
-соответствующим образом при помощи дерева, что может потребовать обхода целой
-ветви. Это и есть худший случай, для которого планируется верхняя оценка.
-
-### Виды функций, пределы и упрощения
-
-```
-Логарифмическая функция - log n
-Линейная функция - an + b
-Квадратическая функция - an^2 + bn +c
-Полиномиальная функция - an^z + . . . + an^2 + a*n^1 + a*n^0, где z константа
-Экспоненциальная функция - a^n, где a константа
-```
-
-Приведены несколько базовых функций используемых при определении сложности в
-различных оценках. Список начинается с самой медленно возрастающей функции
-(логарифм, наиболее быстрое время выполнения) и следует до самой быстро
-возрастающей функции (экспонента, самое медленное время выполнения). Отметим,
-что в то время как 'n' или размер входных данных, возрастает в каждой из этих функций,
-результат намного быстрее возрастает в квадратической, полиномиальной
-и экспоненциальной по сравнению с логарифмической и линейной.
-
-Крайне важно понимать, что при использовании описанной далее нотации необходимо
-использовать упрощенные выражения.
-Это означает, что необходимо отбрасывать константы и слагаемые младших порядков,
-потому что если размер входных данных (n в функции f(n) нашего примера)
-увеличивается до бесконечности (в пределе), тогда слагаемые младших порядков
-и константы становятся пренебрежительно малыми. Таким образом, если есть
-константа например размера 2^9001 или любого другого невообразимого размера,
-надо понимать, что её упрощение внесёт значительные искажения в точность
-оценки.
-
-Т.к. нам нужны упрощенные выражения, немного скорректируем нашу таблицу...
-
-```
-Логарифм - log n
-Линейная функция - n
-Квадратическая функция - n^2
-Полиномиальная функция - n^z, где z константа
-Экспонента - a^n, где a константа
-```
-
-### О-Большое
-О-Большое, записывается как **О**, это асимптотическая запись для оценки худшего
-случая или для ограничения заданой функции сверху. Это позволяет сделать
-_**асимптотическую оценку верхней границы**_ скорости роста времени выполнения
-алгоритма. Допустим `f(n)` время выполнения алгоритма и `g(n)` заданная временная
-сложность которая проверяется для алгоритма. Тогда `f(n)` это O(g(n)), если
-существуют действительные константы с (с > 0) и n<sub>0</sub>, такие
-что `f(n)` <= `c g(n)` выполняется для всех n начиная с некоторого n<sub>0</sub> (n > n<sub>0</sub>).
-
-*Пример 1*
-
-```
-f(n) = 3log n + 100
-g(n) = log n
-```
-
-Является-ли `f(n)` O(g(n))?
-Является-ли `3 log n + 100` O(log n)?
-Посмотрим на определение О-Большого:
-
-```
-3log n + 100 <= c * log n
-```
-
-Существуют-ли константы c, n<sub>0</sub> такие что выражение верно для всех n > n<sub>0</sub>
-
-```
-3log n + 100 <= 150 * log n, n > 2 (неопределенно для n = 1)
-```
-
-Да! По определению О-Большого `f(n)` является O(g(n)).
-
-*Пример 2*
-
-```
-f(n) = 3 * n^2
-g(n) = n
-```
-
-Является-ли `f(n)` O(g(n))?
-Является-ли `3 * n^2` O(n)?
-Посмотрим на определение О-Большого:
-
-```
-3 * n^2 <= c * n
-```
-
-Существуют-ли константы c, n<sub>0</sub> такие что выражение верно для всех n > n<sub>0</sub>?
-Нет, не существуют. `f(n)` НЕ ЯВЛЯЕТСЯ O(g(n)).
-
-### Омега-Большое
-Омега-Большое, записывается как **Ω**, это асимптотическая запись для оценки
-лучшего случая или для ограничения заданой функции снизу. Это позволяет сделать
-_**асимптотическую оценку нижней границы**_ скорости роста времени выполнения
-алгоритма.
-
-`f(n)` принадлежит Ω(g(n)), если существуют действительные константы
-с (с > 0) и <sub>0</sub> (n<sub>0</sub> > 0), такие что `f(n)` >= `c g(n)` для всех n > n<sub>0</sub>.
-
-### Примечание
-
-Асимптотические оценки сделаные при помощи О-Большое и Омега-Большое могут
-как быть так и не быть точными. Для того что бы обозначить что границы не
-являются асимптотически точными используются записи о-малое и омега-малое.
-
-### О-Малое
-O-Малое, записывается как **о**, это асимптотическая запись для оценки верхней
-границы времени выполнения алгоритма, при условии что граница не является
-асимптотически точной.
-
-`f(n)` является o(g(n)), если можно подобрать такие действительные константы,
-что для всех c (c > 0) найдется n<sub>0</sub> (n<sub>0</sub> > 0), так
-что `f(n)` < `c g(n)` выполняется для всех n (n > n<sub>0</sub>).
-
-Определения О-символики для О-Большое и О-Малое похожи. Главное отличие в том,
-что если f(n) = O(g(n)), тогда условие f(n) <= c g(n) выполняется если _**существует**_
-константа c > 0, но если f(n) = o(g(n)), тогда условие f(n) < c g(n) выполняется
-для _**всех**_ констант с > 0.
-
-### Омега-малое
-Омега-малое, записывается как **ω**, это асимптотическая запись для оценки
-верней границы времени выполнения алгоритма, при условии что граница не является
-асимптотически точной.
-
-`f(n)` является ω(g(n)), если можно подобрать такие действительные константы,
-что для всех c (c > 0) найдется n<sub>0</sub> (n<sub>0</sub> > 0), так
-что `f(n)` > `c g(n)` выполняется для всех n (n > n<sub>0</sub>)
-
-Определения Ω-символики и ω-символики похожи. Главное отличие в том, что
-если f(n) = Ω(g(n)), тогда условие f(n) >= c g(n) выполняется если _**существует**_
-константа c > 0, но если f(n) = ω(g(n)), тогда условие f(n) > c g(n)
-выполняется для _**всех**_ констант с > 0.
-
-### Тета
-Тета, записывается как **Θ**, это асимптотическая запись для оценки
-_***асимптотически точной границы***_ времени выполнения алгоритма.
-
-`f(n)` является Θ(g(n)), если для некоторых действительных
-констант c1, c2 и n<sub>0</sub> (c1 > 0, c2 > 0, n<sub>0</sub> > 0),
-`c1 g(n)` < `f(n)` < `c2 g(n)` для всех n (n > n<sub>0</sub>).
-
-∴ `f(n)` является Θ(g(n)) означает что `f(n)` является O(g(n))
-и `f(n)` является Ω(g(n)).
-
-О-Большое основной инструмент для анализа сложности алгоритмов.
-Так же смотрите примеры по ссылкам.
-
-### Заключение
-Такую тему сложно изложить кратко, поэтому обязательно стоит пройти по ссылкам и
-посмотреть дополнительную литературу. В них дается более глубокое описание с
-определениями и примерами.
-
-
-## Дополнительная литература
-
-* [Алгоритмы на Java](https://www.ozon.ru/context/detail/id/18319699/)
-* [Алгоритмы. Построение и анализ](https://www.ozon.ru/context/detail/id/33769775/)
-
-## Ссылки
-
-* [Оценки времени исполнения. Cимвол O()](http://algolist.manual.ru/misc/o_n.php)
-* [Асимптотический анализ и теория вероятностей](https://www.lektorium.tv/course/22903)
-
-## Ссылки (Eng)
-
-* [Algorithms, Part I](https://www.coursera.org/learn/algorithms-part1)
-* [Cheatsheet 1](http://web.mit.edu/broder/Public/asymptotics-cheatsheet.pdf)
-* [Cheatsheet 2](http://bigocheatsheet.com/)
-
+---
+category: Algorithms & Data Structures
+name: Asymptotic Notation
+contributors:
+ - ["Jake Prather", "http://github.com/JakeHP"]
+ - ["Divay Prakash", "http://github.com/divayprakash"]
+translators:
+ - ["pru-mike", "http://github.com/pru-mike"]
+lang: ru-ru
+---
+
+# О-символика
+
+## Что это такое?
+
+О-символика, или асимптотическая запись, — это система символов, позволяющая
+оценить время выполнения алгоритма, устанавливая зависимость времени выполнения
+от увеличения объёма входных данных. Она также известна как оценка
+сложности алгоритмов. Станет ли алгоритм невероятно медленным, когда
+объём входных данных увеличится? Будет ли алгоритм выполняться достаточно быстро,
+если объём входных данных возрастёт? О-символика позволяет ответить на эти
+вопросы.
+
+## Можно ли по-другому найти ответы на эти вопросы?
+
+Один способ — это подсчитать число элементарных операций в зависимости от
+различных объёмов входных данных. Хотя это и приемлемое решение, тот объём
+работы, которого оно потребует, даже для простых алгоритмов делает его
+использование неоправданным.
+
+Другой способ — это измерить, какое время алгоритм потребует для завершения на
+различных объёмах входных данных. В то же время, точность и относительность
+этого метода (полученное время будет относиться только к той машине, на которой
+оно вычислено) зависит от среды выполнения: компьютерного аппаратного
+обеспечения, мощности процессора и т.д.
+
+## Виды О-символики
+
+В первом разделе этого документа мы определили, что О-символика
+позволяет оценивать алгоритмы в зависимости от изменения размера входных
+данных. Представим, что алгоритм — это функция f, n — размер входных данных и
+f(n) — время выполнения. Тогда для данного алгоритма f с размером входных
+данных n получим какое-то результирующее время выполнения f(n).
+Из этого можно построить график, где ось y — время выполнения, ось x — размер входных
+данных, а точки на графике — это время выполнения для заданного размера входных
+данных.
+
+С помощью О-символики можно оценить функцию или алгоритм
+несколькими различными способами. Например, можно оценить алгоритм исходя
+из нижней оценки, верхней оценки, тождественной оценки. Чаще всего встречается
+анализ на основе верхней оценки. Как правило не используется нижняя оценка,
+потому что она не подходит под планируемые условия. Отличный пример — алгоритмы
+сортировки, особенно добавление элементов в древовидную структуру. Нижняя оценка
+большинства таких алгоритмов может быть дана как одна операция. В то время как в
+большинстве случаев добавляемые элементы должны быть отсортированы
+соответствующим образом при помощи дерева, что может потребовать обхода целой
+ветви. Это и есть худший случай, для которого планируется верхняя оценка.
+
+### Виды функций, пределы и упрощения
+
+```
+Логарифмическая функция — log n
+Линейная функция — an + b
+Квадратичная функция — an^2 + bn +c
+Степенная функция — an^z + . . . + an^2 + a*n^1 + a*n^0, где z — константа
+Показательная функция — a^n, где a — константа
+```
+
+Приведены несколько базовых функций, используемых при определении сложности в
+различных оценках. Список начинается с самой медленно возрастающей функции
+(логарифм, наиболее быстрое время выполнения) и следует до самой быстро
+возрастающей функции (экспонента, самое медленное время выполнения). Отметим,
+что в то время, как «n», или размер входных данных, возрастает в каждой из этих функций,
+результат намного быстрее возрастает в квадратичной, степенной
+и показательной по сравнению с логарифмической и линейной.
+
+Крайне важно понимать, что при использовании описанной далее нотации необходимо
+использовать упрощённые выражения.
+Это означает, что необходимо отбрасывать константы и слагаемые младших порядков,
+потому что если размер входных данных (n в функции f(n) нашего примера)
+увеличивается до бесконечности (в пределе), тогда слагаемые младших порядков
+и константы становятся пренебрежительно малыми. Таким образом, если есть
+константа, например, размера 2^9001 или любого другого невообразимого размера,
+надо понимать, что её упрощение внесёт значительные искажения в точность
+оценки.
+
+Т.к. нам нужны упрощённые выражения, немного скорректируем нашу таблицу...
+
+```
+Логарифм — log n
+Линейная функция — n
+Квадратичная функция — n^2
+Степенная функция — n^z, где z — константа
+Показательная функция — a^n, где a — константа
+```
+
+### О Большое
+О Большое, записывается как **О**, — это асимптотическая запись для оценки худшего
+случая, или для ограничения заданной функции сверху. Это позволяет сделать
+_**асимптотическую оценку верхней границы**_ скорости роста времени выполнения
+алгоритма. Пусть `f(n)` — время выполнения алгоритма, а `g(n)` — заданная временная
+сложность, которая проверяется для алгоритма. Тогда `f(n)` — это O(g(n)), если
+существуют действительные константы c (c > 0) и n<sub>0</sub>, такие,
+что `f(n)` <= `c g(n)` выполняется для всех n, начиная с некоторого n<sub>0</sub> (n > n<sub>0</sub>).
+
+*Пример 1*
+
+```
+f(n) = 3log n + 100
+g(n) = log n
+```
+
+Является ли `f(n)` O(g(n))?
+Является ли `3 log n + 100` O(log n)?
+Посмотрим на определение О Большого:
+
+```
+3log n + 100 <= c * log n
+```
+
+Существуют ли константы c и n<sub>0</sub>, такие, что выражение верно для всех n > n<sub>0</sub>?
+
+```
+3log n + 100 <= 150 * log n, n > 2 (не определенно для n = 1)
+```
+
+Да! По определению О Большого `f(n)` является O(g(n)).
+
+*Пример 2*
+
+```
+f(n) = 3 * n^2
+g(n) = n
+```
+
+Является ли `f(n)` O(g(n))?
+Является ли `3 * n^2` O(n)?
+Посмотрим на определение О Большого:
+
+```
+3 * n^2 <= c * n
+```
+
+Существуют ли константы c и n<sub>0</sub>, такие, что выражение верно для всех n > n<sub>0</sub>?
+Нет, не существуют. `f(n)` НЕ ЯВЛЯЕТСЯ O(g(n)).
+
+### Омега Большое
+Омега Большое, записывается как **Ω**, — это асимптотическая запись для оценки
+лучшего случая, или для ограничения заданной функции снизу. Это позволяет сделать
+_**асимптотическую оценку нижней границы**_ скорости роста времени выполнения
+алгоритма.
+
+`f(n)` является Ω(g(n)), если существуют действительные константы
+c (c > 0) и n<sub>0</sub> (n<sub>0</sub> > 0), такие, что `f(n)` >= `c g(n)` для всех n > n<sub>0</sub>.
+
+### Примечание
+
+Асимптотические оценки, сделаные при помощи О Большого и Омега Большого, могут
+как являться, так и не являться точными. Для того, чтобы обозначить, что границы не
+являются асимптотически точными, используются записи О Малое и Омега Малое.
+
+### О Малое
+O Малое, записывается как **о**, — это асимптотическая запись для оценки верхней
+границы времени выполнения алгоритма при условии, что граница не является
+асимптотически точной.
+
+`f(n)` является o(g(n)), если можно подобрать такие действительные константы,
+что для всех c (c > 0) найдётся n<sub>0</sub> (n<sub>0</sub> > 0), так
+что `f(n)` < `c g(n)` выполняется для всех n (n > n<sub>0</sub>).
+
+Определения О-символики для О Большого и О Малого похожи. Главное отличие в том,
+что если f(n) = O(g(n)), тогда условие f(n) <= c g(n) выполняется, если _**существует**_
+константа c > 0, но если f(n) = o(g(n)), тогда условие f(n) < c g(n) выполняется
+для _**всех**_ констант c > 0.
+
+### Омега Малое
+Омега Малое, записывается как **ω**, — это асимптотическая запись для оценки
+верхней границы времени выполнения алгоритма при условии, что граница не является
+асимптотически точной.
+
+`f(n)` является ω(g(n)), если можно подобрать такие действительные константы,
+что для всех c (c > 0) найдётся n<sub>0</sub> (n<sub>0</sub> > 0), так
+что `f(n)` > `c g(n)` выполняется для всех n (n > n<sub>0</sub>).
+
+Определения Ω-символики и ω-символики похожи. Главное отличие в том, что
+если f(n) = Ω(g(n)), тогда условие f(n) >= c g(n) выполняется, если _**существует**_
+константа c > 0, но если f(n) = ω(g(n)), тогда условие f(n) > c g(n)
+выполняется для _**всех**_ констант c > 0.
+
+### Тета
+Тета, записывается как **Θ**, — это асимптотическая запись для оценки
+_***асимптотически точной границы***_ времени выполнения алгоритма.
+
+`f(n)` является Θ(g(n)), если для некоторых действительных
+констант c1, c2 и n<sub>0</sub> (c1 > 0, c2 > 0, n<sub>0</sub> > 0)
+`c1 g(n)` < `f(n)` < `c2 g(n)` для всех n (n > n<sub>0</sub>).
+
+∴ `f(n)` является Θ(g(n)) означает, что `f(n)` является O(g(n))
+и `f(n)` является Ω(g(n)).
+
+О Большое — основной инструмент для анализа сложности алгоритмов.
+Также см. примеры по ссылкам.
+
+### Заключение
+Такую тему сложно изложить кратко, поэтому обязательно стоит пройти по ссылкам и
+посмотреть дополнительную литературу. В ней даётся более глубокое описание с
+определениями и примерами.
+
+
+## Дополнительная литература
+
+* [Алгоритмы на Java](https://www.ozon.ru/context/detail/id/18319699/)
+* [Алгоритмы. Построение и анализ](https://www.ozon.ru/context/detail/id/33769775/)
+
+## Ссылки
+
+* [Оценки времени исполнения. Символ O()](http://algolist.manual.ru/misc/o_n.php)
+* [Асимптотический анализ и теория вероятностей](https://www.lektorium.tv/course/22903)
+
+## Ссылки (англ.)
+
+* [Algorithms, Part I](https://www.coursera.org/learn/algorithms-part1)
+* [Cheatsheet 1](http://web.mit.edu/broder/Public/asymptotics-cheatsheet.pdf)
+* [Cheatsheet 2](http://bigocheatsheet.com/)
+
diff --git a/ru-ru/bash-ru.html.markdown b/ru-ru/bash-ru.html.markdown
index 5e99afc2..ce918340 100644
--- a/ru-ru/bash-ru.html.markdown
+++ b/ru-ru/bash-ru.html.markdown
@@ -11,29 +11,40 @@ contributors:
- ["Rahil Momin", "https://github.com/iamrahil"]
- ["Gregrory Kielian", "https://github.com/gskielian"]
- ["Etan Reisner", "https://github.com/deryni"]
+ - ["Jonathan Wang", "https://github.com/Jonathansw"]
+ - ["Leo Rudberg", "https://github.com/LOZORD"]
+ - ["Betsy Lorton", "https://github.com/schbetsy"]
+ - ["John Detter", "https://github.com/jdetter"]
+ - ["Harry Mumford-Turner", "https://github.com/harrymt"]
+ - ["Martin Nicholson", "https://github.com/mn113"]
translators:
- ["Andrey Samsonov", "https://github.com/kryzhovnik"]
- - ["Andre Polykanine", "https://github.com/Oire"]
+ - ["Andre Polykanine", "https://github.com/Menelion"]
filename: LearnBash-ru.sh
lang: ru-ru
---
-Bash - это командная оболочка unix (unix shell), которая распространялась как оболочка для операционной системы GNU и используется в качестве оболочки по умолчанию для Linux и Mac OS X.
-Почти все нижеприведенные примеры могут быть частью shell-скриптов или исполнены напрямую в shell.
+Bash — это командная оболочка unix, которая распространялась как оболочка
+для операционной системы GNU и используется в качестве оболочки по умолчанию
+для Linux и Mac OS X.
+Почти все нижеприведённые примеры могут быть частью shell-скриптов
+или исполнены напрямую в shell.
[Подробнее.](http://www.gnu.org/software/bash/manual/bashref.html)
```bash
#!/bin/bash
-# Первая строка скрипта - это shebang, который сообщает системе, как исполнять
-# этот скрипт: http://en.wikipedia.org/wiki/Shebang_(Unix)
-# Как вы уже поняли, комментарии начинаются с #. Shebang - тоже комментарий.
+# Первая строка скрипта — это шебанг, который сообщает системе, как исполнять
+# этот скрипт: https://ru.wikipedia.org/wiki/Шебанг_(Unix)
+# Как вы уже поняли, комментарии начинаются с «#». Шебанг — тоже комментарий.
# Простой пример hello world:
echo Hello world!
# Отдельные команды начинаются с новой строки или разделяются точкой с запятой:
echo 'Это первая строка'; echo 'Это вторая строка'
+# => Это первая строка
+# => Это вторая строка
# Вот так объявляется переменная:
VARIABLE="Просто строка"
@@ -41,103 +52,234 @@ VARIABLE="Просто строка"
# но не так:
VARIABLE = "Просто строка"
# Bash решит, что VARIABLE - это команда, которую он должен исполнить,
-# и выдаст ошибку, потому что не сможет найти ее.
+# и выдаст ошибку, потому что не сможет найти её.
# и не так:
VARIABLE= 'Просто строка'
-# Тут Bash решит, что 'Просто строка' - это команда, которую он должен исполнить,
-# и выдаст ошибку, потому что не сможет найти такой команды
+# Тут Bash решит, что 'Просто строка' — это команда, которую он должен
+# исполнить, и выдаст ошибку, потому что не сможет найти такой команды
# (здесь 'VARIABLE=' выглядит как присвоение значения переменной,
# но только в контексте исполнения команды 'Просто строка').
# Использование переменой:
-echo $VARIABLE
-echo "$VARIABLE"
-echo '$VARIABLE'
-# Когда вы используете переменную - присваиваете, экспортируете и т.д. -
+echo $VARIABLE # => Просто строка
+echo "$VARIABLE" # => Просто строка
+echo '$VARIABLE' # => $Variable
+# Когда вы используете переменную — присваиваете, экспортируете и т.д. —
# пишите её имя без $. А для получения значения переменной используйте $.
# Заметьте, что ' (одинарные кавычки) не раскрывают переменные в них.
-# Подстановка строк в переменные
-echo ${VARIABLE/Просто/A}
-# Это выражение заменит первую встреченную подстроку "Просто" на "A"
+# Раскрытие параметров ${ }:
+echo ${Variable} # => Просто строка
+# Это простое использование раскрытия параметров
+# Раскрытие параметров получает значение переменной.
+# Оно «раскрывает», или печатает это значение.
+# ̶Значение можно изменить во время раскрытия.
+# Ниже приведены другие модификации при раскрытии параметров.
+
+# Замена подстрок в переменных
+echo ${Variable/Просто/Это} # => Это строка
+# Заменит первое вхождение «Просто» на «Это»
# Взять подстроку из переменной
LENGTH=7
-echo ${VARIABLE:0:LENGTH}
-# Это выражение вернет только первые 7 символов переменной VARIABLE
+echo ${VARIABLE:0:LENGTH} # => Просто
+# Это выражение вернёт только первые 7 символов переменной VARIABLE
+echo ${Variable: -5} # => трока
+# Вернёт последние 5 символов (обратите внимание на пробел перед «-5»)
+
+# Длина строки
+echo ${#Variable} # => 13
-# Значение по умолчанию
-echo ${FOO:-"DefaultValueIfFOOIsMissingOrEmpty"}
+# Значение переменной по умолчанию
+echo ${FOO:-"ЗначениеПоУмолчаниюЕслиFooПустаИлиНеНайдена"}
+# => ЗначениеПоУмолчаниюЕслиFooПустаИлиНеНайдена
# Это сработает при отсутствующем значении (FOO=) и пустой строке (FOO="");
-# ноль (FOO=0) вернет 0.
-# Заметьте, что в любом случае значение самой переменной FOO не изменится.
+# ноль (FOO=0) вернёт 0.
+# Заметьте, что в любом случае это лишь вернёт значение по умолчанию,
+# а значение самой переменной FOO не изменится.
+
+# Объявить массив из 6 элементов
+array0=(один два три четыре пять шесть)
+# Вывести первый элемент
+echo $array0 # => "один"
+# Вывести первый элемент
+echo ${array0[0]} # => "один"
+# Вывести все элементы
+echo ${array0[@]} # => "один два три четыре пять шесть"
+# Вывести число элементов
+echo ${#array0[@]} # => "6"
+# Вывести число символов в третьем элементе
+echo ${#array0[2]} # => "3"
+# Вывести 2 элемента, начиная с четвёртого
+echo ${array0[@]:3:2} # => "четыре пять"
+# Вывести все элементы, каждый на своей строке
+for i in "${array0[@]}"; do
+ echo "$i"
+done
+
+# Раскрытие скобок { }
+# Используется для создания произвольных строк
+echo {1..10} # => 1 2 3 4 5 6 7 8 9 10
+echo {a..z} # => a b c d e f g h i j k l m n o p q r s t u v w x y z
+# Выведет диапазон от начального до конечного значения
# Встроенные переменные:
# В bash есть полезные встроенные переменные, например
-echo "Последнее возвращенное значение: $?"
-echo "PID скрипта: $$"
-echo "Количество аргументов: $#"
-echo "Аргументы скрипта: $@"
+echo "Значение, возвращённое последней программой: $?"
+echo "Идентификатор процесса скрипта: $$"
+echo "Число аргументов, переданных скрипту: $#"
+echo "Все аргументы, переданные скрипту: $@"
echo "Аргументы скрипта, распределённые по отдельным переменным: $1 $2..."
-# Чтение аргументов из устройста ввода:
+# Теперь, когда мы знаем, как выводить и использовать переменные,
+# давайте изучим некоторые другие основы Bash!
+
+# Текущая директория доступна по команде `pwd`.
+# `pwd` расшифровывается как «print working directory», т.е.
+# «напечатать рабочую директорию».
+# Мы также можем использовать встроенную переменную `$PWD`.
+# Заметьте, следующие выражения эквивалентны:
+echo "Я в $(pwd)" # выполняет `pwd` и раскрывает вывод
+echo "Я в $PWD" # раскрывает переменную
+
+# Если вы получаете слишком много информации в терминале или из скрипта,
+# команда `clear` очистит экран
+clear
+# Очистить экран можно также с помощью Ctrl+L
+
+# Чтение аргументов с устройства ввода:
echo "Как Вас зовут?"
read NAME # Обратите внимание, что нам не нужно определять новую переменную
echo Привет, $NAME!
# У нас есть обычная структура if:
# наберите 'man test' для получения подробной информации о форматах условия
-if [ $NAME -ne $USER ]
+if [ $NAME != $USER ]
then
echo "Имя не совпадает с именем пользователя"
else
echo "Имя совпадает с именем пользователя"
fi
+# Истинно, если значение $Name не совпадает с текущим именем пользователя
-# Примечание: если $Name пустой, bash интерпретирует код как:
-if [ -ne $USER ]
+# Примечание: если $Name пуста, bash интерпретирует код так:
+if [ != $USER ]
# а это ошибочная команда
-# поэтому такие переменные нужно использовать так:
-if [ "$Name" -ne $USER ] ...
-# когда $Name пустой, bash видит код как:
-if [ "" -ne $USER ] ...
+# поэтому «безопасный» способ использовать пустые переменные в Bash таков:
+if [ "$Name" != $USER ] ...
+# при этом, когда $Name пуста, bash видит код так:
+if [ "" != $USER ] ...
# что работает правильно
# Также есть условное исполнение
echo "Исполнится всегда" || echo "Исполнится, если первая команда завершится ошибкой"
+# => Исполнится всегда
echo "Исполнится всегда" && echo "Исполнится, если первая команда выполнится удачно"
+# => Исполнится всегда
+# => Исполнится, если первая команда выполнится удачно
-# Можно использовать && и || в выражениях if, когда нужно несколько пар скобок:
-if [ $NAME == "Steve" ] && [ $AGE -eq 15 ]
+
+# Чтобы использовать && и || в выражениях if, нужно несколько пар скобок:
+if [ $NAME == "Стив" ] && [ $AGE -eq 15 ]
+then
+ echo "Исполнится, если $NAME равно Стив И $AGE равно 15."
+fi
+
+if [ $NAME == "Дания" ] || [ $NAME == "Зак" ]
then
- echo "Исполнится, если $NAME равно Steve И $AGE равно 15."
+ echo "Исполнится, если $NAME равно Дания ИЛИ Зак."
fi
-if [ $NAME == "Daniya" ] || [ $NAME == "Zach" ]
+# Есть ещё оператор «=~», который проверяет строку
+# на соответствие регулярному выражению:
+Email=me@example.com
+if [[ "$Email" =~ [a-z]+@[a-z]{2,}\.(com|net|org) ]]
then
- echo "Исполнится, если $NAME равно Daniya ИЛИ Zach."
+ echo "адрес корректный!"
fi
+# Обратите внимание, что =~ работает только внутри
+# двойных квадратных скобок [[ ]],
+# которые несколько отличаются от одинарных скобок [ ].
+# Для более подробной информации см. http://www.gnu.org/software/bash/manual/bashref.html#Conditional-Constructs.
+
+# Переопределить команду «ping» как псевдоним для отправки только пяти пакетов
+alias ping='ping -c 5'
+# Экранировать псевдоним и использовать команду под своим именем вместо него
+\ping 192.168.1.1
+# Вывести все псевдонимы
+alias -p
# Выражения обозначаются таким форматом:
-echo $(( 10 + 5 ))
+echo $(( 10 + 5 )) # => 15
-# В отличие от других языков программирования, Bash - это командная оболочка,
+# В отличие от других языков программирования, Bash — это командная оболочка,
# а значит, работает в контексте текущей директории.
# Вы можете просматривать файлы и директории в текущей директории командой ls:
-ls
+ls # перечисляет файлы и поддиректории в текущей директории
-# У этой команды есть опции:
+# У этой команды есть параметры:
ls -l # Показать каждый файл и директорию на отдельной строке
+ls -t # сортирует содержимое по дате последнего изменения (в обратном порядке)
+ls -R # Рекурсивно выполняет `ls` по данной директории и всем её поддиректориям
# Результат предыдущей команды может быть направлен на вход следующей.
# Команда grep фильтрует ввод по шаблону.
-# Так мы можем просмотреть только *.txt файлы в текущей директории:
+# Так мы можем просмотреть только *.txt-файлы в текущей директории:
ls -l | grep "\.txt"
+# Для вывода файлов в стандартный поток используйте `cat`:
+cat file.txt
+
+# С помощью `cat` мы также можем читать файлы:
+Contents=$(cat file.txt)
+echo "НАЧАЛО ФАЙЛА\n$Contents\nКОНЕЦ ФАЙЛА" # «\n» выводит символ перевода на новую строку
+# => НАЧАЛО ФАЙЛА
+# => [Содержимое file.txt]
+# => КОНЕЦ ФАЙЛА
+
+# Для копирования файлов и директорий из одного места в другое используйте `cp`.
+# `cp` создаёт новые версии исходных элементов,
+# так что редактирование копии не повлияет на оригинал (и наоборот).
+# Обратите внимание, что команда перезапишет целевой элемент, если он уже существует.
+cp srcFile.txt clone.txt
+cp -r srcDirectory/ dst/ # рекурсивное копирование
+
+# Если вам нужно обмениваться файлами между компьютерами, посмотрите в сторону `scp` или `sftp`.
+# `scp` ведёт себя очень похоже на `cp`.
+# `sftp` более интерактивна.
+
+# Для перемещения файлов и директорий из одного места в другое используйте `mv`.
+# Команда `mv` похожа на `cp`, но она удаляет исходный элемент.
+# `mv` также можно использовать для переименования файлов!
+mv s0urc3.txt dst.txt # Извините, тут были Leet-хакеры...
+
+# Поскольку Bash работает в контексте текущей директории, вам может понадобиться
+# запустить команду в другой директории.
+# Для изменения местоположения у нас есть `cd`:
+cd ~ # Перейти в домашнюю директорию
+cd # Также переходит в домашнюю директорию
+cd .. # Перейти на уровень вверх
+ # (например, из /home/username/Downloads в /home/username)
+cd /home/username/Documents # перейти в указанную директорию
+cd ~/Documents/.. # Всё ещё в домашней директории. Так ведь??
+cd - # Перейти в последнюю директорию
+# => /home/username/Documents
+
+# Для работы по директориям используйте субоболочки
+(echo "Сначала я здесь: $PWD") && (cd someDir; echo "А теперь я тут: $PWD")
+pwd # всё ещё в первой директории
+
+# Для создания новых директорий используйте `mkdir`.
+mkdir myNewDir
+# Флаг `-p` указывает, что нужно создать все промежуточные директории, если нужно.
+mkdir -p myNewDir/with/intermediate/directories
+# Если промежуточные директории до этого не существовали,
+# вышеприведённая команда без флага `-p` вернёт ошибку
+
# Вы можете перенаправить ввод и вывод команды (stdin, stdout и stderr).
-# Следующая команда означает: читать из stdin, пока не встретится ^EOF$, и
-# перезаписать hello.py следующим строками (до строки "EOF"):
+# Прочитать из stdin, пока не встретится ^EOF$, и
+# перезаписать hello.py следующими строками (до строки "EOF"):
cat > hello.py << EOF
#!/usr/bin/env python
from __future__ import print_function
@@ -147,23 +289,25 @@ print("#stderr", file=sys.stderr)
for line in sys.stdin:
print(line, file=sys.stdout)
EOF
+# Если первый «EOF» не заключён в кавычки, переменные будут раскрыты
# Запуск hello.py с разными вариантами перенаправления потоков
# стандартных ввода, вывода и ошибок:
-python hello.py < "input.in"
-python hello.py > "output.out"
-python hello.py 2> "error.err"
-python hello.py > "output-and-error.log" 2>&1
-python hello.py > /dev/null 2>&1
+python hello.py < "input.in" # передать input.in в качестве ввода в скрипт
+python hello.py > "output.out" # передать вывод скрипта в output.out
+python hello.py 2> "error.err" # передать вывод ошибок в error.err
+python hello.py > "output-and-error.log" 2>&1 # передать вывод скрипта и ошибок в output-and-error.log
+python hello.py > /dev/null 2>&1 # передать вывод скрипта и ошибок в «чёрную дыру» /dev/null, т.е., без вывода
# Поток ошибок перезапишет файл, если этот файл существует,
-# поэтому, если вы хотите дописывать файл, используйте ">>":
+# поэтому, если вы хотите дописывать файл, используйте «>>»:
python hello.py >> "output.out" 2>> "error.err"
-# Переписать output.txt, дописать error.err и сосчитать строки:
+# Перезаписать output.txt, дописать error.err и сосчитать строки:
info bash 'Basic Shell Features' 'Redirections' > output.out 2>> error.err
wc -l output.out error.err
-# Запустить команду и вывести ее файловый дескриптор (смотрите: man fd)
+# Запустить команду и вывести её файловый дескриптор (например, /dev/fd/123)
+# См. man fd
echo <(echo "#helloworld")
# Перезаписать output.txt строкой "#helloworld":
@@ -172,40 +316,49 @@ echo "#helloworld" > output.out
echo "#helloworld" | cat > output.out
echo "#helloworld" | tee output.out >/dev/null
-# Подчистить временные файлы с подробным выводом ('-i' - интерактивый режим)
+# Подчистить временные файлы с подробным выводом ('-i' — интерактивный режим)
+# ВНИМАНИЕ: команду `rm` отменить нельзя
rm -v output.out error.err output-and-error.log
+rm -r tempDir/ # рекурсивное удаление
# Команды могут быть подставлены в строку с помощью $( ):
# следующие команды выводят число файлов и директорий в текущей директории.
echo "Здесь $(ls | wc -l) элементов."
-# То же самое можно сделать с использованием обратных кавычек,
+# То же самое можно сделать с использованием обратных кавычек «``»,
# но они не могут быть вложенными, поэтому предпочтительно использовать $( ).
echo "Здесь `ls | wc -l` элементов."
# В Bash есть структура case, которая похожа на switch в Java и C++:
case "$VARIABLE" in
- # Перечислите шаблоны для условий, которые хотите отловить
+ # Перечислите шаблоны для условий, которые хотите выполнить
0) echo "Тут ноль.";;
1) echo "Тут один.";;
*) echo "Это не пустое значение.";;
esac
-# Цикл for перебирает элементы переданные в аргументе:
+# Цикл for перебирает элементы по количеству аргументов:
# Содержимое $VARIABLE будет напечатано три раза.
for VARIABLE in {1..3}
do
echo "$VARIABLE"
done
+# => 1
+# => 2
+# => 3
+
-# Или с использованием "традиционного" синтаксиса цикла for:
+# Или с использованием «традиционного» синтаксиса цикла for:
for ((a=1; a <= 3; a++))
do
echo $a
done
+# => 1
+# => 2
+# => 3
# Цикл for можно использовать для действий с файлами.
-# Запустим команду 'cat' для файлов file1 и file2
+# Запустим команду «cat» для файлов file1 и file2
for VARIABLE in file1 file2
do
cat "$VARIABLE"
@@ -221,52 +374,89 @@ done
# Цикл while:
while [ true ]
do
- echo "тело цикла здесь..."
+ echo "Здесь тело цикла..."
break
done
+# => Здесь тело цикла...
-# Вы можете определять функции
+# Вы также можете определять функции
# Определение:
function foo ()
{
- echo "Аргументы работают также, как аргументы скрипта: $@"
- echo "и: $1 $2..."
+ echo "Аргументы работают так же, как и аргументы скрипта: $@"
+ echo "И так: $1 $2..."
echo "Это функция"
return 0
}
+# Вызовем функцию `foo` с двумя аргументами, arg1 и arg2:
+foo arg1 arg2
+# => Аргументы работают так же, как и аргументы скрипта: arg1 arg2
+# => И так: arg1 arg2...
+# => Это функция
# или просто
bar ()
{
- echo "Другой способ определить функцию!"
+ echo "Другой способ определять функции!"
return 0
}
+# Вызовем функцию `bar` без аргументов:
+bar # => Другой способ определять функции!
# Вызов функции
-foo "Мое имя" $NAME
+foo "Меня зовут" $NAME
# Есть много полезных команд, которые нужно знать:
# напечатать последние 10 строк файла file.txt
tail -n 10 file.txt
+
# напечатать первые 10 строк файла file.txt
head -n 10 file.txt
+
# отсортировать строки file.txt
sort file.txt
-# отобрать или наоборот пропустить повторяющиеся строки (с опцией -d отбирает)
+
+# отобрать или наоборот пропустить повторяющиеся строки (с параметром `-d` отбирает строки)
uniq -d file.txt
-# напечатать только первую колонку перед символом ','
+
+# напечатать только первый столбец перед символом «,»
cut -d ',' -f 1 file.txt
-# заменить каждое 'okay' на 'great' в файле file.txt (regex поддерживается)
-sed -i 's/okay/great/g' file.txt
-# вывести в stdout все строки из file.txt, совпадающие с шаблоном regex;
-# этот пример выводит строки, которые начинаются на "foo" и оканчиваются "bar"
+
+# заменить каждое вхождение «хорошо» на «прекрасно» в файле file.txt
+# (поддерживаются регулярные выражения)
+sed -i 's/хорошо/прекрасно/g' file.txt
+
+# вывести в stdout все строки из file.txt, соответствующие регулярному выражению
+# этот пример выводит строки, которые начинаются на «foo» и оканчиваются на «bar»
grep "^foo.*bar$" file.txt
-# передайте опцию -c чтобы вывести число строк, в которых совпал шаблон
+
+# Передайте параметр `-c`, чтобы вывести лишь число строк,
+# соответствующих регулярному выражению
grep -c "^foo.*bar$" file.txt
-# чтобы искать по строке, а не шаблону regex, используйте fgrep (или grep -F)
+
+# Ниже приведены другие полезные параметры:
+grep -r "^foo.*bar$" someDir/ # рекурсивный `grep`
+grep -n "^foo.*bar$" file.txt # задаются номера строк
+grep -rI "^foo.*bar$" someDir/ # рекурсивный `grep` с игнорированием двоичных файлов
+
+# Выполнить тот же изначальный поиск, но удалив строки, содержащие «baz»
+grep "^foo.*bar$" file.txt | grep -v "baz"
+
+# чтобы искать непосредственно по строке, а не в соответствии
+# с регулярным выражением, используйте fgrep (или grep -F):
fgrep "^foo.*bar$" file.txt
-# Читайте встроенную документацию оболочки Bash командой 'help':
+# Команда `trap` позволяет выполнить некую команду, когда ваш скрипт
+# принимает определённый Posix-сигнал. В следующем примере `trap` выполнит `rm`,
+# если скрипт примет один из трёх перечисленных сигналов.
+trap "rm $TEMP_FILE; exit" SIGHUP SIGINT SIGTERM
+
+# `sudo` используется для выполнения команд с правами суперпользователя
+NAME1=$(whoami)
+NAME2=$(sudo whoami)
+echo "Был $NAME1, затем стал более мощным $NAME2"
+
+# Читайте встроенную документацию оболочки Bash командой `help`:
help
help help
help for
@@ -274,18 +464,18 @@ help return
help source
help .
-# Читайте Bash man-документацию
+# Читайте man-документацию Bash командой `man`:
apropos bash
man 1 bash
man bash
-# Читайте документацию info (? для помощи)
+# Читайте документацию info (? для справки)
apropos info | grep '^info.*('
man info
info info
info 5 info
-# Читайте bash info документацию:
+# Читайте info-документацию Bash:
info bash
info bash 'Bash Features'
info bash 6
diff --git a/ru-ru/learnvisualbasic-ru.html.markdown b/ru-ru/learnvisualbasic-ru.html.markdown
new file mode 100644
index 00000000..72e1358c
--- /dev/null
+++ b/ru-ru/learnvisualbasic-ru.html.markdown
@@ -0,0 +1,284 @@
+---
+language: Visual Basic
+contributors:
+ - ["Brian Martin", "http://brianmartin.biz"]
+translators:
+ - ["satory-ra", "https://github.com/satory-ra"]
+filename: learnvisualbasic-ru.vb
+lang: ru-ru
+---
+
+```vbnet
+Module Module1
+
+ Sub Main()
+ 'Краткий обзор консольных приложений Visual Basic перед более
+ 'глубоким изучением.
+ 'Апостроф начинает строку комментария.
+ 'Чтобы изучить это руководство в компиляторе Visual Basic,
+ 'я создал систему навигации.
+ 'Эта система будет объяснена при прохождении этого урока.
+ 'Постепенно вы всё поймете.
+ Console.Title = ("Выучи Х за Y минут")
+ Console.WriteLine("НАВИГАЦИЯ") 'Display
+ Console.WriteLine("")
+ Console.ForegroundColor = ConsoleColor.Green
+ Console.WriteLine("1. Вывод данных")
+ Console.WriteLine("2. Ввод данных")
+ Console.WriteLine("3. Расчёт целых чисел")
+ Console.WriteLine("4. Расчёт десятичных дробей")
+ Console.WriteLine("5. Калькулятор")
+ Console.WriteLine("6. Использование циклов Do While")
+ Console.WriteLine("7. Использование циклов For")
+ Console.WriteLine("8. Условные выражения")
+ Console.WriteLine("9. Выберите напиток")
+ Console.WriteLine("50. О приложении")
+ Console.WriteLine("Выберите номер из списка")
+ Dim selection As String = Console.ReadLine
+ '«Case» в операторе Select не является обязательным.
+ 'Например, "Select selection" вместо "Select Case selection"
+ 'также будет работать.
+ Select Case selection
+ Case "1" 'Вывод данных
+ Console.Clear() 'Очищает окно консоли
+ HelloWorldOutput() 'Открывает приватную подпрограмму.
+ Case "2" 'Ввод данных
+ Console.Clear()
+ HelloWorldInput()
+ Case "3" 'Расчёт целых чисел
+ Console.Clear()
+ CalculatingWholeNumbers()
+ Case "4" 'Расчёт десятичных дробей
+ Console.Clear()
+ CalculatingDecimalNumbers()
+ Case "5" 'Калькулятор
+ Console.Clear()
+ WorkingCalculator()
+ Case "6" 'Использование циклов Do While
+ Console.Clear()
+ UsingDoWhileLoops()
+ Case "7" 'Использование циклов For
+ Console.Clear()
+ UsingForLoops()
+ Case "8" 'Условные выражения
+ Console.Clear()
+ ConditionalStatement()
+ Case "9" 'Выражения If/Else
+ Console.Clear()
+ IfElseStatement() 'Выберите напиток
+ Case "50" 'Окно сообщения «О приложении»
+ Console.Clear()
+ Console.Title = ("Выучи Х за Y минут :: О приложении")
+ MsgBox("Это руководство от Брайана Мартина (@BrianMartinn")
+ Console.Clear()
+ Main()
+ Console.ReadLine()
+
+ End Select
+ End Sub
+
+ 'Один - Я использую эти цифры для того, чтобы было проще
+ 'соотносить код с системой навигации.
+
+ 'Мы используем частные подпрограммы для разделения различных
+ 'разделов программы.
+ Private Sub HelloWorldOutput()
+ 'Название консольного приложения
+ Console.Title = "Вывод данных | Выучи Х за Y минут"
+ 'Используйте Console.Write ("") или Console.WriteLine ("")
+ 'для отображения результатов.
+ 'Затем следует Console.Read () или Console.Readline ()
+ 'Console.ReadLine () показывает вывод в консоли.
+ Console.WriteLine("Hello World")
+ Console.ReadLine()
+ End Sub
+
+ 'Два
+ Private Sub HelloWorldInput()
+ Console.Title = "Ввод данных | Выучи Х за Y минут"
+ 'Переменная
+ 'используется для хранения пользовательских данных.
+ 'Объявление переменных начинается с Dim и заканчиваются
+ 'As VariableType (тип переменной).
+
+ 'В этом уроке мы хотим узнать ваше имя и заставить программу
+ 'реагировать на это.
+ Dim username As String
+ 'Мы используем тип «string», так как ваше имя - это текстовая переменная.
+ Console.WriteLine("Привет, как тебя зовут? ") 'Просит ввести имя.
+ username = Console.ReadLine() 'Сохраняет имя в переменной username.
+ Console.WriteLine("Пирвет, " + username) 'Выводит: «Привет, 'имя'»
+ Console.ReadLine() 'Отображает вышеуказанный вывод.
+
+ 'Вышеуказанная программа спросит ваше имя и скажет вам привет.
+ 'Есть и другие типы переменных, такие как целые числа (Integer),
+ 'мы используем Integer для обработки целых чисел.
+ End Sub
+
+ 'Три
+ Private Sub CalculatingWholeNumbers()
+ Console.Title = "Расчёт целых чисел | Выучи Х за Y минут"
+ Console.Write("Первое число: ") 'Введите первое целое число: 1, 2, 50, 104 и т.д.
+ Dim a As Integer = Console.ReadLine()
+ Console.Write("Второе число: ") 'Введите второе целое число.
+ Dim b As Integer = Console.ReadLine()
+ Dim c As Integer = a + b
+ Console.WriteLine(c)
+ Console.ReadLine()
+ 'Приведенная программа сумирует два целых числа
+ End Sub
+
+ 'Четыре
+ Private Sub CalculatingDecimalNumbers()
+ Console.Title = "Расчёт десятичных дробей | Выучи Х за Y минут"
+ 'Мы также должны уметь обрабатывать десятичные дроби.
+ 'Просто измените тип переменной с Integer на Double.
+
+ 'Введите число с плавающей точкой: 1.2, 2.4, 50.1, 104.9 и т.д.
+ Console.Write("Первое число: ")
+ Dim a As Double = Console.ReadLine
+ Console.Write("Второе число: ") 'Введите второе число с плавающей точкой.
+ Dim b As Double = Console.ReadLine
+ Dim c As Double = a + b
+ Console.WriteLine(c)
+ Console.ReadLine()
+ 'Приведенный выше код может сложить две десятичных дроби.
+ End Sub
+
+ 'Пять
+ Private Sub WorkingCalculator()
+ Console.Title = "Калькулятор | Выучи Х за Y минут"
+ 'Но что, если вам нужен калькулятор, который может обрабатывать сложение,
+ 'вычитание, умножение и деление?
+ 'Просто скопируйте и вставьте приведенный код.
+ Console.Write("Первое число: ")
+ Dim a As Double = Console.ReadLine
+ Console.Write("Второе число: ")
+ Dim b As Double = Console.ReadLine
+ Dim c As Double = a + b
+ Dim d As Double = a * b
+ Dim e As Double = a - b
+ Dim f As Double = a / b
+
+ 'С помощью следующего кода мы можем вывести результат сложения,
+ 'вычитания, умножения и деления, рассчитанный выше, на экран.
+ Console.Write(a.ToString() + " + " + b.ToString())
+ 'Мы хотим, чтобы в начале ответа было 3 пробела, для этого
+ 'вы можете использовать метод String.PadLeft (3).
+ Console.WriteLine(" = " + c.ToString.PadLeft(3))
+ Console.Write(a.ToString() + " * " + b.ToString())
+ Console.WriteLine(" = " + d.ToString.PadLeft(3))
+ Console.Write(a.ToString() + " - " + b.ToString())
+ Console.WriteLine(" = " + e.ToString.PadLeft(3))
+ Console.Write(a.ToString() + " / " + b.ToString())
+ Console.WriteLine(" = " + f.ToString.PadLeft(3))
+ Console.ReadLine()
+
+ End Sub
+
+ 'Шесть
+ Private Sub UsingDoWhileLoops()
+ 'Код такой же, как и в предидущей подпрограмме
+ 'На этот раз мы спрашиваем, хочет ли пользователь продолжить (да или нет?)
+ 'Мы будем использовать цикл Do While, потому что не знаем,
+ 'понадобиться ли пользователю калькулятор болше одного раза.
+ Console.Title = "Использование циклов Do While | Выучи Х за Y минут"
+ Dim answer As String
+ 'Мы используем тип переменной "String", так как её значение текст.
+ Do 'Мы начаем программу с
+ Console.Write("Первое число: ")
+ Dim a As Double = Console.ReadLine
+ Console.Write("Второе число: ")
+ Dim b As Double = Console.ReadLine
+ Dim c As Double = a + b
+ Dim d As Double = a * b
+ Dim e As Double = a - b
+ Dim f As Double = a / b
+
+ Console.Write(a.ToString() + " + " + b.ToString())
+ Console.WriteLine(" = " + c.ToString.PadLeft(3))
+ Console.Write(a.ToString() + " * " + b.ToString())
+ Console.WriteLine(" = " + d.ToString.PadLeft(3))
+ Console.Write(a.ToString() + " - " + b.ToString())
+ Console.WriteLine(" = " + e.ToString.PadLeft(3))
+ Console.Write(a.ToString() + " / " + b.ToString())
+ Console.WriteLine(" = " + f.ToString.PadLeft(3))
+ Console.ReadLine()
+ 'Спросите пользователя, хочет ли он продолжить,
+ 'в ответе учитывается регистр букв.
+ Console.Write("Желаете ли вы продолжить? (да / нет)")
+ 'Программа берет значение и записывает в переменную answer.
+ answer = Console.ReadLine()
+ 'Когда пользователь вводит «да», программа переходит к Do и снова запускается.
+ Loop While answer = "yes"
+
+ End Sub
+
+ 'Семь
+ Private Sub UsingForLoops()
+ 'Иногда программу нужно запускать только один раз.
+ 'В этой программе мы осуществим обратный отсчет от 10.
+
+ Console.Title = "Использование циклов For | Выучи Х за Y минут"
+ 'Объявите переменные и Step (размер шага, то есть скорость уменьшения,
+ 'например, -1, -2, -3 и т.д.).
+ For i As Integer = 10 To 0 Step -1
+ Console.WriteLine(i.ToString) 'Показывает значение счетчика.
+ Next i 'Рассчитать новое значение i.
+ Console.WriteLine("Поехали")
+ Console.ReadLine()
+ End Sub
+
+ 'Восемь
+ Private Sub ConditionalStatement()
+ Console.Title = "Условные выражения | Выучи Х за Y минут"
+ Dim userName As String
+ Console.WriteLine("Привет, как тебя зовут? ") 'Спросите имя пользователя.
+ userName = Console.ReadLine() 'Записать имя в переменную userName.
+ If userName = "Адам" Then
+ Console.WriteLine("Привет, Адам")
+ Console.WriteLine("Спасибо за создание этого полезного сайта")
+ Console.ReadLine()
+ Else
+ Console.WriteLine("Привет " + userName)
+ Console.WriteLine("Вы заглянули на сайт www.learnxinyminutes.com")
+ Console.ReadLine() 'Программа останавливается и выводит вышеуказанный текст.
+ End If
+ End Sub
+
+ 'Девять
+ Private Sub IfElseStatement()
+ Console.Title = "Выражения If/Else | Выучи Х за Y минут"
+ 'Иногда важно рассмотреть более двух альтернатив.
+ 'Иногда некоторые из них лучше других.
+ 'Когда это произойдет, нам потребуется более одного утверждения «if» (если).
+ 'Оператор «if» подобен торговому автомату.
+ 'В котором пользователь пишет код (A1, A2, A3 и т.д.), чтобы выбрать элементы.
+ 'Все варианты могут быть объединены в одном утверждении «if».
+
+ Dim selection As String 'Объявить переменную для выбора
+ Console.WriteLine("Пожалуйста, выберите продукт из нашего прекрасного торгового автомата.")
+ Console.WriteLine("A1. для 7Up")
+ Console.WriteLine("A2. для Fanta")
+ Console.WriteLine("A3. для Dr. Pepper")
+ Console.WriteLine("A4. для Diet Coke")
+
+ selection = Console.ReadLine() 'Сохранить выбор пользователя
+ If selection = "A1" Then
+ Console.WriteLine("7up")
+ ElseIf selection = "A2" Then
+ Console.WriteLine("Fanta")
+ ElseIf selection = "A3" Then
+ Console.WriteLine("Dr. Pepper")
+ ElseIf selection = "A4" Then
+ Console.WriteLine("Diet Coke")
+ Else
+ Console.WriteLine("Извините, у меня нет " + selection)
+ End If
+ Console.ReadLine()
+
+ End Sub
+
+End Module
+
+```
diff --git a/ru-ru/linker-ru.html.markdown b/ru-ru/linker-ru.html.markdown
new file mode 100644
index 00000000..7df29c23
--- /dev/null
+++ b/ru-ru/linker-ru.html.markdown
@@ -0,0 +1,203 @@
+---
+category: tool
+tool: linker
+contributors:
+ - ["Alexander Kovalchuk", "https://github.com/Zamuhrishka"]
+translators:
+ - ["Alexander Kovalchuk", "https://github.com/Zamuhrishka"]
+lang: ru-ru
+---
+
+# Основные понятия и определения
+**Счетчик позиций** - у компоновщика есть специальная переменная
+"." (точка) всегда содержит текущую позицию вывода.
+
+# Функции
+**ADDR(section)** - возвращает абсолютный адрес указанной секции. Однако
+данная секция должна быть определенна до использования функции ADDR.
+
+**ALIGN(exp)** - возвращает значение счетчика позиций, выравненное на границу
+следующего за exp выражения.
+
+**SIZEOF(section)** - возвращает размер секции в байтах.
+
+**FILL(param)** - определяет образец заполнения для текущей секции. Все
+остальные неуказанные регионы внутри секции заполняются значением указанными
+в аргументе функции.
+
+**KEEP(param)** - используется чтобы помечать param как неустранимый.
+
+**ENTRY(func)** - определяет функцию, которая будет являться точкой входа
+в программу.
+
+```bash
+# Определяем точку входа в программу
+ENTRY(Reset_Handler)
+
+# Определяем перемнную которая содержит адрес вершины стека
+_estack = 0x20020000;
+# Определяем перемнную которая содержит значение размера кучи
+_Min_Heap_Size = 0x200;
+# Определяем перемнную которая содержит значение размера стека
+_Min_Stack_Size = 0x400;
+
+# Описание карты памяти доступной для данного процессора
+# MEMORY
+# {
+# ИМЯ_ОБЛАСТИ_ПАМЯТИ (права доступа) : ORIGIN = АДРЕС_НАЧАЛА, LENGTH = РАЗМЕР
+# }
+# В нашем примере контроллер содержит три области памяти:
+# RAM - начинается с адреса 0x20000000 и занимает 128 Кбайт;
+# CCMRAM - начинается с адреса 0x10000000и занимает 64 Кбайт;
+# FLASH - начинается с адреса 0x8000000 занимает 1024 Кбайт;
+# Причем RAM память доступка для чтения, записи и исполнения.
+# CCMRAM память доступна только на чтение и запись.
+# FLASH память доступна на чтение и исполнение.
+MEMORY
+{
+ RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 128K
+ CCMRAM (rw) : ORIGIN = 0x10000000, LENGTH = 64K
+ FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 1024K
+}
+
+# Описываем выходные секции
+SECTIONS
+{
+ # Первая секция содержит таблицу векторов прерываний
+ .isr_vector :
+ {
+ # Выравниваем текущую позицию на границу 4-х байт.
+ . = ALIGN(4);
+
+ # Существует опция --gc-sections, которая позволяет собирать мусор из неиспользуемых
+ # входных разделов. И если есть разделы, которые сборщик муссора не должен трогать,
+ # то их необходимо указать в качестве аргумента функции KEEP() (аналог ключевого слова
+ # volatile).
+ # Запись (*(.isr_vector)) означает разделы .isr_vector во всех объектных файлах. Т.к.
+ # обращение к разделу в общем виде выглядит так: (ИМЯ_ФАЙЛА(ИМЯ_РАЗДЕЛА))
+ KEEP(*(.isr_vector))
+
+ # Выравниваем текущую позицию на границу 4-х байт.
+ . = ALIGN(4);
+
+ # Выражение ">ОБЛАСТЬ_ПАМЯТИ" указывает в какую именно область памяти будет помещенна
+ # данная секция. В нашем слущае секция .isr_vector будет размещена во FLASH памяти.
+ } >FLASH
+
+# ИТОГО: Секция .isr_vector, которая содержит таблицу векторов прерываний выравнивается
+# по границе 4-х байт, помечается как недоступная для сборщика мусора и размещается в начале
+# FLASH памяти микроконтроллера.
+
+ # Вторая секция содержит код программы.
+ .text :
+ {
+ # Выравниваем текущую позицию на границу 4-х байт.
+ . = ALIGN(4);
+
+ # Указываем, что в данной секции будут хранится области .text всех
+ # объектных файлов
+ *(.text)
+ *(.text*)
+
+ # Защищаем от сборщика мусора секции .init и .fini
+ KEEP (*(.init))
+ KEEP (*(.fini))
+
+ # Выравниваем текущую позицию на границу 4-х байт.
+ . = ALIGN(4);
+
+ # Определяется переменная _etext, которая хранит в себе адрес конца секции .text и которая
+ # может быть доступна в исходном тексте программы через объявление
+ # volaile unsigned int extern _etext;
+ _etext = .;
+ } >FLASH
+
+# ИТОГО: Секция .text, которая содержит код программы выравнивается по границе 4-х байт,
+# включает в себя: все секции с кодом программы во всех объектных файлах и защищенные
+от сборщика муссора секции .init и .fini во всех объектных файлах, распологается во FLASH
+памяти микроконтроллера сразу за таблицей векторов.
+Секции text, .init и .fini. располагаются в памяти в той последовательности в которой они
+объявлены в скрипте.
+
+ # Третья секция содержит константные данные.
+ .rodata :
+ {
+ # Выравниваем текущую позицию на границу 4-х байт.
+ . = ALIGN(4);
+
+ # Указываем, что в данной секции будут хранится области .rodataвсех
+ # объектных файлов
+ *(.rodata)
+ *(.rodata*)
+
+ # Выравниваем текущую позицию на границу 4-х байт.
+ . = ALIGN(4);
+ } >FLASH
+
+ # Сохраняем в переменной _sidata абсолютный адрес секции .data
+ _sidata = LOADADDR(.data);
+
+ # Четвертая секция содержит инициализированные переменные.
+ .data :
+ {
+ # Выравниваем текущую позицию на границу 4-х байт.
+ . = ALIGN(4);
+
+ # Сохраняем в переменной _sdata адрес текущей позиции (начала секции)
+ _sdata = .;
+
+ # Указываем, что в данной секции будут хранится области .data всех
+ # объектных файлов
+ *(.data)
+ *(.data*)
+
+ # Выравниваем текущую позицию на границу 4-х байт.
+ . = ALIGN(4);
+
+ # Сохраняем в переменной _sdata адрес текущей позиции (конец секции)
+ _edata = .;
+
+ # Функция AT указывает на то, что данный сектор хранится в одной области памяти
+ # (в нашем случае FLASH), а исполняться будет из другой обасти памяти (в нашем случае RAM).
+ # Есть два типа адрессов:
+ # * VMA (Virtual memory address) - это run-time адрес по которому уомпилятор ожидает
+ # видеть данные.
+ # * LMA (Load memory address) - это адрес по которому линкер хранит данные.
+
+ #Startup должен код скопировать секцию .data из адрессов LMA в адресса VMA.
+
+ } >RAM AT> FLASH
+
+ # Пятая секция содержит инициализированные нулем переменные.
+ .bss :
+ {
+ # Сохраняем в переменной _sbss и __bss_start__ адрес текущей позиции (начала секции)
+ _sbss = .;
+ __bss_start__ = _sbss;
+
+ # Указываем, что в данной секции будут хранится области .bss всех
+ # объектных файлов
+ *(.bss)
+ *(.bss*)
+
+ # Выравниваем текущую позицию на границу 4-х байт.
+ . = ALIGN(4);
+
+ # Сохраняем в переменной _ebss и __bss_end__ адрес текущей позиции (начала секции)
+ _ebss = .;
+ __bss_end__ = _ebss;
+ } >RAM
+
+ # Шестая секция содержит кучу и стек. Размещается в самом конце RAM.
+ ._user_heap_stack :
+ {
+ . = ALIGN(4);
+ PROVIDE ( end = . );
+ PROVIDE ( _end = . );
+ . = . + _Min_Heap_Size;
+ . = . + _Min_Stack_Size;
+ . = ALIGN(4);
+ } >RAM
+}
+```
+
diff --git a/ru-ru/php-composer-ru.html.markdown b/ru-ru/php-composer-ru.html.markdown
new file mode 100644
index 00000000..4bdf1029
--- /dev/null
+++ b/ru-ru/php-composer-ru.html.markdown
@@ -0,0 +1,197 @@
+---
+category: tool
+tool: composer
+contributors:
+ - ["Brett Taylor", "https://github.com/glutnix"]
+translators:
+ - ["Aleksey Lysenko", "https://github.com/nasgul"]
+filename: LearnComposer-ru.sh
+lang: ru-ru
+---
+
+[Composer](https://getcomposer.org/) — это инструмент управления зависимостями в PHP.
+Он позволяет вам декларировать библиотеки, от которых зависит ваш проект,
+и он будет управлять ими, то есть устанавливать/обновлять их для вас.
+
+# Установка
+
+```sh
+# Устанавливаем composer.phar в текущую папку
+curl -sS https://getcomposer.org/installer | php
+# Если вы используете этот подход, вам нужно будет вызвать Composer следующим образом:
+php composer.phar about
+
+# Устанавливаем бинарный файл в ~/bin/composer
+# Примечание: убедитесь, что ~/bin находится в переменной PATH вашего окружения
+curl -sS https://getcomposer.org/installer | php -- --install-dir=~/bin --filename=composer
+```
+
+Пользователи Windows должны следовать
+[Инструкциям по установке в Windows ](https://getcomposer.org/doc/00-intro.md#installation-windows)
+
+## Подтверждение установки
+
+```sh
+# # Проверить версию и перечислить параметры
+composer
+
+# Получить дополнительную помощь для параметров
+composer help require
+
+# Проверить, способен ли Composer делать то, что ему нужно, и обновлён ли он
+composer diagnose
+composer diag # краткий вариант
+
+# Обновление Composer до последней версии
+composer self-update
+composer self # краткий вариант
+```
+
+# Использование
+
+Composer сохраняет ваши зависимости проекта в `composer.json`.
+Вы можете отредактировать этот файл, но лучше всего позволить Composer управлять им за вас.
+
+```sh
+# Создать новый проект в текущей папке
+composer init
+# запускается интерактивная анкета с просьбой предоставить подробную информацию о вашем проекте.
+# Вы прекрасно можете оставить ответы пустыми, если не делаете другие проекты
+# зависимыми от создаваемого проекта.
+
+# Если файл composer.json уже существует, загрузите зависимости
+composer install
+
+# Чтобы загрузить только зависимости для готового продукта, т.е.
+# исключая зависимости для разработки
+composer install --no-dev
+
+# Добавить зависимость для готового продукта к этому проекту
+composer require guzzlehttp/guzzle
+# выяснит, какая существует последняя версия guzzlehttp / guzzle,
+# загрузит её и добавит новую зависимость в поле require файла composer.json.
+
+composer require guzzlehttp/guzzle:6.0.*
+# Загрузит последнюю версию, соответствующую шаблону (например, 6.0.2),
+# и добавит зависимость к полю require файла composer.json
+
+composer require --dev phpunit/phpunit:~4.5.0
+# Добавит как зависимость для разработки.
+# Будет использовать последнюю версию> = 4.5.0 и <4.6.0
+
+composer require-dev phpunit/phpunit:^4.5.0
+# Добавит как зависимость для разработки.
+# Будет использовать последнюю версию> = 4.5.0 и <5.0
+
+# Для получения дополнительной информации о совместимости версий Composer см.
+# [Документацию Composer по версиям] (https://getcomposer.org/doc/articles/versions.md)
+
+# Чтобы узнать, какие пакеты доступны для установки и в настоящее время установлены
+composer show
+
+# Чтобы узнать, какие пакеты в настоящее время установлены
+composer show --installed
+
+# Чтобы найти пакет со строкой «mailgun» в названии или описании
+composer search mailgun
+```
+
+[Packagist.org](https://packagist.org/) является основным хранилищем для пакетов Composer.
+Существующие сторонние пакеты ищите там.
+
+## composer.json` и `composer.lock`
+
+Файл `composer.json` хранит параметры допустимых версий каждой зависимости
+вашего проекта, а также другую информацию.
+
+
+Файл `composer.lock` хранит точную загруженную версию каждой зависимости.
+Никогда не редактируйте этот файл.
+
+Если вы включите файл `composer.lock` в свой Git-репозиторий,
+каждый разработчик установит версии зависимостей, которые вы используете.
+Даже когда будет выпущена новая версия зависимости, Composer продолжит загрузку версии,
+записанной в lock-файле.
+
+```sh
+# Если вы хотите обновить все зависимости до новейших версий,
+# которые по-прежнему соответствуют вашим предпочтениям для версий
+composer update
+
+# Если вам нужна новая версия определённой зависимости:
+composer update phpunit/phpunit
+
+# Если вы хотите перенести пакет на более новую версию
+#с изменением предпочитаемой версии,
+# вам может потребоваться сначала удалить старый пакет и его зависимости.
+composer remove --dev phpunit/phpunit
+composer require --dev phpunit/phpunit:^5.0
+```
+
+## Автозагрузчик
+
+Composer создаёт класс автозагрузки, который вы можете вызвать
+из своего приложения. Вы можете создавать экземпляры классов через пространство имён.
+
+```php
+require __DIR__ . '/vendor/autoload.php';
+
+$mailgun = new Mailgun\Mailgun("key");
+```
+
+### PSR-4-совместимый автозагрузчик
+
+
+Вы можете добавить в автозагрузчик свои собственные пространства имён.
+
+Добавьте поле `autoload` в `composer.json`:
+
+```json
+{
+ "autoload": {
+ "psr-4": {"Acme\\": "src/"}
+ }
+}
+```
+Это скажет автозагрузчику искать что-либо в пространстве имён `\Acme` в папке `src`.
+
+Вы также можете использовать
+[PSR-0, карту классов или просто список файлов для включения](https://getcomposer.org/doc/04-schema.md#autoload).
+Также существует поле `autoload-dev` для пространств имён, предназначенных только для разработки.
+
+При добавлении или изменении ключа автозагрузки вам необходимо перестроить автозагрузчик:
+
+```sh
+composer dump-autoload
+composer dump # краткий вариант
+
+# Оптимизирует пакеты PSR0 и PSR4 для загрузки классов с помощью карты классов.
+# Медленно запускается, но улучшает производительность готового продукта.
+composer dump-autoload --optimize --no-dev
+```
+
+# Кэш Composer
+
+```sh
+# Composer хранит загруженные пакеты для использования в будущем. Очистите кэш с помощью:
+composer clear-cache
+```
+
+# Устранение неполадок
+
+```sh
+composer diagnose
+composer self-update
+composer clear-cache
+```
+
+## Темы, которые ещё (пока) не включены в этот учебник
+
+* Создание и распространение ваших собственных пакетов на Packagist.org или в другом репозитории
+* Предварительные и пост-скриптовые перехватчики: запуск задач,
+когда происходят определенные события Composer
+
+### Ссылки
+
+* [Composer - Dependency Manager for PHP](https://getcomposer.org/)
+* [Packagist.org](https://packagist.org/)
diff --git a/ru-ru/python-ru.html.markdown b/ru-ru/python-ru.html.markdown
index 43142eff..6087a686 100644
--- a/ru-ru/python-ru.html.markdown
+++ b/ru-ru/python-ru.html.markdown
@@ -541,7 +541,7 @@ Human.grunt() #=> "*grunt*"
# Вы можете импортировать модули
import math
-print(math.sqrt(16)) #=> 4
+print(math.sqrt(16)) #=> 4.0
# Вы можете импортировать отдельные функции модуля
from math import ceil, floor
diff --git a/ru-ru/yaml-ru.html.markdown b/ru-ru/yaml-ru.html.markdown
new file mode 100644
index 00000000..6eb580d9
--- /dev/null
+++ b/ru-ru/yaml-ru.html.markdown
@@ -0,0 +1,189 @@
+---
+language: yaml
+filename: learnyaml-ru.yaml
+contributors:
+- [Adam Brenecki, 'https://github.com/adambrenecki']
+- [Suhas SG, 'https://github.com/jargnar']
+translators:
+- [Sergei Babin, 'https://github.com/serzn1']
+lang: ru-ru
+---
+
+YAML как язык сериализации данных предназначен прежде всего для использования людьми.
+
+Это строгое надмножество JSON с добавлением синтаксически значимых переносов строк и
+отступов как в Python. Тем не менее, в отличие от Python, YAML запрещает
+использование табов для отступов.
+
+```yaml
+--- # начало документа
+
+# Комментарий в YAML выглядит как-то так.
+
+######################
+# Скалярные величины #
+######################
+
+# Наш корневой объект (который продолжается для всего документа) будет соответствовать
+# типу map, который в свою очередь соответствует словарю, хешу или объекту в других языках.
+key: value
+another_key: Другое значение ключа.
+a_number_value: 100
+scientific_notation: 1e+12
+# Число 1 будет интерпретировано как число, а не как логический тип. Если необходимо чтобы
+# значение было интерпретировано как логическое, необходимо использовать true
+boolean: true
+null_value: null
+key with spaces: value
+
+# Обратите внимание что строки используются без кавычек, но могут и с кавычками.
+however: 'Строка заключенная в кавычки.'
+'Ключ заключенный в кавычки.': "Полезно если нужно использовать ':' в вашем ключе."
+single quotes: 'Содержит ''одну'' экранированную строку'
+double quotes: "Содержит несколько: \", \0, \t, \u263A, \x0d\x0a == \r\n, экранированных строк."
+
+# Многострочные строковые значения могут быть записаны как 'строковый блок' (используя |),
+# или как 'сложенный блок' (используя '>').
+literal_block: |
+ Значение всего текста в этом блоке будет присвоено ключу 'literal_block',
+ с сохранением переноса строк.
+
+ Объявление продолжается до удаления отступа и выравнивания с ведущим отступом.
+
+ Любые строки с большим отступом сохраняют остатки своего отступа -
+ эта строка будет содержать дополнительно 4 пробела.
+folded_style: >
+ Весь блок этого тектса будет значением 'folded_style', но в данном случае
+ все символы новой строки будут заменены пробелами.
+
+ Пустые строки будут преобразованы в перенос строки.
+
+ Строки с дополнительными отступами сохраняют их переносы строк -
+ этот текст появится через 2 строки.
+
+##################
+# Типы коллекций #
+##################
+
+# Вложения используют отступы. Отступ в 2 пробела предпочтителен (но не обязателен).
+a_nested_map:
+ key: value
+ another_key: Another Value
+ another_nested_map:
+ hello: hello
+
+# В словарях (maps) используются не только строковые значения ключей.
+0.25: a float key
+
+# Ключи также могут быть сложными, например многострочными.
+# Мы используем ? с последующим пробелом чтобы обозначить начало сложного ключа.
+? |
+ Этот ключ
+ который содержит несколько строк
+: и это его значение
+
+# YAML также разрешает соответствия между последовательностями со сложными ключами
+# Некоторые парсеры могут выдать предупреждения или ошибку
+# Пример
+? - Manchester United
+ - Real Madrid
+: [2001-01-01, 2002-02-02]
+
+# Последовательности (эквивалент списка или массива) выглядят как-то так
+# (обратите внимание что знак '-' считается отступом):
+a_sequence:
+ - Item 1
+ - Item 2
+ - 0.5 # последовательности могут содержать различные типы.
+ - Item 4
+ - key: value
+ another_key: another_value
+ -
+ - Это последовательность
+ - внутри другой последовательности
+ - - - Объявления вложенных последовательностей
+ - могут быть сжаты
+
+# Поскольку YAML это надмножество JSON, вы можете использовать JSON-подобный
+# синтаксис для словарей и последовательностей:
+json_map: {"key": "value"}
+json_seq: [3, 2, 1, "takeoff"]
+в данном случае кавычки не обязательны: {key: [3, 2, 1, takeoff]}
+
+##########################
+# Дополнительные функции #
+##########################
+
+# В YAML есть удобная система так называемых 'якорей' (anchors), которые позволяют легко
+# дублировать содержимое внутри документа. Оба ключа в примере будут иметь одинаковые значения:
+anchored_content: &anchor_name Эта строка будет являться значением обоих ключей.
+other_anchor: *anchor_name
+
+# Якоря могут использоваться для дублирования/наследования свойств
+base: &base
+ name: Каждый будет иметь одинаковое имя
+
+# Регулярное выражение << называется ключом объединения независимо от типа языка.
+# Он используется чтобы показать что все ключи одного или более словарей должны быть
+# добавлены в текущий словарь.
+
+foo: &foo
+ <<: *base
+ age: 10
+
+bar: &bar
+ <<: *base
+ age: 20
+
+# foo и bar могли бы иметь имена: Каждый из них имеет аналогичное имя
+
+# В YAML есть теги (tags), которые используются для явного объявления типов.
+explicit_string: !!str 0.5
+# В некоторых парсерах реализованы теги для конкретного языка, пример для Python
+# пример сложного числового типа.
+python_complex_number: !!python/complex 1+2j
+
+# Мы можем использовать сложные ключи с включенными в них тегами из определенного языка
+? !!python/tuple [5, 7]
+: Fifty Seven
+# Могло бы быть {(5, 7): 'Fifty Seven'} в Python
+
+#######################
+# Дополнительные типы #
+#######################
+
+# Строки и числа не единственные величины которые может понять YAML.
+# YAML также поддерживает даты и время в формате ISO.
+datetime: 2001-12-15T02:59:43.1Z
+datetime_with_spaces: 2001-12-14 21:59:43.10 -5
+date: 2002-12-14
+
+# Тег !!binary показывает что эта строка является base64-закодированным
+# представлением двоичного объекта.
+gif_file: !!binary |
+ R0lGODlhDAAMAIQAAP//9/X17unp5WZmZgAAAOfn515eXvPz7Y6OjuDg4J+fn5
+ OTk6enp56enmlpaWNjY6Ojo4SEhP/++f/++f/++f/++f/++f/++f/++f/++f/+
+ +f/++f/++f/++f/++f/++SH+Dk1hZGUgd2l0aCBHSU1QACwAAAAADAAMAAAFLC
+ AgjoEwnuNAFOhpEMTRiggcz4BNJHrv/zCFcLiwMWYNG84BwwEeECcgggoBADs=
+
+# YAML может использовать объекты типа ассоциативных массивов (set), как представлено ниже:
+set:
+ ? item1
+ ? item2
+ ? item3
+or: {item1, item2, item3}
+
+# Сеты (set) являются простыми эквивалентами словарей со значениями
+# типа null; запись выше эквивалентна следующей:
+set2:
+ item1: null
+ item2: null
+ item3: null
+
+... # конец документа
+```
+
+### Больше информации
+
++ [YAML оффициальный вебсайт](http://yaml.org/)
++ [YAML онлайн валидатор](http://www.yamllint.com/)
diff --git a/scala.html.markdown b/scala.html.markdown
index 28424684..c7a8842e 100644
--- a/scala.html.markdown
+++ b/scala.html.markdown
@@ -345,7 +345,7 @@ s(0) // Boolean = false
s(1) // Boolean = true
/* Look up the documentation of map here -
- * http://www.scala-lang.org/api/current/index.html#scala.collection.immutable.Map
+ * https://www.scala-lang.org/api/current/scala/collection/immutable/Map.html
* and make sure you can read it
*/
diff --git a/sl-si/asciidoc-sl.html.markdown b/sl-si/asciidoc-sl.html.markdown
new file mode 100644
index 00000000..52f30fbd
--- /dev/null
+++ b/sl-si/asciidoc-sl.html.markdown
@@ -0,0 +1,136 @@
+---
+language: asciidoc
+contributors:
+ - ["Ryan Mavilia", "http://unoriginality.rocks/"]
+ - ["Abel Salgado Romero", "https://twitter.com/abelsromero"]
+translators:
+ - ["Filip Štamcar", "https://github.com/filips123"]
+lang: sl-si
+filename: asciidoc-sl.md
+---
+
+AsciiDoc je označevalni jezik, ki je podoben Markdownu in ga je mogoče uporabiti za vse od knjig do spletnih dnevnikov. Jezik, ki ga je leta 2002 ustvaril Stuart Rackham, je preprost, vendar omogoča veliko prilagoditev.
+
+## Glava dokumenta
+
+Glave so neobvezne in ne smejo vsebovati praznih vrstic. Od vsebine jih mora ločiti vsaj ena prazna vrstica.
+
+### Naslov
+
+```
+= Naslov dokumenta
+
+Prvi stavek dokumenta.
+```
+
+### Naslov in avtor
+
+```
+= Naslov dokumenta
+Ime Priimek <ime.priimek@learnxinyminutes.com>
+
+Prvi stavek dokumenta.
+```
+
+### Naslov in več avtorjev
+
+```
+
+= Naslov dokumenta
+Ime Priimek <ime.priimek@learnxinyminutes.com>; Janez Novak <janez.novak@pirate.com>
+
+Prvi stavek dokumenta.
+```
+
+Vrstica za revizijo
+
+```
+= Naslov dokumenta V1
+Janez Novak <janez.novak@pirate.com>
+v1.0, 2016-01-13
+
+Prvi stavek dokumenta.
+```
+
+## Odstavki
+
+```
+Za odstavke ne potrebujete nič posebnega.
+
+Da jih ločite, dodajte prazno črto med odstavki.
+
+Če želite ustvariti prazno vrstico, dodajte +
+in ustvarili boste prelom vrstice!
+```
+
+## Oblikovanje besedila
+
+```
+_podčrtaj za pošvno_
+*zvezdice za krepko*
+*_kombinacije za zabavo_*
+`krativec za monospace`
+`*krepki monospace*`
+```
+
+## Naslovi razdelkov
+
+```
+= Stopnja 0 (samo za naslov dokumenta)
+
+== Stopnja 1 <h2>
+
+=== Stopnja 2 <h3>
+
+==== Stopnja 3 <h4>
+
+===== Stopnja 4 <h5>
+
+```
+
+## Seznami
+
+Če želite ustvariti neoštevilčen seznam, uporabite zvezdice.
+
+```
+* foo
+* bar
+* baz
+```
+
+Če želite ustvaril oštevilčen seznam, uporabite pike.
+
+```
+. predmet 1
+. predmet 2
+. predmet 3
+```
+
+Seznami lahko do petkrat gnezdite tako, da dodate dodatne zvezdice ali pike.
+
+```
+* foo 1
+** foo 2
+*** foo 3
+**** foo 4
+***** foo 5
+
+. foo 1
+.. foo 2
+... foo 3
+.... foo 4
+..... foo 5
+```
+
+## Nadaljnje branje
+
+Obstajata dve orodji za obdelavo AsciiDoc dokumentov:
+
+1. [AsciiDoc](http://asciidoc.org/): izvirna implementacija v Pythonu je na voljo v glavnih distribucijah Linuxa. Stabilen in trenutno v vzdrževalnem načinu.
+2. [Asciidoctor](http://asciidoctor.org/): alternativna Ruby implementacija, uporabno tudi iz Java in JavaScript. Z aktivnim razvojem si prizadeva razširiti sintakso AsciiDoc z novimi funkcijami in izhodnimi formati.
+
+Naslednje povezave so povezane `Asciidoctor` implementacijo:
+
+* [Markdown - AsciiDoc syntax comparison](http://asciidoctor.org/docs/user-manual/#comparison-by-example): primerjava skupnih elementov Markdowna in AsciiDoca.
+* [Getting started](http://asciidoctor.org/docs/#get-started-with-asciidoctor): namestitev in navodila, ki omogočajo enostavne dokumente.
+* [Asciidoctor User Manual](http://asciidoctor.org/docs/user-manual/): popolni priročnik z enim dokumentom s sklicevanjem na sintakso, primeri in oridji za upodabljanje.
diff --git a/smalltalk.html.markdown b/smalltalk.html.markdown
index 87135cf4..ae7ecb0e 100644
--- a/smalltalk.html.markdown
+++ b/smalltalk.html.markdown
@@ -2,7 +2,7 @@
language: Smalltalk
filename: smalltalk.st
contributors:
- - ["Jigyasa Grover", "https://github.com/jig08"]
+ - ["Jigyasa Grover", "https://github.com/jigyasa-grover"]
- ["tim Rowledge", "tim@rowledge.org"]
---
@@ -10,18 +10,19 @@ contributors:
- Smalltalk was created as the language to underpin the "new world" of computing exemplified by "human–computer symbiosis."
- It was designed and created in part for educational use, more so for constructionist learning, at the Learning Research Group (LRG) of Xerox PARC by Alan Kay, Dan Ingalls, Adele Goldberg, Ted Kaehler, Scott Wallace, and others during the 1970s.
-Feedback highly appreciated! Reach me at [@jigyasa_grover](https://twitter.com/jigyasa_grover) or send me an e-mail at `grover.jigyasa1@gmail.com`.
+`Feedback highly appreciated! Reach me at [@jigyasa_grover](https://twitter.com/jigyasa_grover) or send me an e-mail at grover.jigyasa1@gmail.com.`
## The Basics
+
### Everything is an object
Yes, everything. Integers are instances of one of the numeric classes. Classes are instances of the class Metaclass and are just as manipulable as any other object. All classes are part of a single class tree; no disjoint class trees. Stack frames are objects and can be manipulated, which is how the debugger works. There are no pointers into memory locations that you can dereference and mess with.
### Functions are not called; messages are sent to objects
-Work is done by sending messages to objects, which decide how to respond to that message and run a method as a result, which eventually returns some object to the original message sending code.
-The system knows the class of the object receiving a message and looks up the message in that class's list of methods. If it is not found, the lookup continues in the super class until either it is found or the root of the classes is reached and there is still no relevant method.
-If a suitable method is found the code is run, and the same process keeps on going with all the methods sent by that method and so on forever.
-If no suitable method is found an exception is raised, which typically results in a user interface notifier to tell the user that the message was not understood. It is entirely possible to catch the exception and do something to fix the problem, which might range from 'ignore it' to 'load some new packages for this class and try again'.
-A method (more strictly an instance of the class CompiledMethod) is a chunk of Smalltalk code that has been compiled into bytecodes. Executing methods start at the beginning and return to the sender when a return is encountered (we use ^ to signify 'return the follwing object') or the end of the code is reached, in which case the current object running the code is returned.
+- Work is done by sending messages to objects, which decide how to respond to that message and run a method as a result, which eventually returns some object to the original message sending code.
+- The system knows the class of the object receiving a message and looks up the message in that class's list of methods. If it is not found, the lookup continues in the super class until either it is found or the root of the classes is reached and there is still no relevant method.
+- If a suitable method is found the code is run, and the same process keeps on going with all the methods sent by that method and so on forever.
+- If no suitable method is found an exception is raised, which typically results in a user interface notifier to tell the user that the message was not understood. It is entirely possible to catch the exception and do something to fix the problem, which might range from 'ignore it' to 'load some new packages for this class and try again'.
+- A method (more strictly an instance of the class CompiledMethod) is a chunk of Smalltalk code that has been compiled into bytecodes. Executing methods start at the beginning and return to the sender when a return is encountered (we use ^ to signify 'return the follwing object') or the end of the code is reached, in which case the current object running the code is returned.
### Simple syntax
Smalltalk has a simple syntax with very few rules.
@@ -55,7 +56,9 @@ self size > 4 ifTrue: [^argumentObject sizeRelatingTo: self].
```
Everything here except the `^` involves sending more messages. Event the `ifTrue:` that you might think is a language control structure is just Smalltalk code.
+
We start by sending `size` to `self`. `self` is the object currently running the code - so in this case it is the myObject we started with. `size` is a very common message that we might anticipate tells us something about how big an object is; you could look it up with the Smalltalk tools very simply. The result we get is then sent the message `>` with the plain old integer 4 (which is an object too; no strange primitive types to pollute the system here) and nobody should be surprised the `>` is a comparison that answers true or false. That boolean (which is actually a Boolean object in Smalltalk) is sent the message `ifTrue:` with the block of code between the `[]` as its argument; obvioulsy a true boolean might be expected to run that block of code and a false to ignore it.
+
If the block is run then we do some more message sending to the argument object and noting the `^` we return the answer back to our starting point and it gets assigned to `result`. If the block is ignored we seem to run out of code and so `self` is returned and assigned to `result`.
## Smalltalk quick reference cheat-sheet
@@ -92,179 +95,178 @@ Taken from [Smalltalk Cheatsheet](http://www.angelfire.com/tx4/cus/notes/smallta
#### Transcript:
```
-Transcript clear. "clear to transcript window"
-Transcript show: 'Hello World'. "output string in transcript window"
-Transcript nextPutAll: 'Hello World'. "output string in transcript window"
-Transcript nextPut: $A. "output character in transcript window"
-Transcript space. "output space character in transcript window"
-Transcript tab. "output tab character in transcript window"
-Transcript cr. "carriage return / linefeed"
-'Hello' printOn: Transcript. "append print string into the window"
-'Hello' storeOn: Transcript. "append store string into the window"
-Transcript endEntry. "flush the output buffer"
+Transcript clear. "clear to transcript window"
+Transcript show: 'Hello World'. "output string in transcript window"
+Transcript nextPutAll: 'Hello World'. "output string in transcript window"
+Transcript nextPut: $A. "output character in transcript window"
+Transcript space. "output space character in transcript window"
+Transcript tab. "output tab character in transcript window"
+Transcript cr. "carriage return / linefeed"
+'Hello' printOn: Transcript. "append print string into the window"
+'Hello' storeOn: Transcript. "append store string into the window"
+Transcript endEntry. "flush the output buffer"
```
#### Assignment:
```
| x y |
-x _ 4. "assignment (Squeak) <-"
-x := 5. "assignment"
-x := y := z := 6. "compound assignment"
+x _ 4. "assignment (Squeak) <-"
+x := 5. "assignment"
+x := y := z := 6. "compound assignment"
x := (y := 6) + 1.
-x := Object new. "bind to allocated instance of a class"
-x := 123 class. "discover the object class"
-x := Integer superclass. "discover the superclass of a class"
-x := Object allInstances. "get an array of all instances of a class"
-x := Integer allSuperclasses. "get all superclasses of a class"
-x := 1.2 hash. "hash value for object"
-y := x copy. "copy object"
-y := x shallowCopy. "copy object (not overridden)"
-y := x deepCopy. "copy object and instance vars"
-y := x veryDeepCopy. "complete tree copy using a dictionary"
+x := Object new. "bind to allocated instance of a class"
+x := 123 class. "discover the object class"
+x := Integer superclass. "discover the superclass of a class"
+x := Object allInstances. "get an array of all instances of a class"
+x := Integer allSuperclasses. "get all superclasses of a class"
+x := 1.2 hash. "hash value for object"
+y := x copy. "copy object"
+y := x shallowCopy. "copy object (not overridden)"
+y := x deepCopy. "copy object and instance vars"
+y := x veryDeepCopy. "complete tree copy using a dictionary"
```
#### Constants:
```
| b |
-b := true. "true constant"
-b := false. "false constant"
-x := nil. "nil object constant"
-x := 1. "integer constants"
-x := 3.14. "float constants"
-x := 2e-2. "fractional constants"
-x := 16r0F. "hex constant".
-x := -1. "negative constants"
-x := 'Hello'. "string constant"
-x := 'I''m here'. "single quote escape"
-x := $A. "character constant"
-x := $ . "character constant (space)"
-x := #aSymbol. "symbol constants"
-x := #(3 2 1). "array constants"
-x := #('abc' 2 $a). "mixing of types allowed"
+b := true. "true constant"
+b := false. "false constant"
+x := nil. "nil object constant"
+x := 1. "integer constants"
+x := 3.14. "float constants"
+x := 2e-2. "fractional constants"
+x := 16r0F. "hex constant".
+x := -1. "negative constants"
+x := 'Hello'. "string constant"
+x := 'I''m here'. "single quote escape"
+x := $A. "character constant"
+x := $ . "character constant (space)"
+x := #aSymbol. "symbol constants"
+x := #(3 2 1). "array constants"
+x := #('abc' 2 $a). "mixing of types allowed"
```
#### Booleans:
```
| b x y |
x := 1. y := 2.
-b := (x = y). "equals"
-b := (x ~= y). "not equals"
-b := (x == y). "identical"
-b := (x ~~ y). "not identical"
-b := (x > y). "greater than"
-b := (x < y). "less than"
-b := (x >= y). "greater than or equal"
-b := (x <= y). "less than or equal"
-b := b not. "boolean not"
-b := (x < 5) & (y > 1). "boolean and"
-b := (x < 5) | (y > 1). "boolean or"
-b := (x < 5) and: [y > 1]. "boolean and (short-circuit)"
-b := (x < 5) or: [y > 1]. "boolean or (short-circuit)"
-b := (x < 5) eqv: (y > 1). "test if both true or both false"
-b := (x < 5) xor: (y > 1). "test if one true and other false"
-b := 5 between: 3 and: 12. "between (inclusive)"
-b := 123 isKindOf: Number. "test if object is class or subclass of"
-b := 123 isMemberOf: SmallInteger. "test if object is type of class"
-b := 123 respondsTo: sqrt. "test if object responds to message"
-b := x isNil. "test if object is nil"
-b := x isZero. "test if number is zero"
-b := x positive. "test if number is positive"
-b := x strictlyPositive. "test if number is greater than zero"
-b := x negative. "test if number is negative"
-b := x even. "test if number is even"
-b := x odd. "test if number is odd"
-b := x isLiteral. "test if literal constant"
-b := x isInteger. "test if object is integer"
-b := x isFloat. "test if object is float"
-b := x isNumber. "test if object is number"
-b := $A isUppercase. "test if upper case character"
-b := $A isLowercase. "test if lower case character"
+b := (x = y). "equals"
+b := (x ~= y). "not equals"
+b := (x == y). "identical"
+b := (x ~~ y). "not identical"
+b := (x > y). "greater than"
+b := (x < y). "less than"
+b := (x >= y). "greater than or equal"
+b := (x <= y). "less than or equal"
+b := b not. "boolean not"
+b := (x < 5) & (y > 1). "boolean and"
+b := (x < 5) | (y > 1). "boolean or"
+b := (x < 5) and: [y > 1]. "boolean and (short-circuit)"
+b := (x < 5) or: [y > 1]. "boolean or (short-circuit)"
+b := (x < 5) eqv: (y > 1). "test if both true or both false"
+b := (x < 5) xor: (y > 1). "test if one true and other false"
+b := 5 between: 3 and: 12. "between (inclusive)"
+b := 123 isKindOf: Number. "test if object is class or subclass of"
+b := 123 isMemberOf: SmallInteger. "test if object is type of class"
+b := 123 respondsTo: sqrt. "test if object responds to message"
+b := x isNil. "test if object is nil"
+b := x isZero. "test if number is zero"
+b := x positive. "test if number is positive"
+b := x strictlyPositive. "test if number is greater than zero"
+b := x negative. "test if number is negative"
+b := x even. "test if number is even"
+b := x odd. "test if number is odd"
+b := x isLiteral. "test if literal constant"
+b := x isInteger. "test if object is integer"
+b := x isFloat. "test if object is float"
+b := x isNumber. "test if object is number"
+b := $A isUppercase. "test if upper case character"
+b := $A isLowercase. "test if lower case character"
```
#### Arithmetic expressions:
```
| x |
-x := 6 + 3. "addition"
-x := 6 - 3. "subtraction"
-x := 6 * 3. "multiplication"
-x := 1 + 2 * 3. "evaluation always left to right (1 + 2) * 3"
-x := 5 / 3. "division with fractional result"
-x := 5.0 / 3.0. "division with float result"
-x := 5.0 // 3.0. "integer divide"
-x := 5.0 \\ 3.0. "integer remainder"
-x := -5. "unary minus"
-x := 5 sign. "numeric sign (1, -1 or 0)"
-x := 5 negated. "negate receiver"
-x := 1.2 integerPart. "integer part of number (1.0)"
-x := 1.2 fractionPart. "fractional part of number (0.2)"
-x := 5 reciprocal. "reciprocal function"
-x := 6 * 3.1. "auto convert to float"
-x := 5 squared. "square function"
-x := 25 sqrt. "square root"
-x := 5 raisedTo: 2. "power function"
-x := 5 raisedToInteger: 2. "power function with integer"
-x := 5 exp. "exponential"
-x := -5 abs. "absolute value"
-x := 3.99 rounded. "round"
-x := 3.99 truncated. "truncate"
-x := 3.99 roundTo: 1. "round to specified decimal places"
-x := 3.99 truncateTo: 1. "truncate to specified decimal places"
-x := 3.99 floor. "truncate"
-x := 3.99 ceiling. "round up"
-x := 5 factorial. "factorial"
-x := -5 quo: 3. "integer divide rounded toward zero"
-x := -5 rem: 3. "integer remainder rounded toward zero"
-x := 28 gcd: 12. "greatest common denominator"
-x := 28 lcm: 12. "least common multiple"
-x := 100 ln. "natural logarithm"
-x := 100 log. "base 10 logarithm"
-x := 100 log: 10. "logarithm with specified base"
-x := 100 floorLog: 10. "floor of the log"
-x := 180 degreesToRadians. "convert degrees to radians"
-x := 3.14 radiansToDegrees. "convert radians to degrees"
-x := 0.7 sin. "sine"
-x := 0.7 cos. "cosine"
-x := 0.7 tan. "tangent"
-x := 0.7 arcSin. "arcsine"
-x := 0.7 arcCos. "arccosine"
-x := 0.7 arcTan. "arctangent"
-x := 10 max: 20. "get maximum of two numbers"
-x := 10 min: 20. "get minimum of two numbers"
-x := Float pi. "pi"
-x := Float e. "exp constant"
-x := Float infinity. "infinity"
-x := Float nan. "not-a-number"
-x := Random new next; yourself. x next. "random number stream (0.0 to 1.0)"
-x := 100 atRandom. "quick random number"
+x := 6 + 3. "addition"
+x := 6 - 3. "subtraction"
+x := 6 * 3. "multiplication"
+x := 1 + 2 * 3. "evaluation always left to right (1 + 2) * 3"
+x := 5 / 3. "division with fractional result"
+x := 5.0 / 3.0. "division with float result"
+x := 5.0 // 3.0. "integer divide"
+x := 5.0 \\ 3.0. "integer remainder"
+x := -5. "unary minus"
+x := 5 sign. "numeric sign (1, -1 or 0)"
+x := 5 negated. "negate receiver"
+x := 1.2 integerPart. "integer part of number (1.0)"
+x := 1.2 fractionPart. "fractional part of number (0.2)"
+x := 5 reciprocal. "reciprocal function"
+x := 6 * 3.1. "auto convert to float"
+x := 5 squared. "square function"
+x := 25 sqrt. "square root"
+x := 5 raisedTo: 2. "power function"
+x := 5 raisedToInteger: 2. "power function with integer"
+x := 5 exp. "exponential"
+x := -5 abs. "absolute value"
+x := 3.99 rounded. "round"
+x := 3.99 truncated. "truncate"
+x := 3.99 roundTo: 1. "round to specified decimal places"
+x := 3.99 truncateTo: 1. "truncate to specified decimal places"
+x := 3.99 floor. "truncate"
+x := 3.99 ceiling. "round up"
+x := 5 factorial. "factorial"
+x := -5 quo: 3. "integer divide rounded toward zero"
+x := -5 rem: 3. "integer remainder rounded toward zero"
+x := 28 gcd: 12. "greatest common denominator"
+x := 28 lcm: 12. "least common multiple"
+x := 100 ln. "natural logarithm"
+x := 100 log. "base 10 logarithm"
+x := 100 log: 10. "floor of the log"
+x := 180 degreesToRadians. "convert degrees to radians"
+x := 3.14 radiansToDegrees. "convert radians to degrees"
+x := 0.7 sin. "sine"
+x := 0.7 cos. "cosine"
+x := 0.7 tan. "tangent"
+x := 0.7 arcSin. "arcsine"
+x := 0.7 arcCos. "arccosine"
+x := 0.7 arcTan. "arctangent"
+x := 10 max: 20. "get maximum of two numbers"
+x := 10 min: 20. "get minimum of two numbers"
+x := Float pi. "pi"
+x := Float e. "exp constant"
+x := Float infinity. "infinity"
+x := Float nan. "not-a-number"
+x := Random new next; yourself. x next. "random number stream (0.0 to 1.0)"
+x := 100 atRandom. "quick random number"
```
#### Bitwise Manipulation:
```
| b x |
-x := 16rFF bitAnd: 16r0F. "and bits"
-x := 16rF0 bitOr: 16r0F. "or bits"
-x := 16rFF bitXor: 16r0F. "xor bits"
-x := 16rFF bitInvert. "invert bits"
-x := 16r0F bitShift: 4. "left shift"
-x := 16rF0 bitShift: -4. "right shift"
-"x := 16r80 bitAt: 7." "bit at position (0|1) [!Squeak]"
-x := 16r80 highbit. "position of highest bit set"
-b := 16rFF allMask: 16r0F. "test if all bits set in mask set in receiver"
-b := 16rFF anyMask: 16r0F. "test if any bits set in mask set in receiver"
-b := 16rFF noMask: 16r0F. "test if all bits set in mask clear in receiver"
+x := 16rFF bitAnd: 16r0F. "and bits"
+x := 16rF0 bitOr: 16r0F. "or bits"
+x := 16rFF bitXor: 16r0F. "xor bits"
+x := 16rFF bitInvert. "invert bits"
+x := 16r0F bitShift: 4. "left shift"
+x := 16rF0 bitShift: -4. "right shift"
+"x := 16r80 bitAt: 7." "bit at position (0|1) [!Squeak]"
+x := 16r80 highbit. "position of highest bit set"
+b := 16rFF allMask: 16r0F. "test if all bits set in mask set in receiver"
+b := 16rFF anyMask: 16r0F. "test if any bits set in mask set in receiver"
+b := 16rFF noMask: 16r0F. "test if all bits set in mask clear in receiver"
```
#### Conversion:
```
| x |
-x := 3.99 asInteger. "convert number to integer (truncates in Squeak)"
-x := 3.99 asFraction. "convert number to fraction"
-x := 3 asFloat. "convert number to float"
-x := 65 asCharacter. "convert integer to character"
-x := $A asciiValue. "convert character to integer"
-x := 3.99 printString. "convert object to string via printOn:"
-x := 3.99 storeString. "convert object to string via storeOn:"
-x := 15 radix: 16. "convert to string in given base"
+x := 3.99 asInteger. "convert number to integer (truncates in Squeak)"
+x := 3.99 asFraction. "convert number to fraction"
+x := 3 asFloat. "convert number to float"
+x := 65 asCharacter. "convert integer to character"
+x := $A asciiValue. "convert character to integer"
+x := 3.99 printString. "convert object to string via printOn:"
+x := 3.99 storeString. "convert object to string via storeOn:"
+x := 15 radix: 16. "convert to string in given base"
x := 15 printStringBase: 16.
x := 15 storeStringBase: 16.
```
@@ -284,6 +286,7 @@ x := 15 storeStringBase: 16.
x := [ y := 1. z := 2. ]. x value. "simple block usage"
x := [ :argOne :argTwo | argOne, ' and ' , argTwo.]. "set up block with argument passing"
Transcript show: (x value: 'First' value: 'Second'); cr. "use block with argument passing"
+
"x := [ | z | z := 1.]. *** localvars not available in squeak blocks"
```
@@ -303,27 +306,31 @@ Transcript show: (x value: 'First' value: 'Second'); cr. "use block with argu
```
| x |
-x := 2 sqrt. "unary message"
-x := 2 raisedTo: 10. "keyword message"
-x := 194 * 9. "binary message"
-Transcript show: (194 * 9) printString; cr. "combination (chaining)"
-x := 2 perform: #sqrt. "indirect method invocation"
-Transcript "Cascading - send multiple messages to receiver"
+x := 2 sqrt. "unary message"
+x := 2 raisedTo: 10. "keyword message"
+x := 194 * 9. "binary message"
+Transcript show: (194 * 9) printString; cr. "combination (chaining)"
+x := 2 perform: #sqrt. "indirect method invocation"
+Transcript "Cascading - send multiple messages to receiver"
show: 'hello ';
show: 'world';
cr.
-x := 3 + 2; * 100. "result=300. Sends message to same receiver (3)"
+x := 3 + 2; * 100. "result=300. Sends message to same receiver (3)"
```
#### Conditional Statements:
```
| x |
-x > 10 ifTrue: [Transcript show: 'ifTrue'; cr]. "if then"
-x > 10 ifFalse: [Transcript show: 'ifFalse'; cr]. "if else"
-x > 10 "if then else"
+x > 10 ifTrue: [Transcript show: 'ifTrue'; cr]. "if then"
+x > 10 ifFalse: [Transcript show: 'ifFalse'; cr]. "if else"
+
+"if then else"
+x > 10
ifTrue: [Transcript show: 'ifTrue'; cr]
ifFalse: [Transcript show: 'ifFalse'; cr].
-x > 10 "if else then"
+
+"if else then"
+x > 10
ifFalse: [Transcript show: 'ifFalse'; cr]
ifTrue: [Transcript show: 'ifTrue'; cr].
Transcript
@@ -332,7 +339,9 @@ Transcript
ifTrue: ['ifTrue']
ifFalse: ['ifFalse']);
cr.
-Transcript "nested if then else"
+
+"nested if then else"
+Transcript
show:
(x > 10
ifTrue: [x > 5
@@ -340,7 +349,9 @@ Transcript "nested if then else
ifFalse: ['B']]
ifFalse: ['C']);
cr.
-switch := Dictionary new. "switch functionality"
+
+"switch functionality"
+switch := Dictionary new.
switch at: $A put: [Transcript show: 'Case A'; cr].
switch at: $B put: [Transcript show: 'Case B'; cr].
switch at: $C put: [Transcript show: 'Case C'; cr].
@@ -351,129 +362,129 @@ result := (switch at: $B) value.
```
| x y |
x := 4. y := 1.
-[x > 0] whileTrue: [x := x - 1. y := y * 2]. "while true loop"
-[x >= 4] whileFalse: [x := x + 1. y := y * 2]. "while false loop"
-x timesRepeat: [y := y * 2]. "times repeat loop (i := 1 to x)"
-1 to: x do: [:a | y := y * 2]. "for loop"
-1 to: x by: 2 do: [:a | y := y / 2]. "for loop with specified increment"
-#(5 4 3) do: [:a | x := x + a]. "iterate over array elements"
+[x > 0] whileTrue: [x := x - 1. y := y * 2]. "while true loop"
+[x >= 4] whileFalse: [x := x + 1. y := y * 2]. "while false loop"
+x timesRepeat: [y := y * 2]. "times repeat loop (i := 1 to x)"
+1 to: x do: [:a | y := y * 2]. "for loop"
+1 to: x by: 2 do: [:a | y := y / 2]. "for loop with specified increment"
+#(5 4 3) do: [:a | x := x + a]. "iterate over array elements"
```
#### Character:
```
| x y |
-x := $A. "character assignment"
-y := x isLowercase. "test if lower case"
-y := x isUppercase. "test if upper case"
-y := x isLetter. "test if letter"
-y := x isDigit. "test if digit"
-y := x isAlphaNumeric. "test if alphanumeric"
-y := x isSeparator. "test if separator char"
-y := x isVowel. "test if vowel"
-y := x digitValue. "convert to numeric digit value"
-y := x asLowercase. "convert to lower case"
-y := x asUppercase. "convert to upper case"
-y := x asciiValue. "convert to numeric ascii value"
-y := x asString. "convert to string"
-b := $A <= $B. "comparison"
+x := $A. "character assignment"
+y := x isLowercase. "test if lower case"
+y := x isUppercase. "test if upper case"
+y := x isLetter. "test if letter"
+y := x isDigit. "test if digit"
+y := x isAlphaNumeric. "test if alphanumeric"
+y := x isSeparator. "test if separator char"
+y := x isVowel. "test if vowel"
+y := x digitValue. "convert to numeric digit value"
+y := x asLowercase. "convert to lower case"
+y := x asUppercase. "convert to upper case"
+y := x asciiValue. "convert to numeric ascii value"
+y := x asString. "convert to string"
+b := $A <= $B. "comparison"
y := $A max: $B.
```
#### Symbol:
```
| b x y |
-x := #Hello. "symbol assignment"
-y := 'String', 'Concatenation'. "symbol concatenation (result is string)"
-b := x isEmpty. "test if symbol is empty"
-y := x size. "string size"
-y := x at: 2. "char at location"
-y := x copyFrom: 2 to: 4. "substring"
-y := x indexOf: $e ifAbsent: [0]. "first position of character within string"
-x do: [:a | Transcript show: a printString; cr]. "iterate over the string"
-b := x conform: [:a | (a >= $a) & (a <= $z)]. "test if all elements meet condition"
-y := x select: [:a | a > $a]. "return all elements that meet condition"
-y := x asString. "convert symbol to string"
-y := x asText. "convert symbol to text"
-y := x asArray. "convert symbol to array"
-y := x asOrderedCollection. "convert symbol to ordered collection"
-y := x asSortedCollection. "convert symbol to sorted collection"
-y := x asBag. "convert symbol to bag collection"
-y := x asSet. "convert symbol to set collection"
+x := #Hello. "symbol assignment"
+y := 'String', 'Concatenation'. "symbol concatenation (result is string)"
+b := x isEmpty. "test if symbol is empty"
+y := x size. "string size"
+y := x at: 2. "char at location"
+y := x copyFrom: 2 to: 4. "substring"
+y := x indexOf: $e ifAbsent: [0]. "first position of character within string"
+x do: [:a | Transcript show: a printString; cr]. "iterate over the string"
+b := x conform: [:a | (a >= $a) & (a <= $z)]. "test if all elements meet condition"
+y := x select: [:a | a > $a]. "return all elements that meet condition"
+y := x asString. "convert symbol to string"
+y := x asText. "convert symbol to text"
+y := x asArray. "convert symbol to array"
+y := x asOrderedCollection. "convert symbol to ordered collection"
+y := x asSortedCollection. "convert symbol to sorted collection"
+y := x asBag. "convert symbol to bag collection"
+y := x asSet. "convert symbol to set collection"
```
#### String:
```
| b x y |
-x := 'This is a string'. "string assignment"
-x := 'String', 'Concatenation'. "string concatenation"
-b := x isEmpty. "test if string is empty"
-y := x size. "string size"
-y := x at: 2. "char at location"
-y := x copyFrom: 2 to: 4. "substring"
-y := x indexOf: $a ifAbsent: [0]. "first position of character within string"
-x := String new: 4. "allocate string object"
-x "set string elements"
+x := 'This is a string'. "string assignment"
+x := 'String', 'Concatenation'. "string concatenation"
+b := x isEmpty. "test if string is empty"
+y := x size. "string size"
+y := x at: 2. "char at location"
+y := x copyFrom: 2 to: 4. "substring"
+y := x indexOf: $a ifAbsent: [0]. "first position of character within string"
+x := String new: 4. "allocate string object"
+x "set string elements"
at: 1 put: $a;
at: 2 put: $b;
at: 3 put: $c;
at: 4 put: $e.
-x := String with: $a with: $b with: $c with: $d. "set up to 4 elements at a time"
-x do: [:a | Transcript show: a printString; cr]. "iterate over the string"
-b := x conform: [:a | (a >= $a) & (a <= $z)]. "test if all elements meet condition"
-y := x select: [:a | a > $a]. "return all elements that meet condition"
-y := x asSymbol. "convert string to symbol"
-y := x asArray. "convert string to array"
-x := 'ABCD' asByteArray. "convert string to byte array"
-y := x asOrderedCollection. "convert string to ordered collection"
-y := x asSortedCollection. "convert string to sorted collection"
-y := x asBag. "convert string to bag collection"
-y := x asSet. "convert string to set collection"
-y := x shuffled. "randomly shuffle string"
+x := String with: $a with: $b with: $c with: $d. "set up to 4 elements at a time"
+x do: [:a | Transcript show: a printString; cr]. "iterate over the string"
+b := x conform: [:a | (a >= $a) & (a <= $z)]. "test if all elements meet condition"
+y := x select: [:a | a > $a]. "return all elements that meet condition"
+y := x asSymbol. "convert string to symbol"
+y := x asArray. "convert string to array"
+x := 'ABCD' asByteArray. "convert string to byte array"
+y := x asOrderedCollection. "convert string to ordered collection"
+y := x asSortedCollection. "convert string to sorted collection"
+y := x asBag. "convert string to bag collection"
+y := x asSet. "convert string to set collection"
+y := x shuffled. "randomly shuffle string"
```
#### Array:
Fixed length collection
-
- ByteArray: Array limited to byte elements (0-255)
- WordArray: Array limited to word elements (0-2^32)
```
| b x y sum max |
-x := #(4 3 2 1). "constant array"
-x := Array with: 5 with: 4 with: 3 with: 2. "create array with up to 4 elements"
-x := Array new: 4. "allocate an array with specified size"
-x "set array elements"
+x := #(4 3 2 1). "constant array"
+x := Array with: 5 with: 4 with: 3 with: 2. "create array with up to 4 elements"
+x := Array new: 4. "allocate an array with specified size"
+x "set array elements"
at: 1 put: 5;
at: 2 put: 4;
at: 3 put: 3;
at: 4 put: 2.
-b := x isEmpty. "test if array is empty"
-y := x size. "array size"
-y := x at: 4. "get array element at index"
-b := x includes: 3. "test if element is in array"
-y := x copyFrom: 2 to: 4. "subarray"
-y := x indexOf: 3 ifAbsent: [0]. "first position of element within array"
-y := x occurrencesOf: 3. "number of times object in collection"
-x do: [:a | Transcript show: a printString; cr]. "iterate over the array"
-b := x conform: [:a | (a >= 1) & (a <= 4)]. "test if all elements meet condition"
-y := x select: [:a | a > 2]. "return collection of elements that pass test"
-y := x reject: [:a | a < 2]. "return collection of elements that fail test"
-y := x collect: [:a | a + a]. "transform each element for new collection"
-y := x detect: [:a | a > 3] ifNone: []. "find position of first element that passes test"
-sum := 0. x do: [:a | sum := sum + a]. sum. "sum array elements"
-sum := 0. 1 to: (x size) do: [:a | sum := sum + (x at: a)]. "sum array elements"
-sum := x inject: 0 into: [:a :c | a + c]. "sum array elements"
-max := x inject: 0 into: [:a :c | (a > c) "find max element in array"
+b := x isEmpty. "test if array is empty"
+y := x size. "array size"
+y := x at: 4. "get array element at index"
+b := x includes: 3. "test if element is in array"
+y := x copyFrom: 2 to: 4. "subarray"
+y := x indexOf: 3 ifAbsent: [0]. "first position of element within array"
+y := x occurrencesOf: 3. "number of times object in collection"
+x do: [:a | Transcript show: a printString; cr]. "iterate over the array"
+b := x conform: [:a | (a >= 1) & (a <= 4)]. "test if all elements meet condition"
+y := x select: [:a | a > 2]. "return collection of elements that pass test"
+y := x reject: [:a | a < 2]. "return collection of elements that fail test"
+y := x collect: [:a | a + a]. "transform each element for new collection"
+y := x detect: [:a | a > 3] ifNone: []. "find position of first element that passes test"
+sum := 0. x do: [:a | sum := sum + a]. sum. "sum array elements"
+sum := 0. 1 to: (x size)
+ do: [:a | sum := sum + (x at: a)]. "sum array elements"
+sum := x inject: 0 into: [:a :c | a + c]. "sum array elements"
+max := x inject: 0 into: [:a :c | (a > c) "find max element in array"
ifTrue: [a]
ifFalse: [c]].
-y := x shuffled. "randomly shuffle collection"
-y := x asArray. "convert to array"
-"y := x asByteArray." "note: this instruction not available on Squeak"
-y := x asWordArray. "convert to word array"
-y := x asOrderedCollection. "convert to ordered collection"
-y := x asSortedCollection. "convert to sorted collection"
-y := x asBag. "convert to bag collection"
-y := x asSet. "convert to set collection"
+y := x shuffled. "randomly shuffle collection"
+y := x asArray. "convert to array"
+"y := x asByteArray." "note: this instruction not available on Squeak"
+y := x asWordArray. "convert to word array"
+y := x asOrderedCollection. "convert to ordered collection"
+y := x asSortedCollection. "convert to sorted collection"
+y := x asBag. "convert to bag collection"
+y := x asSet. "convert to set collection"
```
#### OrderedCollection:
@@ -481,44 +492,46 @@ acts like an expandable array
```
| b x y sum max |
-x := OrderedCollection with: 4 with: 3 with: 2 with: 1. "create collection with up to 4 elements"
-x := OrderedCollection new. "allocate collection"
-x add: 3; add: 2; add: 1; add: 4; yourself. "add element to collection"
-y := x addFirst: 5. "add element at beginning of collection"
-y := x removeFirst. "remove first element in collection"
-y := x addLast: 6. "add element at end of collection"
-y := x removeLast. "remove last element in collection"
-y := x addAll: #(7 8 9). "add multiple elements to collection"
-y := x removeAll: #(7 8 9). "remove multiple elements from collection"
-x at: 2 put: 3. "set element at index"
-y := x remove: 5 ifAbsent: []. "remove element from collection"
-b := x isEmpty. "test if empty"
-y := x size. "number of elements"
-y := x at: 2. "retrieve element at index"
-y := x first. "retrieve first element in collection"
-y := x last. "retrieve last element in collection"
-b := x includes: 5. "test if element is in collection"
-y := x copyFrom: 2 to: 3. "subcollection"
-y := x indexOf: 3 ifAbsent: [0]. "first position of element within collection"
-y := x occurrencesOf: 3. "number of times object in collection"
-x do: [:a | Transcript show: a printString; cr]. "iterate over the collection"
-b := x conform: [:a | (a >= 1) & (a <= 4)]. "test if all elements meet condition"
-y := x select: [:a | a > 2]. "return collection of elements that pass test"
-y := x reject: [:a | a < 2]. "return collection of elements that fail test"
-y := x collect: [:a | a + a]. "transform each element for new collection"
-y := x detect: [:a | a > 3] ifNone: []. "find position of first element that passes test"
-sum := 0. x do: [:a | sum := sum + a]. sum. "sum elements"
-sum := 0. 1 to: (x size) do: [:a | sum := sum + (x at: a)]. "sum elements"
-sum := x inject: 0 into: [:a :c | a + c]. "sum elements"
-max := x inject: 0 into: [:a :c | (a > c) "find max element in collection"
+x := OrderedCollection
+ with: 4 with: 3 with: 2 with: 1. "create collection with up to 4 elements"
+x := OrderedCollection new. "allocate collection"
+x add: 3; add: 2; add: 1; add: 4; yourself. "add element to collection"
+y := x addFirst: 5. "add element at beginning of collection"
+y := x removeFirst. "remove first element in collection"
+y := x addLast: 6. "add element at end of collection"
+y := x removeLast. "remove last element in collection"
+y := x addAll: #(7 8 9). "add multiple elements to collection"
+y := x removeAll: #(7 8 9). "remove multiple elements from collection"
+x at: 2 put: 3. "set element at index"
+y := x remove: 5 ifAbsent: []. "remove element from collection"
+b := x isEmpty. "test if empty"
+y := x size. "number of elements"
+y := x at: 2. "retrieve element at index"
+y := x first. "retrieve first element in collection"
+y := x last. "retrieve last element in collection"
+b := x includes: 5. "test if element is in collection"
+y := x copyFrom: 2 to: 3. "subcollection"
+y := x indexOf: 3 ifAbsent: [0]. "first position of element within collection"
+y := x occurrencesOf: 3. "number of times object in collection"
+x do: [:a | Transcript show: a printString; cr]. "iterate over the collection"
+b := x conform: [:a | (a >= 1) & (a <= 4)]. "test if all elements meet condition"
+y := x select: [:a | a > 2]. "return collection of elements that pass test"
+y := x reject: [:a | a < 2]. "return collection of elements that fail test"
+y := x collect: [:a | a + a]. "transform each element for new collection"
+y := x detect: [:a | a > 3] ifNone: []. "find position of first element that passes test"
+sum := 0. x do: [:a | sum := sum + a]. sum. "sum elements"
+sum := 0. 1 to: (x size)
+ do: [:a | sum := sum + (x at: a)]. "sum elements"
+sum := x inject: 0 into: [:a :c | a + c]. "sum elements"
+max := x inject: 0 into: [:a :c | (a > c) "find max element in collection"
ifTrue: [a]
ifFalse: [c]].
-y := x shuffled. "randomly shuffle collection"
-y := x asArray. "convert to array"
-y := x asOrderedCollection. "convert to ordered collection"
-y := x asSortedCollection. "convert to sorted collection"
-y := x asBag. "convert to bag collection"
-y := x asSet. "convert to set collection"
+y := x shuffled. "randomly shuffle collection"
+y := x asArray. "convert to array"
+y := x asOrderedCollection. "convert to ordered collection"
+y := x asSortedCollection. "convert to sorted collection"
+y := x asBag. "convert to bag collection"
+y := x asSet. "convert to set collection"
```
#### SortedCollection:
@@ -526,43 +539,45 @@ like OrderedCollection except order of elements determined by sorting criteria
```
| b x y sum max |
-x := SortedCollection with: 4 with: 3 with: 2 with: 1. "create collection with up to 4 elements"
-x := SortedCollection new. "allocate collection"
-x := SortedCollection sortBlock: [:a :c | a > c]. "set sort criteria"
-x add: 3; add: 2; add: 1; add: 4; yourself. "add element to collection"
-y := x addFirst: 5. "add element at beginning of collection"
-y := x removeFirst. "remove first element in collection"
-y := x addLast: 6. "add element at end of collection"
-y := x removeLast. "remove last element in collection"
-y := x addAll: #(7 8 9). "add multiple elements to collection"
-y := x removeAll: #(7 8 9). "remove multiple elements from collection"
-y := x remove: 5 ifAbsent: []. "remove element from collection"
-b := x isEmpty. "test if empty"
-y := x size. "number of elements"
-y := x at: 2. "retrieve element at index"
-y := x first. "retrieve first element in collection"
-y := x last. "retrieve last element in collection"
-b := x includes: 4. "test if element is in collection"
-y := x copyFrom: 2 to: 3. "subcollection"
-y := x indexOf: 3 ifAbsent: [0]. "first position of element within collection"
-y := x occurrencesOf: 3. "number of times object in collection"
-x do: [:a | Transcript show: a printString; cr]. "iterate over the collection"
-b := x conform: [:a | (a >= 1) & (a <= 4)]. "test if all elements meet condition"
-y := x select: [:a | a > 2]. "return collection of elements that pass test"
-y := x reject: [:a | a < 2]. "return collection of elements that fail test"
-y := x collect: [:a | a + a]. "transform each element for new collection"
-y := x detect: [:a | a > 3] ifNone: []. "find position of first element that passes test"
-sum := 0. x do: [:a | sum := sum + a]. sum. "sum elements"
-sum := 0. 1 to: (x size) do: [:a | sum := sum + (x at: a)]. "sum elements"
-sum := x inject: 0 into: [:a :c | a + c]. "sum elements"
-max := x inject: 0 into: [:a :c | (a > c) "find max element in collection"
+x := SortedCollection
+ with: 4 with: 3 with: 2 with: 1. "create collection with up to 4 elements"
+x := SortedCollection new. "allocate collection"
+x := SortedCollection sortBlock: [:a :c | a > c]. "set sort criteria"
+x add: 3; add: 2; add: 1; add: 4; yourself. "add element to collection"
+y := x addFirst: 5. "add element at beginning of collection"
+y := x removeFirst. "remove first element in collection"
+y := x addLast: 6. "add element at end of collection"
+y := x removeLast. "remove last element in collection"
+y := x addAll: #(7 8 9). "add multiple elements to collection"
+y := x removeAll: #(7 8 9). "remove multiple elements from collection"
+y := x remove: 5 ifAbsent: []. "remove element from collection"
+b := x isEmpty. "test if empty"
+y := x size. "number of elements"
+y := x at: 2. "retrieve element at index"
+y := x first. "retrieve first element in collection"
+y := x last. "retrieve last element in collection"
+b := x includes: 4. "test if element is in collection"
+y := x copyFrom: 2 to: 3. "subcollection"
+y := x indexOf: 3 ifAbsent: [0]. "first position of element within collection"
+y := x occurrencesOf: 3. "number of times object in collection"
+x do: [:a | Transcript show: a printString; cr]. "iterate over the collection"
+b := x conform: [:a | (a >= 1) & (a <= 4)]. "test if all elements meet condition"
+y := x select: [:a | a > 2]. "return collection of elements that pass test"
+y := x reject: [:a | a < 2]. "return collection of elements that fail test"
+y := x collect: [:a | a + a]. "transform each element for new collection"
+y := x detect: [:a | a > 3] ifNone: []. "find position of first element that passes test"
+sum := 0. x do: [:a | sum := sum + a]. sum. "sum elements"
+sum := 0. 1 to: (x size)
+ do: [:a | sum := sum + (x at: a)]. "sum elements"
+sum := x inject: 0 into: [:a :c | a + c]. "sum elements"
+max := x inject: 0 into: [:a :c | (a > c) "find max element in collection"
ifTrue: [a]
ifFalse: [c]].
-y := x asArray. "convert to array"
-y := x asOrderedCollection. "convert to ordered collection"
-y := x asSortedCollection. "convert to sorted collection"
-y := x asBag. "convert to bag collection"
-y := x asSet. "convert to set collection"
+y := x asArray. "convert to array"
+y := x asOrderedCollection. "convert to ordered collection"
+y := x asSortedCollection. "convert to sorted collection"
+y := x asBag. "convert to bag collection"
+y := x asSet. "convert to set collection"
```
#### Bag:
@@ -570,32 +585,32 @@ like OrderedCollection except elements are in no particular order
```
| b x y sum max |
-x := Bag with: 4 with: 3 with: 2 with: 1. "create collection with up to 4 elements"
-x := Bag new. "allocate collection"
-x add: 4; add: 3; add: 1; add: 2; yourself. "add element to collection"
-x add: 3 withOccurrences: 2. "add multiple copies to collection"
-y := x addAll: #(7 8 9). "add multiple elements to collection"
-y := x removeAll: #(7 8 9). "remove multiple elements from collection"
-y := x remove: 4 ifAbsent: []. "remove element from collection"
-b := x isEmpty. "test if empty"
-y := x size. "number of elements"
-b := x includes: 3. "test if element is in collection"
-y := x occurrencesOf: 3. "number of times object in collection"
-x do: [:a | Transcript show: a printString; cr]. "iterate over the collection"
-b := x conform: [:a | (a >= 1) & (a <= 4)]. "test if all elements meet condition"
-y := x select: [:a | a > 2]. "return collection of elements that pass test"
-y := x reject: [:a | a < 2]. "return collection of elements that fail test"
-y := x collect: [:a | a + a]. "transform each element for new collection"
-y := x detect: [:a | a > 3] ifNone: []. "find position of first element that passes test"
-sum := 0. x do: [:a | sum := sum + a]. sum. "sum elements"
-sum := x inject: 0 into: [:a :c | a + c]. "sum elements"
-max := x inject: 0 into: [:a :c | (a > c) "find max element in collection"
+x := Bag with: 4 with: 3 with: 2 with: 1. "create collection with up to 4 elements"
+x := Bag new. "allocate collection"
+x add: 4; add: 3; add: 1; add: 2; yourself. "add element to collection"
+x add: 3 withOccurrences: 2. "add multiple copies to collection"
+y := x addAll: #(7 8 9). "add multiple elements to collection"
+y := x removeAll: #(7 8 9). "remove multiple elements from collection"
+y := x remove: 4 ifAbsent: []. "remove element from collection"
+b := x isEmpty. "test if empty"
+y := x size. "number of elements"
+b := x includes: 3. "test if element is in collection"
+y := x occurrencesOf: 3. "number of times object in collection"
+x do: [:a | Transcript show: a printString; cr]. "iterate over the collection"
+b := x conform: [:a | (a >= 1) & (a <= 4)]. "test if all elements meet condition"
+y := x select: [:a | a > 2]. "return collection of elements that pass test"
+y := x reject: [:a | a < 2]. "return collection of elements that fail test"
+y := x collect: [:a | a + a]. "transform each element for new collection"
+y := x detect: [:a | a > 3] ifNone: []. "find position of first element that passes test"
+sum := 0. x do: [:a | sum := sum + a]. sum. "sum elements"
+sum := x inject: 0 into: [:a :c | a + c]. "sum elements"
+max := x inject: 0 into: [:a :c | (a > c) "find max element in collection"
ifTrue: [a]
ifFalse: [c]].
-y := x asOrderedCollection. "convert to ordered collection"
-y := x asSortedCollection. "convert to sorted collection"
-y := x asBag. "convert to bag collection"
-y := x asSet. "convert to set collection"
+y := x asOrderedCollection. "convert to ordered collection"
+y := x asSortedCollection. "convert to sorted collection"
+y := x asBag. "convert to bag collection"
+y := x asSet. "convert to set collection"
```
#### Set:
@@ -606,60 +621,61 @@ uses identity test (== rather than =)
```
| b x y sum max |
-x := Set with: 4 with: 3 with: 2 with: 1. "create collection with up to 4 elements"
-x := Set new. "allocate collection"
-x add: 4; add: 3; add: 1; add: 2; yourself. "add element to collection"
-y := x addAll: #(7 8 9). "add multiple elements to collection"
-y := x removeAll: #(7 8 9). "remove multiple elements from collection"
-y := x remove: 4 ifAbsent: []. "remove element from collection"
-b := x isEmpty. "test if empty"
-y := x size. "number of elements"
-x includes: 4. "test if element is in collection"
-x do: [:a | Transcript show: a printString; cr]. "iterate over the collection"
-b := x conform: [:a | (a >= 1) & (a <= 4)]. "test if all elements meet condition"
-y := x select: [:a | a > 2]. "return collection of elements that pass test"
-y := x reject: [:a | a < 2]. "return collection of elements that fail test"
-y := x collect: [:a | a + a]. "transform each element for new collection"
-y := x detect: [:a | a > 3] ifNone: []. "find position of first element that passes test"
-sum := 0. x do: [:a | sum := sum + a]. sum. "sum elements"
-sum := x inject: 0 into: [:a :c | a + c]. "sum elements"
-max := x inject: 0 into: [:a :c | (a > c) "find max element in collection"
+x := Set with: 4 with: 3 with: 2 with: 1. "create collection with up to 4 elements"
+x := Set new. "allocate collection"
+x add: 4; add: 3; add: 1; add: 2; yourself. "add element to collection"
+y := x addAll: #(7 8 9). "add multiple elements to collection"
+y := x removeAll: #(7 8 9). "remove multiple elements from collection"
+y := x remove: 4 ifAbsent: []. "remove element from collection"
+b := x isEmpty. "test if empty"
+y := x size. "number of elements"
+x includes: 4. "test if element is in collection"
+x do: [:a | Transcript show: a printString; cr]. "iterate over the collection"
+b := x conform: [:a | (a >= 1) & (a <= 4)]. "test if all elements meet condition"
+y := x select: [:a | a > 2]. "return collection of elements that pass test"
+y := x reject: [:a | a < 2]. "return collection of elements that fail test"
+y := x collect: [:a | a + a]. "transform each element for new collection"
+y := x detect: [:a | a > 3] ifNone: []. "find position of first element that passes test"
+sum := 0. x do: [:a | sum := sum + a]. sum. "sum elements"
+sum := x inject: 0 into: [:a :c | a + c]. "sum elements"
+max := x inject: 0 into: [:a :c | (a > c) "find max element in collection"
ifTrue: [a]
ifFalse: [c]].
-y := x asArray. "convert to array"
-y := x asOrderedCollection. "convert to ordered collection"
-y := x asSortedCollection. "convert to sorted collection"
-y := x asBag. "convert to bag collection"
-y := x asSet. "convert to set collection"
+y := x asArray. "convert to array"
+y := x asOrderedCollection. "convert to ordered collection"
+y := x asSortedCollection. "convert to sorted collection"
+y := x asBag. "convert to bag collection"
+y := x asSet. "convert to set collection"
```
#### Interval:
```
| b x y sum max |
-x := Interval from: 5 to: 10. "create interval object"
+x := Interval from: 5 to: 10. "create interval object"
x := 5 to: 10.
-x := Interval from: 5 to: 10 by: 2. "create interval object with specified increment"
+x := Interval from: 5 to: 10 by: 2. "create interval object with specified increment"
x := 5 to: 10 by: 2.
-b := x isEmpty. "test if empty"
-y := x size. "number of elements"
-x includes: 9. "test if element is in collection"
-x do: [:k | Transcript show: k printString; cr]. "iterate over interval"
-b := x conform: [:a | (a >= 1) & (a <= 4)]. "test if all elements meet condition"
-y := x select: [:a | a > 7]. "return collection of elements that pass test"
-y := x reject: [:a | a < 2]. "return collection of elements that fail test"
-y := x collect: [:a | a + a]. "transform each element for new collection"
-y := x detect: [:a | a > 3] ifNone: []. "find position of first element that passes test"
-sum := 0. x do: [:a | sum := sum + a]. sum. "sum elements"
-sum := 0. 1 to: (x size) do: [:a | sum := sum + (x at: a)]. "sum elements"
-sum := x inject: 0 into: [:a :c | a + c]. "sum elements"
-max := x inject: 0 into: [:a :c | (a > c) "find max element in collection"
+b := x isEmpty. "test if empty"
+y := x size. "number of elements"
+x includes: 9. "test if element is in collection"
+x do: [:k | Transcript show: k printString; cr]. "iterate over interval"
+b := x conform: [:a | (a >= 1) & (a <= 4)]. "test if all elements meet condition"
+y := x select: [:a | a > 7]. "return collection of elements that pass test"
+y := x reject: [:a | a < 2]. "return collection of elements that fail test"
+y := x collect: [:a | a + a]. "transform each element for new collection"
+y := x detect: [:a | a > 3] ifNone: []. "find position of first element that passes test"
+sum := 0. x do: [:a | sum := sum + a]. sum. "sum elements"
+sum := 0. 1 to: (x size)
+ do: [:a | sum := sum + (x at: a)]. "sum elements"
+sum := x inject: 0 into: [:a :c | a + c]. "sum elements"
+max := x inject: 0 into: [:a :c | (a > c) "find max element in collection"
ifTrue: [a]
ifFalse: [c]].
-y := x asArray. "convert to array"
-y := x asOrderedCollection. "convert to ordered collection"
-y := x asSortedCollection. "convert to sorted collection"
-y := x asBag. "convert to bag collection"
-y := x asSet. "convert to set collection"
+y := x asArray. "convert to array"
+y := x asOrderedCollection. "convert to ordered collection"
+y := x asSortedCollection. "convert to sorted collection"
+y := x asBag. "convert to bag collection"
+y := x asSet. "convert to set collection"
```
#### Associations:
@@ -676,65 +692,68 @@ uses identity test (== rather than =)
```
| b x y |
-x := Dictionary new. "allocate collection"
-x add: #a->4; add: #b->3; add: #c->1; add: #d->2; yourself. "add element to collection"
-x at: #e put: 3. "set element at index"
-b := x isEmpty. "test if empty"
-y := x size. "number of elements"
-y := x at: #a ifAbsent: []. "retrieve element at index"
-y := x keyAtValue: 3 ifAbsent: []. "retrieve key for given value with error block"
-y := x removeKey: #e ifAbsent: []. "remove element from collection"
-b := x includes: 3. "test if element is in values collection"
-b := x includesKey: #a. "test if element is in keys collection"
-y := x occurrencesOf: 3. "number of times object in collection"
-y := x keys. "set of keys"
-y := x values. "bag of values"
+x := Dictionary new. "allocate collection"
+x add: #a->4;
+ add: #b->3;
+ add: #c->1;
+ add: #d->2; yourself. "add element to collection"
+x at: #e put: 3. "set element at index"
+b := x isEmpty. "test if empty"
+y := x size. "number of elements"
+y := x at: #a ifAbsent: []. "retrieve element at index"
+y := x keyAtValue: 3 ifAbsent: []. "retrieve key for given value with error block"
+y := x removeKey: #e ifAbsent: []. "remove element from collection"
+b := x includes: 3. "test if element is in values collection"
+b := x includesKey: #a. "test if element is in keys collection"
+y := x occurrencesOf: 3. "number of times object in collection"
+y := x keys. "set of keys"
+y := x values. "bag of values"
x do: [:a | Transcript show: a printString; cr]. "iterate over the values collection"
x keysDo: [:a | Transcript show: a printString; cr]. "iterate over the keys collection"
x associationsDo: [:a | Transcript show: a printString; cr]."iterate over the associations"
x keysAndValuesDo: [:aKey :aValue | Transcript "iterate over keys and values"
show: aKey printString; space;
show: aValue printString; cr].
-b := x conform: [:a | (a >= 1) & (a <= 4)]. "test if all elements meet condition"
-y := x select: [:a | a > 2]. "return collection of elements that pass test"
-y := x reject: [:a | a < 2]. "return collection of elements that fail test"
-y := x collect: [:a | a + a]. "transform each element for new collection"
-y := x detect: [:a | a > 3] ifNone: []. "find position of first element that passes test"
-sum := 0. x do: [:a | sum := sum + a]. sum. "sum elements"
-sum := x inject: 0 into: [:a :c | a + c]. "sum elements"
-max := x inject: 0 into: [:a :c | (a > c) "find max element in collection"
+b := x conform: [:a | (a >= 1) & (a <= 4)]. "test if all elements meet condition"
+y := x select: [:a | a > 2]. "return collection of elements that pass test"
+y := x reject: [:a | a < 2]. "return collection of elements that fail test"
+y := x collect: [:a | a + a]. "transform each element for new collection"
+y := x detect: [:a | a > 3] ifNone: []. "find position of first element that passes test"
+sum := 0. x do: [:a | sum := sum + a]. sum. "sum elements"
+sum := x inject: 0 into: [:a :c | a + c]. "sum elements"
+max := x inject: 0 into: [:a :c | (a > c) "find max element in collection"
ifTrue: [a]
ifFalse: [c]].
-y := x asArray. "convert to array"
-y := x asOrderedCollection. "convert to ordered collection"
-y := x asSortedCollection. "convert to sorted collection"
-y := x asBag. "convert to bag collection"
-y := x asSet. "convert to set collection"
-
-Smalltalk at: #CMRGlobal put: 'CMR entry'. "put global in Smalltalk Dictionary"
-x := Smalltalk at: #CMRGlobal. "read global from Smalltalk Dictionary"
-Transcript show: (CMRGlobal printString). "entries are directly accessible by name"
-Smalltalk keys do: [ :k | "print out all classes"
+y := x asArray. "convert to array"
+y := x asOrderedCollection. "convert to ordered collection"
+y := x asSortedCollection. "convert to sorted collection"
+y := x asBag. "convert to bag collection"
+y := x asSet. "convert to set collection"
+
+Smalltalk at: #CMRGlobal put: 'CMR entry'. "put global in Smalltalk Dictionary"
+x := Smalltalk at: #CMRGlobal. "read global from Smalltalk Dictionary"
+Transcript show: (CMRGlobal printString). "entries are directly accessible by name"
+Smalltalk keys do: [ :k | "print out all classes"
((Smalltalk at: k) isKindOf: Class)
ifFalse: [Transcript show: k printString; cr]].
-Smalltalk at: #CMRDictionary put: (Dictionary new). "set up user defined dictionary"
-CMRDictionary at: #MyVar1 put: 'hello1'. "put entry in dictionary"
-CMRDictionary add: #MyVar2->'hello2'. "add entry to dictionary use key->value combo"
-CMRDictionary size. "dictionary size"
-CMRDictionary keys do: [ :k | "print out keys in dictionary"
+Smalltalk at: #CMRDictionary put: (Dictionary new). "set up user defined dictionary"
+CMRDictionary at: #MyVar1 put: 'hello1'. "put entry in dictionary"
+CMRDictionary add: #MyVar2->'hello2'. "add entry to dictionary use key->value combo"
+CMRDictionary size. "dictionary size"
+CMRDictionary keys do: [ :k | "print out keys in dictionary"
Transcript show: k printString; cr].
-CMRDictionary values do: [ :k | "print out values in dictionary"
+CMRDictionary values do: [ :k | "print out values in dictionary"
Transcript show: k printString; cr].
-CMRDictionary keysAndValuesDo: [:aKey :aValue | "print out keys and values"
+CMRDictionary keysAndValuesDo: [:aKey :aValue | "print out keys and values"
Transcript
show: aKey printString;
space;
show: aValue printString;
cr].
-CMRDictionary associationsDo: [:aKeyValue | "another iterator for printing key values"
+CMRDictionary associationsDo: [:aKeyValue | "another iterator for printing key values"
Transcript show: aKeyValue printString; cr].
-Smalltalk removeKey: #CMRGlobal ifAbsent: []. "remove entry from Smalltalk dictionary"
-Smalltalk removeKey: #CMRDictionary ifAbsent: []. "remove user dictionary from Smalltalk dictionary"
+Smalltalk removeKey: #CMRGlobal ifAbsent: []. "remove entry from Smalltalk dictionary"
+Smalltalk removeKey: #CMRDictionary ifAbsent: []. "remove user dictionary from Smalltalk dictionary"
```
#### Internal Stream:
@@ -742,8 +761,7 @@ Smalltalk removeKey: #CMRDictionary ifAbsent: []. "remove user diction
| b x ios |
ios := ReadStream on: 'Hello read stream'.
ios := ReadStream on: 'Hello read stream' from: 1 to: 5.
-[(x := ios nextLine) notNil]
- whileTrue: [Transcript show: x; cr].
+[(x := ios nextLine) notNil] whileTrue: [Transcript show: x; cr].
ios position: 3.
ios position.
x := ios next.
@@ -756,8 +774,7 @@ ios := ReadWriteStream on: 'Hello read stream' from: 1 to: 5.
ios := ReadWriteStream with: 'Hello read stream'.
ios := ReadWriteStream with: 'Hello read stream' from: 1 to: 10.
ios position: 0.
-[(x := ios nextLine) notNil]
- whileTrue: [Transcript show: x; cr].
+[(x := ios nextLine) notNil] whileTrue: [Transcript show: x; cr].
ios position: 6.
ios position.
ios nextPutAll: 'Chris'.
@@ -778,8 +795,7 @@ ios nextPutAll: 'Hello File'; cr.
ios close.
ios := FileStream oldFileNamed: 'ios.txt'.
-[(x := ios nextLine) notNil]
- whileTrue: [Transcript show: x; cr].
+[(x := ios nextLine) notNil] whileTrue: [Transcript show: x; cr].
ios position: 3.
x := ios position.
x := ios next.
@@ -791,80 +807,80 @@ ios close.
#### Date:
```
| x y |
-x := Date today. "create date for today"
-x := Date dateAndTimeNow. "create date from current time/date"
-x := Date readFromString: '01/02/1999'. "create date from formatted string"
-x := Date newDay: 12 month: #July year: 1999 "create date from parts"
-x := Date fromDays: 36000. "create date from elapsed days since 1/1/1901"
-y := Date dayOfWeek: #Monday. "day of week as int (1-7)"
-y := Date indexOfMonth: #January. "month of year as int (1-12)"
-y := Date daysInMonth: 2 forYear: 1996. "day of month as int (1-31)"
-y := Date daysInYear: 1996. "days in year (365|366)"
-y := Date nameOfDay: 1 "weekday name (#Monday,...)"
-y := Date nameOfMonth: 1. "month name (#January,...)"
-y := Date leapYear: 1996. "1 if leap year; 0 if not leap year"
-y := x weekday. "day of week (#Monday,...)"
-y := x previous: #Monday. "date for previous day of week"
-y := x dayOfMonth. "day of month (1-31)"
-y := x day. "day of year (1-366)"
-y := x firstDayOfMonth. "day of year for first day of month"
-y := x monthName. "month of year (#January,...)"
-y := x monthIndex. "month of year (1-12)"
-y := x daysInMonth. "days in month (1-31)"
-y := x year. "year (19xx)"
-y := x daysInYear. "days in year (365|366)"
-y := x daysLeftInYear. "days left in year (364|365)"
-y := x asSeconds. "seconds elapsed since 1/1/1901"
-y := x addDays: 10. "add days to date object"
-y := x subtractDays: 10. "subtract days to date object"
-y := x subtractDate: (Date today). "subtract date (result in days)"
-y := x printFormat: #(2 1 3 $/ 1 1). "print formatted date"
-b := (x <= Date today). "comparison"
+x := Date today. "create date for today"
+x := Date dateAndTimeNow. "create date from current time/date"
+x := Date readFromString: '01/02/1999'. "create date from formatted string"
+x := Date newDay: 12 month: #July year: 1999 "create date from parts"
+x := Date fromDays: 36000. "create date from elapsed days since 1/1/1901"
+y := Date dayOfWeek: #Monday. "day of week as int (1-7)"
+y := Date indexOfMonth: #January. "month of year as int (1-12)"
+y := Date daysInMonth: 2 forYear: 1996. "day of month as int (1-31)"
+y := Date daysInYear: 1996. "days in year (365|366)"
+y := Date nameOfDay: 1 "weekday name (#Monday,...)"
+y := Date nameOfMonth: 1. "month name (#January,...)"
+y := Date leapYear: 1996. "1 if leap year; 0 if not leap year"
+y := x weekday. "day of week (#Monday,...)"
+y := x previous: #Monday. "date for previous day of week"
+y := x dayOfMonth. "day of month (1-31)"
+y := x day. "day of year (1-366)"
+y := x firstDayOfMonth. "day of year for first day of month"
+y := x monthName. "month of year (#January,...)"
+y := x monthIndex. "month of year (1-12)"
+y := x daysInMonth. "days in month (1-31)"
+y := x year. "year (19xx)"
+y := x daysInYear. "days in year (365|366)"
+y := x daysLeftInYear. "days left in year (364|365)"
+y := x asSeconds. "seconds elapsed since 1/1/1901"
+y := x addDays: 10. "add days to date object"
+y := x subtractDays: 10. "subtract days to date object"
+y := x subtractDate: (Date today). "subtract date (result in days)"
+y := x printFormat: #(2 1 3 $/ 1 1). "print formatted date"
+b := (x <= Date today). "comparison"
```
#### Time:
```
| x y |
-x := Time now. "create time from current time"
-x := Time dateAndTimeNow. "create time from current time/date"
-x := Time readFromString: '3:47:26 pm'. "create time from formatted string"
-x := Time fromSeconds: (60 * 60 * 4). "create time from elapsed time from midnight"
-y := Time millisecondClockValue. "milliseconds since midnight"
-y := Time totalSeconds. "total seconds since 1/1/1901"
-y := x seconds. "seconds past minute (0-59)"
-y := x minutes. "minutes past hour (0-59)"
-y := x hours. "hours past midnight (0-23)"
-y := x addTime: (Time now). "add time to time object"
-y := x subtractTime: (Time now). "subtract time to time object"
-y := x asSeconds. "convert time to seconds"
-x := Time millisecondsToRun: [ "timing facility"
+x := Time now. "create time from current time"
+x := Time dateAndTimeNow. "create time from current time/date"
+x := Time readFromString: '3:47:26 pm'. "create time from formatted string"
+x := Time fromSeconds: (60 * 60 * 4). "create time from elapsed time from midnight"
+y := Time millisecondClockValue. "milliseconds since midnight"
+y := Time totalSeconds. "total seconds since 1/1/1901"
+y := x seconds. "seconds past minute (0-59)"
+y := x minutes. "minutes past hour (0-59)"
+y := x hours. "hours past midnight (0-23)"
+y := x addTime: (Time now). "add time to time object"
+y := x subtractTime: (Time now). "subtract time to time object"
+y := x asSeconds. "convert time to seconds"
+x := Time millisecondsToRun: [ "timing facility"
1 to: 1000 do: [:index | y := 3.14 * index]].
-b := (x <= Time now). "comparison"
+b := (x <= Time now). "comparison"
```
#### Point:
```
| x y |
-x := 200@100. "obtain a new point"
-y := x x. "x coordinate"
-y := x y. "y coordinate"
-x := 200@100 negated. "negates x and y"
-x := (-200@-100) abs. "absolute value of x and y"
-x := (200.5@100.5) rounded. "round x and y"
-x := (200.5@100.5) truncated. "truncate x and y"
-x := 200@100 + 100. "add scale to both x and y"
-x := 200@100 - 100. "subtract scale from both x and y"
-x := 200@100 * 2. "multiply x and y by scale"
-x := 200@100 / 2. "divide x and y by scale"
-x := 200@100 // 2. "divide x and y by scale"
-x := 200@100 \\ 3. "remainder of x and y by scale"
-x := 200@100 + 50@25. "add points"
-x := 200@100 - 50@25. "subtract points"
-x := 200@100 * 3@4. "multiply points"
-x := 200@100 // 3@4. "divide points"
-x := 200@100 max: 50@200. "max x and y"
-x := 200@100 min: 50@200. "min x and y"
-x := 20@5 dotProduct: 10@2. "sum of product (x1*x2 + y1*y2)"
+x := 200@100. "obtain a new point"
+y := x x. "x coordinate"
+y := x y. "y coordinate"
+x := 200@100 negated. "negates x and y"
+x := (-200@-100) abs. "absolute value of x and y"
+x := (200.5@100.5) rounded. "round x and y"
+x := (200.5@100.5) truncated. "truncate x and y"
+x := 200@100 + 100. "add scale to both x and y"
+x := 200@100 - 100. "subtract scale from both x and y"
+x := 200@100 * 2. "multiply x and y by scale"
+x := 200@100 / 2. "divide x and y by scale"
+x := 200@100 // 2. "divide x and y by scale"
+x := 200@100 \\ 3. "remainder of x and y by scale"
+x := 200@100 + 50@25. "add points"
+x := 200@100 - 50@25. "subtract points"
+x := 200@100 * 3@4. "multiply points"
+x := 200@100 // 3@4. "divide points"
+x := 200@100 max: 50@200. "max x and y"
+x := 200@100 min: 50@200. "min x and y"
+x := 20@5 dotProduct: 10@2. "sum of product (x1*x2 + y1*y2)"
```
#### Rectangle:
@@ -878,23 +894,24 @@ Rectangle fromUser.
Display restoreAfter: [
Display fillWhite.
-myPen := Pen new. "get graphic pen"
+myPen := Pen new. "get graphic pen"
myPen squareNib: 1.
-myPen color: (Color blue). "set pen color"
-myPen home. "position pen at center of display"
-myPen up. "makes nib unable to draw"
-myPen down. "enable the nib to draw"
-myPen north. "points direction towards top"
-myPen turn: -180. "add specified degrees to direction"
-myPen direction. "get current angle of pen"
-myPen go: 50. "move pen specified number of pixels"
-myPen location. "get the pen position"
-myPen goto: 200@200. "move to specified point"
-myPen place: 250@250. "move to specified point without drawing"
-myPen print: 'Hello World' withFont: (TextStyle default fontAt: 1).
-Display extent. "get display width@height"
-Display width. "get display width"
-Display height. "get display height"
+myPen color: (Color blue). "set pen color"
+myPen home. "position pen at center of display"
+myPen up. "makes nib unable to draw"
+myPen down. "enable the nib to draw"
+myPen north. "points direction towards top"
+myPen turn: -180. "add specified degrees to direction"
+myPen direction. "get current angle of pen"
+myPen go: 50. "move pen specified number of pixels"
+myPen location. "get the pen position"
+myPen goto: 200@200. "move to specified point"
+myPen place: 250@250. "move to specified point without drawing"
+myPen print: 'Hello World'
+ withFont: (TextStyle default fontAt: 1).
+Display extent. "get display width@height"
+Display width. "get display width"
+Display height. "get display height"
].
```
@@ -902,6 +919,7 @@ Display height. "get display height"
#### Dynamic Message Calling/Compiling:
```
| receiver message result argument keyword1 keyword2 argument1 argument2 |
+
"unary message"
receiver := 5.
message := 'factorial' asSymbol.
@@ -923,11 +941,14 @@ keyword1 := 'between:' asSymbol.
keyword2 := 'and:' asSymbol.
argument1 := 10.
argument2 := 20.
+
result := receiver
perform: (keyword1, keyword2) asSymbol
withArguments: (Array with: argument1 with: argument2).
+
result := Compiler evaluate:
((receiver storeString), ' ', keyword1, (argument1 storeString) , ' ', keyword2, (argument2 storeString)).
+
result := (Message
new
setSelector: (keyword1, keyword2) asSymbol
@@ -935,67 +956,67 @@ result := (Message
sentTo: receiver.
```
-#### Class/Meta-class:
+#### Class/Meta-Class:
```
| b x |
-x := String name. "class name"
-x := String category. "organization category"
-x := String comment. "class comment"
-x := String kindOfSubclass. "subclass type - subclass: variableSubclass, etc"
-x := String definition. "class definition"
-x := String instVarNames. "immediate instance variable names"
-x := String allInstVarNames. "accumulated instance variable names"
-x := String classVarNames. "immediate class variable names"
-x := String allClassVarNames. "accumulated class variable names"
-x := String sharedPools. "immediate dictionaries used as shared pools"
-x := String allSharedPools. "accumulated dictionaries used as shared pools"
-x := String selectors. "message selectors for class"
-x := String sourceCodeAt: #size. "source code for specified method"
-x := String allInstances. "collection of all instances of class"
-x := String superclass. "immediate superclass"
-x := String allSuperclasses. "accumulated superclasses"
-x := String withAllSuperclasses. "receiver class and accumulated superclasses"
-x := String subclasses. "immediate subclasses"
-x := String allSubclasses. "accumulated subclasses"
-x := String withAllSubclasses. "receiver class and accumulated subclasses"
-b := String instSize. "number of named instance variables"
-b := String isFixed. "true if no indexed instance variables"
-b := String isVariable. "true if has indexed instance variables"
-b := String isPointers. "true if index instance vars contain objects"
-b := String isBits. "true if index instance vars contain bytes/words"
-b := String isBytes. "true if index instance vars contain bytes"
-b := String isWords. "true if index instance vars contain words"
-Object withAllSubclasses size. "get total number of class entries"
+x := String name. "class name"
+x := String category. "organization category"
+x := String comment. "class comment"
+x := String kindOfSubclass. "subclass type - subclass: variableSubclass, etc"
+x := String definition. "class definition"
+x := String instVarNames. "immediate instance variable names"
+x := String allInstVarNames. "accumulated instance variable names"
+x := String classVarNames. "immediate class variable names"
+x := String allClassVarNames. "accumulated class variable names"
+x := String sharedPools. "immediate dictionaries used as shared pools"
+x := String allSharedPools. "accumulated dictionaries used as shared pools"
+x := String selectors. "message selectors for class"
+x := String sourceCodeAt: #size. "source code for specified method"
+x := String allInstances. "collection of all instances of class"
+x := String superclass. "immediate superclass"
+x := String allSuperclasses. "accumulated superclasses"
+x := String withAllSuperclasses. "receiver class and accumulated superclasses"
+x := String subclasses. "immediate subclasses"
+x := String allSubclasses. "accumulated subclasses"
+x := String withAllSubclasses. "receiver class and accumulated subclasses"
+b := String instSize. "number of named instance variables"
+b := String isFixed. "true if no indexed instance variables"
+b := String isVariable. "true if has indexed instance variables"
+b := String isPointers. "true if index instance vars contain objects"
+b := String isBits. "true if index instance vars contain bytes/words"
+b := String isBytes. "true if index instance vars contain bytes"
+b := String isWords. "true if index instance vars contain words"
+Object withAllSubclasses size. "get total number of class entries"
```
#### Debugging:
```
| a b x |
-x yourself. "returns receiver"
-String browse. "browse specified class"
-x inspect. "open object inspector window"
+x yourself. "returns receiver"
+String browse. "browse specified class"
+x inspect. "open object inspector window"
x confirm: 'Is this correct?'.
-x halt. "breakpoint to open debugger window"
+x halt. "breakpoint to open debugger window"
x halt: 'Halt message'.
x notify: 'Notify text'.
-x error: 'Error string'. "open up error window with title"
-x doesNotUnderstand: #cmrMessage. "flag message is not handled"
-x shouldNotImplement. "flag message should not be implemented"
-x subclassResponsibility. "flag message as abstract"
-x errorImproperStore. "flag an improper store into indexable object"
-x errorNonIntegerIndex. "flag only integers should be used as index"
-x errorSubscriptBounds. "flag subscript out of bounds"
-x primitiveFailed. "system primitive failed"
-
-a := 'A1'. b := 'B2'. a become: b. "switch two objects"
+x error: 'Error string'. "open up error window with title"
+x doesNotUnderstand: #cmrMessage. "flag message is not handled"
+x shouldNotImplement. "flag message should not be implemented"
+x subclassResponsibility. "flag message as abstract"
+x errorImproperStore. "flag an improper store into indexable object"
+x errorNonIntegerIndex. "flag only integers should be used as index"
+x errorSubscriptBounds. "flag subscript out of bounds"
+x primitiveFailed. "system primitive failed"
+
+a := 'A1'. b := 'B2'. a become: b. "switch two objects"
Transcript show: a, b; cr.
```
-#### Misc
+#### Miscellaneous
```
| x |
-"Smalltalk condenseChanges." "compress the change file"
-x := FillInTheBlank request: 'Prompt Me'. "prompt user for input"
+"Smalltalk condenseChanges." "compress the change file"
+x := FillInTheBlank request: 'Prompt Me'. "prompt user for input"
Utilities openCommandKeyHelp
```
@@ -1016,7 +1037,7 @@ Most Smalltalks are either free as in OSS or have a free downloadable version wi
* [Smalltalk-72 Manual](http://www.bitsavers.org/pdf/xerox/parc/techReports/Smalltalk-72_Instruction_Manual_Mar76.pdf)
* [GNU Smalltalk User's Guide](https://www.gnu.org/software/smalltalk/manual/html_node/Tutorial.html)
-#### Historical doc
+#### Historical Documentation(s)
* [BYTE: A Special issue on Smalltalk](https://archive.org/details/byte-magazine-1981-08)
* [Smalltalk-72 Manual](http://www.bitsavers.org/pdf/xerox/parc/techReports/Smalltalk-72_Instruction_Manual_Mar76.pdf)
* [Smalltalk, Objects, and Design](https://books.google.co.in/books?id=W8_Une9cbbgC&printsec=frontcover&dq=smalltalk&hl=en&sa=X&ved=0CCIQ6AEwAWoVChMIw63Vo6CpyAIV0HGOCh3S2Alf#v=onepage&q=smalltalk&f=false)
diff --git a/solidity.html.markdown b/solidity.html.markdown
index acf750f7..cc719ec7 100644
--- a/solidity.html.markdown
+++ b/solidity.html.markdown
@@ -5,6 +5,7 @@ contributors:
- ["Nemil Dalal", "https://www.nemil.com"]
- ["Joseph Chow", ""]
- ["Bhoomtawath Plinsut", "https://github.com/varshard"]
+ - ["Shooter", "https://github.com/liushooter"]
---
Solidity lets you program on [Ethereum](https://www.ethereum.org/), a
@@ -237,7 +238,7 @@ uint x[][5]; // arr with 5 dynamic array elements (opp order of most languages)
// Dictionaries (any type to any other type)
mapping (string => uint) public balances;
balances["charles"] = 1;
-console.log(balances["ada"]); // is 0, all non-set key values return zeroes
+// balances["ada"] result is 0, all non-set key values return zeroes
// 'public' allows following from another contract
contractName.balances("charles"); // returns 1
// 'public' created a getter (but not setter) like the following:
@@ -403,8 +404,12 @@ event LogSent(address indexed from, address indexed to, uint amount); // note ca
// Call
LogSent(from, to, amount);
-// For an external party (a contract or external entity), to watch using
-// the Web3 Javascript library:
+/**
+
+For an external party (a contract or external entity), to watch using
+the Web3 Javascript library:
+
+// The following is Javascript code, not Solidity code
Coin.LogSent().watch({}, '', function(error, result) {
if (!error) {
console.log("Coin transfer: " + result.args.amount +
@@ -415,6 +420,8 @@ Coin.LogSent().watch({}, '', function(error, result) {
"Receiver: " + Coin.balances.call(result.args.to));
}
}
+**/
+
// Common paradigm for one contract to depend on another (e.g., a
// contract that depends on current exchange rate provided by another)
@@ -476,7 +483,7 @@ for(uint x = 0; x < refundAddressList.length; x++) {
// A. Calling external contract
contract InfoFeed {
- function info() returns (uint ret) { return 42; }
+ function info() payable returns (uint ret) { return 42; }
}
contract Consumer {
@@ -831,6 +838,7 @@ someContractAddress.callcode('function_name');
## Additional resources
- [Solidity Docs](https://solidity.readthedocs.org/en/latest/)
- [Smart Contract Best Practices](https://github.com/ConsenSys/smart-contract-best-practices)
+- [Superblocks Lab - Browser based IDE for Solidity](https://lab.superblocks.com/)
- [EthFiddle - The JsFiddle for Solidity](https://ethfiddle.com/)
- [Browser-based Solidity Editor](https://remix.ethereum.org/)
- [Gitter Solidity Chat room](https://gitter.im/ethereum/solidity)
diff --git a/standard-ml.html.markdown b/standard-ml.html.markdown
index b34f1c08..0ba42f39 100644
--- a/standard-ml.html.markdown
+++ b/standard-ml.html.markdown
@@ -272,6 +272,9 @@ fun evenly_positioned_elems (odd::even::xs) = even::evenly_positioned_elems xs
datatype temp =
C of real
| F of real
+
+(* Declaring a new C temp value...
+ val t: temp = C 45.0 *)
fun temp_to_f t =
case t of
diff --git a/stylus.html.markdown b/stylus.html.markdown
new file mode 100644
index 00000000..1c5ddd32
--- /dev/null
+++ b/stylus.html.markdown
@@ -0,0 +1,228 @@
+---
+language: stylus
+filename: learnStylus.styl
+contributors:
+ - ["Salomão Neto", "https://github.com/salomaosnff"]
+ - ["Isaac Henrique", "https://github.com/Isaachi1"]
+translators:
+ - ["Divay Prakash", "https://github.com/divayprakash"]
+---
+
+Stylus is a dynamic stylesheet preprocessor language that is compiled into CSS. It aims to add functionality to CSS without breaking compatibility across web browsers.
+It does this using variables, nesting, mixins, functions and more.
+
+Stylus syntax is very flexible. You can use standard CSS syntax and leave the semicolon (;), colon (:) and even the ({) and (}) optional, making your code even more readable.
+
+Stylus does not provide new style options, but gives functionality that lets you make your CSS much more dynamic.
+
+```scss
+
+/* Code style
+==============================*/
+
+/* Keys, semicolon, and colon are optional in Stylus. */
+
+body {
+ background: #000;
+}
+
+body {
+ background: #000
+}
+
+body {
+ background #000
+}
+
+body
+ background #000
+
+body
+ background: #000;
+
+body
+ background: #000
+
+// Single-line comments are removed when Stylus is compiled into CSS.
+
+/* Multi-line comments are preserved. */
+
+
+/* Selectors
+==============================*/
+
+/* Selecting elements within another element */
+body {
+ background: #000000;
+ h1 {
+ color: #FF0000;
+ }
+}
+
+/* Or if you prefer... */
+body
+ background #000000
+ h1
+ color #FF0000
+
+
+/* Getting parent element reference
+==============================*/
+a {
+ color: #0088dd;
+ &:hover {
+ color: #DD8800;
+ }
+}
+
+
+/* Variables
+==============================*/
+
+
+/*
+ You can store a CSS value (such as the color) of a variable.
+  Although it is optional, it is recommended to add $ before a variable name
+  so you can distinguish a variable from another CSS value.
+*/
+
+$primary-color = #A3A4FF
+$secondary-color = #51527F
+$body-font = 'Roboto', sans-serif
+
+/* You can use variables throughout your style sheet.
+Now, if you want to change the color, you only have to make the change once. */
+
+body
+ background-color $primary-color
+ color $secondary-color
+ font-family $body-font
+
+/* After compilation: */
+body {
+ background-color: #A3A4FF;
+ color: #51527F;
+ font-family: 'Roboto', sans-serif;
+}
+
+/ *
+This is much easier to maintain than having to change color
+each time it appears throughout your style sheet.
+* /
+
+
+/* Mixins
+==============================*/
+
+/* If you find that you are writing the same code for more than one
+element, you may want to store that code in a mixin.
+
+center()
+ display block
+ margin-left auto
+ margin-right auto
+ left 0
+ right 0
+
+/* Using the mixin */
+body {
+ center()
+ background-color: $primary-color
+}
+
+/* After compilation: */
+div {
+ display: block;
+ margin-left: auto;
+ margin-right: auto;
+ left: 0;
+ right: 0;
+ background-color: #A3A4FF;
+}
+
+/* You can use mixins to create a shorthand property. */
+
+size($width, $height)
+ width $width
+ height $height
+
+.rectangle
+ size(100px, 60px)
+
+.square
+ size(40px, 40px)
+
+/* You can use a mixin as a CSS property. */
+circle($ratio)
+ width $ratio * 2
+ height $ratio * 2
+ border-radius $ratio
+
+.ball
+ circle 25px
+
+
+/* Interpolation
+==============================*/
+
+vendor(prop, args)
+ -webkit-{prop} args
+ -moz-{prop} args
+ {prop} args
+
+border-radius()
+ vendor('border-radius', arguments)
+
+box-shadow()
+ vendor('box-shadow', arguments)
+
+button
+ border-radius 1px 2px / 3px 4px
+
+
+/* Functions
+==============================*/
+
+/* Functions in Stylus allow you to perform a variety of tasks, such as recalling some data. */
+
+body {
+ background darken(#0088DD, 50%) // Dim color #0088DD by 50%
+}
+
+/* Creating your own function */
+add(a, b)
+ a + b
+
+body
+ padding add(10px, 5)
+
+
+/* Conditions
+==============================*/
+compare(a, b)
+ if a > b
+ bigger
+ else if a < b
+ smaller
+ else
+ equal
+
+compare(5, 2) // => bigger
+compare(1, 5) // => smaller
+compare(10, 10) // => equal
+
+
+/* Iterations
+==============================*/
+
+/*
+Repeat loop syntax for:
+for <val-name> [, <key-name>] in <expression>
+*/
+
+for $item in (1..2) /* Repeat block 12 times */
+ .col-{$item}
+ width ($item / 12) * 100% /* Calculate row by column number */
+```
+
+Now that you know a little about this powerful CSS preprocessor, you're ready to create more dynamic style sheets. To learn more, visit the official stylus documentation at http://stylus-lang.com.
diff --git a/swift.html.markdown b/swift.html.markdown
index f834f373..c2fb3471 100644
--- a/swift.html.markdown
+++ b/swift.html.markdown
@@ -8,22 +8,26 @@ contributors:
- ["Clayton Walker", "https://github.com/cwalk"]
- ["Fernando Valverde", "http://visualcosita.xyz"]
- ["Alexey Nazaroff", "https://github.com/rogaven"]
+ - ["@Samasaur1", "https://github.com/Samasaur1"]
filename: learnswift.swift
---
Swift is a programming language for iOS and OS X development created by Apple. Designed to coexist with Objective-C and to be more resilient against erroneous code, Swift was introduced in 2014 at Apple's developer conference WWDC. It is built with the LLVM compiler included in Xcode 6+.
-The official _[Swift Programming Language](https://itunes.apple.com/us/book/swift-programming-language/id881256329)_ book from Apple is now available via iBooks.
+The official _[Swift Programming Language](https://itunes.apple.com/us/book/swift-programming-language/id881256329)_ book from Apple is now available via iBooks. It goes into much more detail than this guide, and if you have the time and patience to read it, it's recommended. Some of these examples are from that book.
Another great reference is _About Swift_ on Swift's [website](https://docs.swift.org/swift-book/).
```swift
// import a module
-import UIKit
+import Foundation
-//
-// MARK: Basics
-//
+// Single-line comments are prefixed with //
+// Multi-line comments start with /* and end with */
+/* Nested multiline comments
+ /* ARE */
+ allowed
+ */
// Xcode supports landmarks to annotate your code and lists them in the jump bar
// MARK: Section mark
@@ -31,220 +35,383 @@ import UIKit
// TODO: Do something soon
// FIXME: Fix this code
-// In Swift 2, println and print were combined into one print method. Print automatically appends a new line.
-print("Hello, world") // println is now print
-print("Hello, world", terminator: "") // printing without appending a newline
+//MARK: Hello, World
+// From Swift 3 on, to print, just use the `print` method.
+// It automatically appends a new line.
+print("Hello, world")
+
+//
+// MARK: - Variables
+//
+
+
+//Use `let` to declare a constant and `var` to declare a variable.
+let theAnswer = 42
+var theQuestion = "What is the Answer?"
+theQuestion = "How many roads must a man walk down?"
+theQuestion = "What is six by nine?"
+// Atttempting to reassign a constant throws a compile-time error
+//theAnswer = 54
+
+// Both variables and constants can be declared before they are given a value,
+// but must be given a value before they are used
+let someConstant: Int
+var someVariable: String
+// These lines will throw errors:
+//print(someConstant)
+//print(someVariable)
+someConstant = 0
+someVariable = "0"
+// These lines are now valid:
+print(someConstant)
+print(someVariable)
+
+// As you can see above, variable types are automatically inferred.
+// To explicitly declare the type, write it after the variable name,
+// separated by a colon.
+let aString: String = "A string"
+let aDouble: Double = 0
+
+// Values are never implicitly converted to another type.
+// Explicitly make instances of the desired type.
+let stringWithDouble = aString + String(aDouble)
+let intFromDouble = Int(aDouble)
+
+// For strings, use string interpolation
+let descriptionString = "The value of aDouble is \(aDouble)"
+// You can put any expression inside string interpolation.
+let equation = "Six by nine is \(6 * 9), not 42!"
+// To avoid escaping double quotes and backslashes, change the string delimiter
+let explanationString = #"The string I used was "The value of aDouble is \(aDouble)" and the result was \#(descriptionString)"#
+// You can put as many number signs as you want before the opening quote,
+// just match them at the ending quote. They also change the escape character
+// to a backslash followed by the same number of number signs.
+
+let multiLineString = """
+ This is a multi-line string.
+ It's called that because it takes up multiple lines (wow!)
+ Any indentation beyond the closing quotation marks is kept, the rest is discarded.
+ You can include " or "" in multi-line strings because the delimeter is three "s.
+ """
+
+// Arrays
+let shoppingList = ["catfish", "water", "tulips",] //commas are allowed after the last element
+let secondElement = shoppingList[1] // Arrays are 0-indexed
+
+// Arrays declared with let are immutable; the following line throws a compile-time error
+//shoppingList[2] = "mango"
+
+// Arrays are structs (more on that later), so this creates a copy instead of referencing the same object
+var mutableShoppingList = shoppingList
+mutableShoppingList[2] = "mango"
+
+// == is equality
+shoppingList == mutableShoppingList // false
+
+// Dictionaries declared with let are also immutable
+var occupations = [
+ "Malcolm": "Captain",
+ "Kaylee": "Mechanic"
+]
+occupations["Jayne"] = "Public Relations"
+// Dictionaries are also structs, so this also creates a copy
+let immutableOccupations = occupations
+
+immutableOccupations == occupations // true
-// variables (var) value can change after being set
-// constants (let) value can NOT be changed after being set
+// Arrays and dictionaries both automatically grow as you add elements
+mutableShoppingList.append("blue paint")
+occupations["Tim"] = "CEO"
-var myVariable = 42
+// They can both be set to empty
+mutableShoppingList = []
+occupations = [:]
+
+let emptyArray = [String]()
+let emptyArray2 = Array<String>() // same as above
+// [T] is shorthand for Array<T>
+let emptyArray3: [String] = [] // Declaring the type explicitly allows you to set it to an empty array
+let emptyArray4: Array<String> = [] // same as above
+
+// [Key: Value] is shorthand for Dictionary<Key, Value>
+let emptyDictionary = [String: Double]()
+let emptyDictionary2 = Dictionary<String, Double>() // same as above
+var emptyMutableDictionary: [String: Double] = [:]
+var explicitEmptyMutableDictionary: Dictionary<String, Double> = [:] // same as above
+
+// MARK: Other variables
let øπΩ = "value" // unicode variable names
-let π = 3.1415926
-let convenience = "keyword" // contextual variable name
-let weak = "keyword"; let override = "another keyword" // statements can be separated by a semi-colon
-let `class` = "keyword" // backticks allow keywords to be used as variable names
-let explicitDouble: Double = 70
-let intValue = 0007 // 7
-let largeIntValue = 77_000 // 77000
-let label = "some text " + String(myVariable) // String construction
-let piText = "Pi = \(π), Pi 2 = \(π * 2)" // String interpolation
-
-// Build Specific values
-// uses -D build configuration
-#if false
- print("Not printed")
- let buildValue = 3
-#else
- let buildValue = 7
-#endif
-print("Build value: \(buildValue)") // Build value: 7
+let 🤯 = "wow" // emoji variable names
-/*
-Optionals are a Swift language feature that either contains a value,
-or contains nil (no value) to indicate that a value is missing.
-A question mark (?) after the type marks the value as optional.
+// Keywords can be used as variable names
+// These are contextual keywords that wouldn't be used now, so are allowed
+let convenience = "keyword"
+let weak = "another keyword"
+let override = "another keyword"
+
+// Using backticks allows keywords to be used as variable names even if they wouldn't be allowed normally
+let `class` = "keyword"
-Because Swift requires every property to have a value, even nil must be
-explicitly stored as an Optional value.
+// MARK: - Optionals
+
+/*
+ Optionals are a Swift language feature that either contains a value,
+ or contains nil (no value) to indicate that a value is missing.
+ Nil is roughly equivalent to `null` in other languages.
+ A question mark (?) after the type marks the value as optional of that type.
+
+ If a type is not optional, it is guaranteed to have a value.
+
+ Because Swift requires every property to have a type, even nil must be
+ explicitly stored as an Optional value.
+
+ Optional<T> is an enum, with the cases .none (nil) and .some(T) (the value)
+ */
-Optional<T> is an enum.
-*/
var someOptionalString: String? = "optional" // Can be nil
-// same as above, but ? is a postfix operator (syntax candy)
-var someOptionalString2: Optional<String> = "optional"
+// T? is shorthand for Optional<T> — ? is a postfix operator (syntax candy)
+let someOptionalString2: Optional<String> = nil
+let someOptionalString3 = String?.some("optional") // same as the first one
+let someOptionalString4 = String?.none //nil
+
+/*
+ To access the value of an optional that has a value, use the postfix
+ operator !, which force-unwraps it. Force-unwrapping is like saying, "I
+ know that this optional definitely has a value, please give it to me."
+
+ Trying to use ! to access a non-existent optional value triggers a
+ runtime error. Always make sure that an optional contains a non-nil
+ value before using ! to force-unwrap its value.
+ */
if someOptionalString != nil {
// I am not nil
if someOptionalString!.hasPrefix("opt") {
print("has the prefix")
}
-
- let empty = someOptionalString?.isEmpty
}
-someOptionalString = nil
-/*
-Trying to use ! to access a non-existent optional value triggers a runtime
-error. Always make sure that an optional contains a non-nil value before
-using ! to force-unwrap its value.
-*/
-
-// implicitly unwrapped optional
-var unwrappedString: String! = "Value is expected."
-// same as above, but ! is a postfix operator (more syntax candy)
-var unwrappedString2: ImplicitlyUnwrappedOptional<String> = "Value is expected."
-
-// If let structure -
-// If let is a special structure in Swift that allows you to check if an Optional rhs holds a value, and in case it does - unwraps and assigns it to the lhs.
-if let someOptionalStringConstant = someOptionalString {
+// Swift supports "optional chaining," which means that you can call functions
+// or get properties of optional values and they are optionals of the appropriate type.
+// You can even do this multiple times, hence the name "chaining."
+
+let empty = someOptionalString?.isEmpty // Bool?
+
+// if-let structure -
+// if-let is a special structure in Swift that allows you to check
+// if an Optional rhs holds a value, and if it does unwrap
+// and assign it to the lhs.
+if let someNonOptionalStringConstant = someOptionalString {
// has `Some` value, non-nil
- if !someOptionalStringConstant.hasPrefix("ok") {
+ // someOptionalStringConstant is of type String, not type String?
+ if !someNonOptionalStringConstant.hasPrefix("ok") {
// does not have the prefix
}
}
-// The nil-coalescing operator ?? unwraps an optional if it contains a non-nil value, or returns a default value.
-var someOptionalString: String?
-let someString = someOptionalString ?? "abc"
-print(someString) // abc
+//if-var is allowed too!
+if var someNonOptionalString = someOptionalString {
+ someNonOptionalString = "Non optional AND mutable"
+ print(someNonOptionalString)
+}
-// Swift has support for storing a value of any type.
-// For that purposes there is two keywords: `Any` and `AnyObject`
-// `AnyObject` == `id` from Objective-C
-// `Any` – also works with any scalar values (Class, Int, struct, etc.)
-var anyVar: Any = 7
-anyVar = "Changed value to a string, not good practice, but possible."
-let anyObjectVar: AnyObject = Int(1) as NSNumber
+// You can bind multiple optional values in one if-let statement.
+// If any of the bound values are nil, the if statement does not execute.
+if let first = someOptionalString, let second = someOptionalString2,
+ let third = someOptionalString3, let fourth = someOptionalString4 {
+ print("\(first), \(second), \(third), and \(fourth) are all not nil")
+}
-/*
- Comment here
+//if-let supports "," (comma) clauses, which can be used to
+// enforce conditions on newly-bound optional values.
+// Both the assignment and the "," clause must pass.
+let someNumber: Int? = 7
+if let num = someNumber, num > 3 {
+ print("num is not nil and is greater than 3")
+}
- /*
- Nested comments are also supported
- */
-*/
+// Implicitly unwrapped optional — An optional value that doesn't need to be unwrapped
+let unwrappedString: String! = "Value is expected."
-//
-// MARK: Collections
-//
+// Here's the difference:
+let forcedString = someOptionalString! // requires an exclamation mark
+let implicitString = unwrappedString // doesn't require an exclamation mark
/*
-Array and Dictionary types are structs. So `let` and `var` also indicate
-that they are mutable (var) or immutable (let) when declaring these types.
-*/
-
-// Array
-var shoppingList = ["catfish", "water", "lemons"]
-shoppingList[1] = "bottle of water"
-let emptyArray = [String]() // let == immutable
-let emptyArray2 = Array<String>() // same as above
-var emptyMutableArray = [String]() // var == mutable
-var explicitEmptyMutableStringArray: [String] = [] // same as above
-
+ You can think of an implicitly unwrapped optional as giving permission
+ for the optional to be unwrapped automatically whenever it's used.
+ Rather than placing an exclamation mark after the optional's name each time you use it,
+ you place an exclamation mark after the optional's type when you declare it.
+ */
-// Dictionary
-var occupations = [
- "Malcolm": "Captain",
- "kaylee": "Mechanic"
-]
-occupations["Jayne"] = "Public Relations"
-let emptyDictionary = [String: Float]() // let == immutable
-let emptyDictionary2 = Dictionary<String, Float>() // same as above
-var emptyMutableDictionary = [String: Float]() // var == mutable
-var explicitEmptyMutableDictionary: [String: Float] = [:] // same as above
+// Otherwise, you can treat an implicitly unwrapped optional the same way the you treat a normal optional
+// (i.e., if-let, != nil, etc.)
+// Pre-Swift 5, T! was shorthand for ImplicitlyUnwrappedOptional<T>
+// Swift 5 and later, using ImplicitlyUnwrappedOptional throws a compile-time error.
+//var unwrappedString2: ImplicitlyUnwrappedOptional<String> = "Value is expected." //error
-//
-// MARK: Control Flow
-//
-
-// Condition statements support "," (comma) clauses, which can be used
-// to help provide conditions on optional values.
-// Both the assignment and the "," clause must pass.
-let someNumber = Optional<Int>(7)
-if let num = someNumber, num > 3 {
- print("num is greater than 3")
-}
-
-// for loop (array)
-let myArray = [1, 1, 2, 3, 5]
-for value in myArray {
- if value == 1 {
- print("One!")
- } else {
- print("Not one!")
- }
-}
+// The nil-coalescing operator ?? unwraps an optional if it contains a non-nil value, or returns a default value.
+someOptionalString = nil
+let someString = someOptionalString ?? "abc"
+print(someString) // abc
+// a ?? b is shorthand for a != nil ? a! : b
-// for loop (dictionary)
-var dict = ["one": 1, "two": 2]
-for (key, value) in dict {
- print("\(key): \(value)")
-}
+// MARK: - Control Flow
-// for loop (range)
-for i in -1...shoppingList.count {
- print(i)
-}
-shoppingList[1...2] = ["steak", "peacons"]
-// use ..< to exclude the last number
+let condition = true
+if condition { print("condition is true") } // can't omit the braces
-// while loop
-var i = 1
-while i < 1000 {
- i *= 2
+if theAnswer > 50 {
+ print("theAnswer > 50")
+} else if condition {
+ print("condition is true")
+} else {
+ print("Neither are true")
}
-// repeat-while loop
-repeat {
- print("hello")
-} while 1 == 2
+// The condition in an `if` statement must be a `Bool`, so the following code is an error, not an implicit comparison to zero
+//if 5 {
+// print("5 is not zero")
+//}
// Switch
+// Must be exhaustive
+// Does not implicitly fall through, use the fallthrough keyword
// Very powerful, think `if` statements with syntax candy
// They support String, object instances, and primitives (Int, Double, etc)
let vegetable = "red pepper"
+let vegetableComment: String
switch vegetable {
case "celery":
- let vegetableComment = "Add some raisins and make ants on a log."
-case "cucumber", "watercress":
- let vegetableComment = "That would make a good tea sandwich."
+ vegetableComment = "Add some raisins and make ants on a log."
+case "cucumber", "watercress": // match multiple values
+ vegetableComment = "That would make a good tea sandwich."
case let localScopeValue where localScopeValue.hasSuffix("pepper"):
- let vegetableComment = "Is it a spicy \(localScopeValue)?"
+ vegetableComment = "Is it a spicy \(localScopeValue)?"
default: // required (in order to cover all possible input)
- let vegetableComment = "Everything tastes good in soup."
+ vegetableComment = "Everything tastes good in soup."
+}
+print(vegetableComment)
+
+// You use the `for-in` loop to iterate over a sequence, such as an array, dictionary, range, etc.
+for element in shoppingList {
+ print(element) // shoppingList is of type `[String]`, so element is of type `String`
+}
+//Iterating through a dictionary does not guarantee any specific order
+for (person, job) in immutableOccupations {
+ print("\(person)'s job is \(job)")
+}
+for i in 1...5 {
+ print(i, terminator: " ") // Prints "1 2 3 4 5"
+}
+for i in 0..<5 {
+ print(i, terminator: " ") // Prints "0 1 2 3 4"
+}
+//for index in range can replace a C-style for loop:
+// for (int i = 0; i < 10; i++) {
+// //code
+// }
+//becomes:
+// for i in 0..<10 {
+// //code
+// }
+//To step by more than one, use the stride(from:to:by:) or stride(from:through:by) functions
+//`for i in stride(from: 0, to: 10, by: 2)` is the same as `for (int i = 0; i < 10; i += 2)`
+//`for i in stride(from: 0, through: 10, by: 2)` is the same as `for (int i = 0; i <= 10; i += 2)
+
+// while loops are just like most languages
+var i = 0
+while i < 5 {
+ i += Bool.random() ? 1 : 0
+ print(i)
}
-//
-// MARK: Functions
-//
+// This is like a do-while loop in other languages — the body of the loop executes a minimum of once
+repeat {
+ i -= 1
+ i += Int.random(in: 0...3)
+} while i < 5
-// Functions are a first-class type, meaning they can be nested
-// in functions and can be passed around
+// The continue statement continues executing a loop at the next iteration
+// The break statement ends a swift or loop immediately
-// Function with Swift header docs (format as Swift-modified Markdown syntax)
+// MARK: - Functions
-/**
-A greet operation
+// Functions are a first-class type, meaning they can be nested in functions and can be passed around.
-- A bullet in docs
-- Another bullet in the docs
+// Function with Swift header docs (format as Swift-modified Markdown syntax)
-- Parameter name : A name
-- Parameter day : A day
-- Returns : A string containing the name and day value.
-*/
+/// A greet operation.
+///
+/// - Parameters:
+/// - name: A name.
+/// - day: A day.
+/// - Returns: A string containing the name and day value.
func greet(name: String, day: String) -> String {
return "Hello \(name), today is \(day)."
}
greet(name: "Bob", day: "Tuesday")
-// similar to above except for the function parameter behaviors
-func greet2(name: String, externalParamName localParamName: String) -> String {
- return "Hello \(name), the day is \(localParamName)"
+// Ideally, function names and parameter labels combine to make function calls similar to sentences.
+func sayHello(to name: String, onDay day: String) -> String {
+ return "Hello \(name), the day is \(day)"
+}
+sayHello(to: "John", onDay: "Sunday")
+
+//Functions that don't return anything can omit the return arrow; they don't need to say that they return Void (although they can).
+func helloWorld() {
+ print("Hello, World!")
+}
+
+// Argument labels can be blank
+func say(_ message: String) {
+ print(#"I say "\#(message)""#)
+}
+say("Hello")
+
+// Default parameters can be ommitted when calling the function.
+func printParameters(requiredParameter r: Int, optionalParameter o: Int = 10) {
+ print("The required parameter was \(r) and the optional parameter was \(o)")
+}
+printParameters(requiredParameter: 3)
+printParameters(requiredParameter: 3, optionalParameter: 6)
+
+// Variadic args — only one set per function.
+func setup(numbers: Int...) {
+ // it's an array
+ let _ = numbers[0]
+ let _ = numbers.count
+}
+
+// pass by ref
+func swapTwoInts(a: inout Int, b: inout Int) {
+ let tempA = a
+ a = b
+ b = tempA
+}
+var someIntA = 7
+var someIntB = 3
+swapTwoInts(a: &someIntA, b: &someIntB) //must be called with an & before the variable name.
+print(someIntB) // 7
+
+type(of: greet) // (String, String) -> String
+type(of: helloWorld) // () -> Void
+
+// Passing and returning functions
+func makeIncrementer() -> ((Int) -> Int) {
+ func addOne(number: Int) -> Int {
+ return 1 + number
+ }
+ return addOne
+}
+var increment = makeIncrementer()
+increment(7)
+
+func performFunction(_ function: (String, String) -> String, on string1: String, and string2: String) {
+ let result = function(string1, string2)
+ print("The result of calling the function on \(string1) and \(string2) was \(result)")
}
-greet2(name: "John", externalParamName: "Sunday")
// Function that returns multiple items in a tuple
func getGasPrices() -> (Double, Double, Double) {
@@ -271,46 +438,24 @@ print("Highest gas price: \(pricesTuple2.highestPrice)")
func testGuard() {
// guards provide early exits or breaks, placing the error handler code near the conditions.
// it places variables it declares in the same scope as the guard statement.
+ // They make it easier to avoid the "pyramid of doom"
guard let aNumber = Optional<Int>(7) else {
- return
+ return // guard statements MUST exit the scope that they are in.
+ // They generally use `return` or `throw`.
}
-
+
print("number is \(aNumber)")
}
testGuard()
-// Variadic Args
-func setup(numbers: Int...) {
- // it's an array
- let _ = numbers[0]
- let _ = numbers.count
-}
-
-// Passing and returning functions
-func makeIncrementer() -> ((Int) -> Int) {
- func addOne(number: Int) -> Int {
- return 1 + number
- }
- return addOne
-}
-var increment = makeIncrementer()
-increment(7)
-
-// pass by ref
-func swapTwoInts(a: inout Int, b: inout Int) {
- let tempA = a
- a = b
- b = tempA
-}
-var someIntA = 7
-var someIntB = 3
-swapTwoInts(a: &someIntA, b: &someIntB)
-print(someIntB) // 7
+// Note that the print function is declared like so:
+// func print(_ input: Any..., separator: String = " ", terminator: String = "\n")
+// To print without a newline:
+print("No newline", terminator: "")
+print("!")
+// MARK: - Closures
-//
-// MARK: Closures
-//
var numbers = [1, 2, 6]
// Functions are special case closures ({})
@@ -336,85 +481,157 @@ numbers = numbers.sorted { $0 > $1 }
print(numbers) // [18, 6, 3]
-//
-// MARK: Structures
-//
+// MARK: - Enums
-// Structures and classes have very similar capabilities
-struct NamesTable {
- let names: [String]
+// Enums can optionally be of a specific type or on their own.
+// They can contain methods like classes.
- // Custom subscript
- subscript(index: Int) -> String {
- return names[index]
+enum Suit {
+ case spades, hearts, diamonds, clubs
+ var icon: Character {
+ switch self {
+ case .spades:
+ return "♤"
+ case .hearts:
+ return "♡"
+ case .diamonds:
+ return "♢"
+ case .clubs:
+ return "♧"
+ }
}
}
-// Structures have an auto-generated (implicit) designated initializer
-let namesTable = NamesTable(names: ["Me", "Them"])
-let name = namesTable[1]
-print("Name is \(name)") // Name is Them
-
-//
-// MARK: Error Handling
-//
+// Enum values allow short hand syntax, no need to type the enum type
+// when the variable is explicitly declared
+var suitValue: Suit = .hearts
-// The `Error` protocol is used when throwing errors to catch
-enum MyError: Error {
- case badValue(msg: String)
- case reallyBadValue(msg: String)
+// Conforming to the CaseIterable protocol automatically synthesizes the allCases property,
+// which contains all the values. It works on enums without associated values or @available attributes.
+enum Rank: CaseIterable {
+ case ace
+ case two, three, four, five, six, seven, eight, nine, ten
+ case jack, queen, king
+ var icon: String {
+ switch self {
+ case .ace:
+ return "A"
+ case .two:
+ return "2"
+ case .three:
+ return "3"
+ case .four:
+ return "4"
+ case .five:
+ return "5"
+ case .six:
+ return "6"
+ case .seven:
+ return "7"
+ case .eight:
+ return "8"
+ case .nine:
+ return "9"
+ case .ten:
+ return "10"
+ case .jack:
+ return "J"
+ case .queen:
+ return "Q"
+ case .king:
+ return "K"
+ }
+ }
}
-// functions marked with `throws` must be called using `try`
-func fakeFetch(value: Int) throws -> String {
- guard 7 == value else {
- throw MyError.reallyBadValue(msg: "Some really bad value")
+for suit in [Suit.clubs, .diamonds, .hearts, .spades] {
+ for rank in Rank.allCases {
+ print("\(rank.icon)\(suit.icon)")
}
+}
- return "test"
+// String enums can have direct raw value assignments
+// or their raw values will be derived from the Enum field
+enum BookName: String {
+ case john
+ case luke = "Luke"
}
+print("Name: \(BookName.john.rawValue)")
-func testTryStuff() {
- // assumes there will be no error thrown, otherwise a runtime exception is raised
- let _ = try! fakeFetch(value: 7)
+// Enum with associated Values
+enum Furniture {
+ // Associate with Int
+ case desk(height: Int)
+ // Associate with String and Int
+ case chair(String, Int)
+
+ func description() -> String {
+ //either placement of let is acceptable
+ switch self {
+ case .desk(let height):
+ return "Desk with \(height) cm"
+ case let .chair(brand, height):
+ return "Chair of \(brand) with \(height) cm"
+ }
+ }
+}
- // if an error is thrown, then it proceeds, but if the value is nil
- // it also wraps every return value in an optional, even if its already optional
- let _ = try? fakeFetch(value: 7)
+var desk: Furniture = .desk(height: 80)
+print(desk.description()) // "Desk with 80 cm"
+var chair = Furniture.chair("Foo", 40)
+print(chair.description()) // "Chair of Foo with 40 cm"
- do {
- // normal try operation that provides error handling via `catch` block
- try fakeFetch(value: 1)
- } catch MyError.badValue(let msg) {
- print("Error message: \(msg)")
- } catch {
- // must be exhaustive
+// MARK: - Structures & Classes
+
+/*
+ Structures and classes in Swift have many things in common. Both can:
+ - Define properties to store values
+ - Define methods to provide functionality
+ - Define subscripts to provide access to their values using subscript syntax
+ - Define initializers to set up their initial state
+ - Be extended to expand their functionality beyond a default implementation
+ - Conform to protocols to provide standard functionality of a certain kind
+
+ Classes have additional capabilities that structures don't have:
+ - Inheritance enables one class to inherit the characteristics of another.
+ - Type casting enables you to check and interpret the type of a class instance at runtime.
+ - Deinitializers enable an instance of a class to free up any resources it has assigned.
+ - Reference counting allows more than one reference to a class instance.
+
+ Unless you need to use a class for one of these reasons, use a struct.
+
+ Structures are value types, while classes are reference types.
+ */
+
+// MARK: Structures
+
+struct NamesTable {
+ let names: [String]
+
+ // Custom subscript
+ subscript(index: Int) -> String {
+ return names[index]
}
}
-testTryStuff()
-//
-// MARK: Classes
-//
+// Structures have an auto-generated (implicit) designated "memberwise" initializer
+let namesTable = NamesTable(names: ["Me", "Them"])
+let name = namesTable[1]
+print("Name is \(name)") // Name is Them
-// Classes, structures and its members have three levels of access control
-// They are: internal (default), public, private
+// MARK: Classes
-public class Shape {
- public func getArea() -> Int {
+class Shape {
+ func getArea() -> Int {
return 0
}
}
-// All methods and properties of a class are public.
-// If you just need to store data in a
-// structured object, you should use a `struct`
-
-internal class Rect: Shape {
+class Rect: Shape {
var sideLength: Int = 1
-
+
// Custom getter and setter property
- private var perimeter: Int {
+ var perimeter: Int {
get {
return 4 * sideLength
}
@@ -423,16 +640,16 @@ internal class Rect: Shape {
sideLength = newValue / 4
}
}
-
+
// Computed properties must be declared as `var`, you know, cause' they can change
var smallestSideLength: Int {
return self.sideLength - 1
}
-
+
// Lazily load a property
// subShape remains nil (uninitialized) until getter called
lazy var subShape = Rect(sideLength: 4)
-
+
// If you don't need a custom getter and setter,
// but still want to run code before and after getting or setting
// a property, you can use `willSet` and `didSet`
@@ -442,19 +659,19 @@ internal class Rect: Shape {
print(someIdentifier)
}
}
-
+
init(sideLength: Int) {
self.sideLength = sideLength
// always super.init last when init custom properties
super.init()
}
-
+
func shrink() {
if sideLength > 0 {
sideLength -= 1
}
}
-
+
override func getArea() -> Int {
return sideLength * sideLength
}
@@ -486,13 +703,13 @@ class Circle: Shape {
override func getArea() -> Int {
return 3 * radius * radius
}
-
+
// Place a question mark postfix after `init` is an optional init
// which can return nil
init?(radius: Int) {
self.radius = radius
super.init()
-
+
if radius <= 0 {
return nil
}
@@ -509,104 +726,143 @@ if let circle = myEmptyCircle {
print("circle is not nil")
}
+// MARK: - Protocols
-//
-// MARK: Enums
-//
+// protocols are also known as interfaces in some other languages
-// Enums can optionally be of a specific type or on their own.
-// They can contain methods like classes.
+// `protocol`s can require that conforming types have specific
+// instance properties, instance methods, type methods,
+// operators, and subscripts.
-enum Suit {
- case spades, hearts, diamonds, clubs
- func getIcon() -> String {
- switch self {
- case .spades: return "♤"
- case .hearts: return "♡"
- case .diamonds: return "♢"
- case .clubs: return "♧"
- }
- }
+protocol ShapeGenerator {
+ var enabled: Bool { get set }
+ func buildShape() -> Shape
}
-// Enum values allow short hand syntax, no need to type the enum type
-// when the variable is explicitly declared
-var suitValue: Suit = .hearts
+// MARK: - Other
-// String enums can have direct raw value assignments
-// or their raw values will be derived from the Enum field
-enum BookName: String {
- case john
- case luke = "Luke"
-}
-print("Name: \(BookName.john.rawValue)")
+// MARK: Typealiases
-// Enum with associated Values
-enum Furniture {
- // Associate with Int
- case desk(height: Int)
- // Associate with String and Int
- case chair(String, Int)
+// Typealiases allow one type (or composition of types) to be referred to by another name
+typealias Integer = Int
+let myInteger: Integer = 0
- func description() -> String {
- switch self {
- case .desk(let height):
- return "Desk with \(height) cm"
- case .chair(let brand, let height):
- return "Chair of \(brand) with \(height) cm"
- }
- }
-}
+// MARK: = Operator
-var desk: Furniture = .desk(height: 80)
-print(desk.description()) // "Desk with 80 cm"
-var chair = Furniture.chair("Foo", 40)
-print(chair.description()) // "Chair of Foo with 40 cm"
+// Assignment does not return a value. This means it can't be used in conditional statements,
+// and the following statement is also illegal
+// let multipleAssignment = theQuestion = "No questions asked"
+//But you can do this:
+let multipleAssignment = "No questions asked", secondConstant = "No answers given"
+// MARK: Ranges
-//
-// MARK: Protocols
-//
+// The ..< and ... operators create ranges.
-// `protocol`s can require that conforming types have specific
-// instance properties, instance methods, type methods,
-// operators, and subscripts.
+// ... is inclusive on both ends (a "closed range") — mathematically, [0, 10]
+let _0to10 = 0...10
+// ..< is inclusive on the left, exclusive on the right (a "range") — mathematically, [0, 10)
+let singleDigitNumbers = 0..<10
+// You can omit one end (a "PartialRangeFrom") — mathematically, [0, ∞)
+let toInfinityAndBeyond = 0...
+// Or the other end (a "PartialRangeTo") — mathematically, (-∞, 0)
+let negativeInfinityToZero = ..<0
+// (a "PartialRangeThrough") — mathematically, (-∞, 0]
+let negativeInfinityThroughZero = ...0
-protocol ShapeGenerator {
- var enabled: Bool { get set }
- func buildShape() -> Shape
+// MARK: Wildcard operator
+
+// In Swift, _ (underscore) is the wildcard operator, which allows values to be ignored
+
+// It allows functions to be declared without argument labels:
+func function(_ labelLessParameter: Int, label labeledParameter: Int, labelAndParameterName: Int) {
+ print(labelLessParameter, labeledParameter, labelAndParameterName)
}
+function(0, label: 0, labelAndParameterName: 0)
-// Protocols declared with @objc allow optional functions,
-// which allow you to check for conformance. These functions must be
-// marked with @objc also.
-@objc protocol TransformShape {
- @objc optional func reshape()
- @objc optional func canReshape() -> Bool
+// You can ignore the return values of functions
+func printAndReturn(_ str: String) -> String {
+ print(str)
+ return str
}
+let _ = printAndReturn("Some String")
-class MyShape: Rect {
- var delegate: TransformShape?
+// You can ignore part of a tuple and keep part of it
+func returnsTuple() -> (Int, Int) {
+ return (1, 2)
+}
+let (_, two) = returnsTuple()
- func grow() {
- sideLength += 2
+// You can ignore closure parameters
+let closure: (Int, Int) -> String = { someInt, _ in
+ return "\(someInt)"
+}
+closure(1, 2) // returns 1
- // Place a question mark after an optional property, method, or
- // subscript to gracefully ignore a nil value and return nil
- // instead of throwing a runtime error ("optional chaining").
- if let reshape = self.delegate?.canReshape?(), reshape {
- // test for delegate then for method
- self.delegate?.reshape?()
- }
- }
+// You can ignore the value in a for loop
+for _ in 0..<10 {
+ // Code to execute 10 times
}
+// MARK: Access Control
-//
-// MARK: Other
-//
+/*
+ Swift has five levels of access control:
+ - Open: Accessible *and subclassible* in any module that imports it.
+ - Public: Accessible in any module that imports it, subclassible in the module it is declared in.
+ - Internal: Accessible and subclassible in the module it is declared in.
+ - Fileprivate: Accessible and subclassible in the file it is declared in.
+ - Private: Accessible and subclassible in the enclosing declaration (think inner classes/structs/enums)
+
+ See more here: https://docs.swift.org/swift-book/LanguageGuide/AccessControl.html
+ */
+
+// MARK: Conditional Compilation, Compile-Time Diagnostics, & Availability Conditions
+
+// Conditional Compilation
+#if false
+print("This code will not be compiled")
+#else
+print("This code will be compiled")
+#endif
+/*
+ Options are:
+ os() macOS, iOS, watchOS, tvOS, Linux
+ arch() i386, x86_64, arm, arm64
+ swift() >= or < followed by a version number
+ compiler() >= or < followed by a version number
+ canImport() A module name
+ targetEnvironment() simulator
+ */
+#if swift(<3)
+println()
+#endif
+
+// Compile-Time Diagnostics
+// You can use #warning(message) and #error(message) to have the compiler emit warnings and/or errors
+#warning("This will be a compile-time warning")
+// #error("This would be a compile-time error")
+
+//Availability Conditions
+if #available(iOSMac 10.15, *) {
+ // macOS 10.15 is available, you can use it here
+} else {
+ // macOS 10.15 is not available, use alternate APIs
+}
+
+// MARK: Any and AnyObject
+
+// Swift has support for storing a value of any type.
+// For that purpose there are two keywords: `Any` and `AnyObject`
+// `AnyObject` == `id` from Objective-C
+// `Any` works with any values (class, Int, struct, etc.)
+var anyVar: Any = 7
+anyVar = "Changed value to a string, not good practice, but possible."
+let anyObjectVar: AnyObject = Int(1) as NSNumber
-// `extension`s: Add extra functionality to an already existing type
+// MARK: Extensions
+
+// Extensions allow you to add extra functionality to an already-declared type, even one that you don't have the source code for.
// Square now "conforms" to the `CustomStringConvertible` protocol
extension Square: CustomStringConvertible {
@@ -619,17 +875,23 @@ print("Square: \(mySquare)")
// You can also extend built-in types
extension Int {
- var customProperty: String {
- return "This is \(self)"
+ var doubled: Int {
+ return self * 2
}
-
- func multiplyBy(num: Int) -> Int {
+
+ func multipliedBy(num: Int) -> Int {
return num * self
}
+
+ mutating func multiplyBy(num: Int) {
+ self *= num
+ }
}
-print(7.customProperty) // "This is 7"
-print(14.multiplyBy(num: 3)) // 42
+print(7.doubled) // 14
+print(7.doubled.multipliedBy(num: 3)) // 42
+
+// MARK: Generics
// Generics: Similar to Java and C#. Use the `where` keyword to specify the
// requirements of the generics.
@@ -642,10 +904,21 @@ func findIndex<T: Equatable>(array: [T], valueToFind: T) -> Int? {
}
return nil
}
-let foundAtIndex = findIndex(array: [1, 2, 3, 4], valueToFind: 3)
-print(foundAtIndex == 2) // true
+findIndex(array: [1, 2, 3, 4], valueToFind: 3) // 2
+
+// You can extend types with generics as well
+extension Array where Array.Element == Int {
+ var sum: Int {
+ var total = 0
+ for el in self {
+ total += el
+ }
+ return total
+ }
+}
+
+// MARK: Operators
-// Operators:
// Custom operators can start with the characters:
// / = - + * % < > ! & | ^ . ~
// or
@@ -678,4 +951,40 @@ var bar: Float = 20
foo <-> bar
print("foo is \(foo), bar is \(bar)") // "foo is 20.0, bar is 10.0"
+
+// MARK: - Error Handling
+
+// The `Error` protocol is used when throwing errors to catch
+enum MyError: Error {
+ case badValue(msg: String)
+ case reallyBadValue(msg: String)
+}
+
+// functions marked with `throws` must be called using `try`
+func fakeFetch(value: Int) throws -> String {
+ guard 7 == value else {
+ throw MyError.reallyBadValue(msg: "Some really bad value")
+ }
+
+ return "test"
+}
+
+func testTryStuff() {
+ // assumes there will be no error thrown, otherwise a runtime exception is raised
+ let _ = try! fakeFetch(value: 7)
+
+ // if an error is thrown, then it proceeds, but if the value is nil
+ // it also wraps every return value in an optional, even if its already optional
+ let _ = try? fakeFetch(value: 7)
+
+ do {
+ // normal try operation that provides error handling via `catch` block
+ try fakeFetch(value: 1)
+ } catch MyError.badValue(let msg) {
+ print("Error message: \(msg)")
+ } catch {
+ // must be exhaustive
+ }
+}
+testTryStuff()
```
diff --git a/tcsh.html.markdown b/tcsh.html.markdown
index 80411ea6..e38b7a27 100644
--- a/tcsh.html.markdown
+++ b/tcsh.html.markdown
@@ -1,5 +1,6 @@
---
-language: tcsh
+category: tool
+tool: tcsh
filename: LearnTCSH.csh
contributors:
- ["Nicholas Christopoulos", "https://github.com/nereusx"]
diff --git a/th-th/pascal.th.html.markdown b/th-th/pascal.th.html.markdown
index 4fe0c4ac..bf1da958 100644
--- a/th-th/pascal.th.html.markdown
+++ b/th-th/pascal.th.html.markdown
@@ -2,13 +2,14 @@
language: Pascal
filename: learnpascal.pas
contributors:
- - ["Ganesha Danu", "http://github.com/blinfoldking"]
- - ["Keith Miyake", "https://github.com/kaymmm"]
- - ["Worajedt Sitthidumrong", "https://bitbucket.org/wrj"]
+ - ["Ganesha Danu", "http://github.com/blinfoldking"]
+ - ["Keith Miyake", "https://github.com/kaymmm"]
+translators:
+ - ["Worajedt Sitthidumrong", "https://bitbucket.org/wrj"]
lang: th-th
---
-Pascal (ปาสกาล) เป็นภาษาโปรแกรมมิ่งทั้งแบบ imperative และ procedural ที่ออกแบบโดย Niklaus Wirth (นิเคล้า เวิร์ท) เมื่อปี 1968-69 และเผยแพร่ตอน 1970 โดยเน้นให้เป็นภาษาที่เล็ก มีประสิทธิภาพ เพื่อเสริมการเขียนโปรแกรมที่มีแนวปฏิบัติที่ดีด้วยการใช้โครงสร้างของตัวภาษา และโครงสร้างข้อมูลมากำกับ ชื่อของภาษานี้ตั้งเป็นเกียรติให้กับนักคณิตศาสตร์ชาวฝรั่งเศส, นักปรัชญา และนักฟิสิกส์ ชื่อ Blaise Pascal (เบลส ปาสกาล) ข้อมูลจาก : [วิกิพีเดีย][1]
+> Pascal (ปาสกาล) เป็นภาษาโปรแกรมมิ่งทั้งแบบ imperative และ procedural ที่ออกแบบโดย Niklaus Wirth (นิเคล้า เวิร์ท) เมื่อปี 1968-69 และเผยแพร่ตอน 1970 โดยเน้นให้เป็นภาษาที่เล็ก มีประสิทธิภาพ เพื่อเสริมการเขียนโปรแกรมที่มีแนวปฏิบัติที่ดีด้วยการใช้โครงสร้างของตัวภาษา และโครงสร้างข้อมูลมากำกับ ชื่อของภาษานี้ตั้งเป็นเกียรติให้กับนักคณิตศาสตร์ชาวฝรั่งเศส, นักปรัชญา และนักฟิสิกส์ ชื่อ Blaise Pascal (เบลส ปาสกาล) ข้อมูลจาก : [วิกิพีเดีย][1]
การคอมไพล์และรันโค้ดภาษาปาสกาลนี้ สามารถใช้ปาสกาลคอมไพลเลอร์ฟรีชื่อ Free Pascal ได้ โดย [ดาวน์โหลดที่นี่][2]
@@ -37,7 +38,8 @@ type
}
var
{
- ตัวแปร ในภาษาปาสกาล ไม่เหมือนกับภาษาอื่น ๆ เพราะต้องประกาศในบล็อค var ก่อนใช้งานเสมอ
+ ตัวแปร ในภาษาปาสกาล ไม่เหมือนกับภาษาอื่น ๆ
+ เพราะต้องประกาศในบล็อค var ก่อนใช้งานเสมอ
}
//มาถึงส่วนโปรแกรมหลัก หรือ main fucntion นั่นเอง
@@ -65,7 +67,7 @@ var
var a,b : integer;
```
-โค้ดตัวอย่างนี้เป็นโปรแกรม Learn_More ที่เป็นโครงสร้างโปรแกรมง่าย ๆ ที่จบสมบูรณ์หนึ่งโปรแกรม มีบล็อค program, const, type, main (Begin..End.)
+โค้ดตัวอย่างนี้เป็นโปรแกรม Learn\_More ที่เป็นโครงสร้างโปรแกรมง่าย ๆ ที่จบสมบูรณ์หนึ่งโปรแกรม มีบล็อค program, const, type, main (Begin..End.)
```pascal
program Learn_More;
@@ -77,10 +79,11 @@ const
// ค่าคงที่ ให้ตั้งชื่อเป็น ตัวพิมพ์ใหญ่ ทั้งหมด ใช้กับชนิดข้อมูลใดๆ ก็ได้
// ค่าคงที่ ก็ตามชื่อเลย กำหนดค่าแล้ว ไม่สามารถเปลี่ยนแปลงได้ขณะรัน
-// การประกาศชนิดข้อมูลของเราเอง : ชนิดของตัวแปรสองแบบนี้ จะนำไปใช้ด้านล่าง
+// การประกาศชนิดข้อมูลของเราเอง
+// "ชนิด" ของตัวแปรสองแบบนี้ จะนำไปใช้ด้านล่าง
type
ch_array : array [0..255] of char;
- // อะเรย์ เป็นชนิดข้อมูลอีกแบบ ที่มี ความยาว/ช่องเก็บข้อมูล และ ชนิดข้อมูล
+ // อะเรย์ เป็นชนิดข้อมูลที่มี ความยาว/ช่องเก็บข้อมูล และ ชนิดข้อมูล
// โค้ดด้านบน เป็นการประกาศอะเรย์ของตัวอักษา 255 ตัวอักษา
// ซึ่งได้ ความยาว/ช่องเก็บข้อมูลในตัวแปรตัวนี้ 256 ช่องที่เป็นข้อความ
md_array : array of array of integer;
@@ -106,14 +109,14 @@ var
// ตัวอักษรเป็นแบบ ASCII 8 bit ดังนั้นจะไม่ใช่ UTF, Unicode
str : string;
// ตัวแปรสตริงจะเก็บข้อความ หรือ char หลาย ๆ ตัว
- // ชนิดข้อมูลนี้ไม่เป็นมาตรฐานภาษาแต่แทบทุกคอมไพเลอร์ปาสกาลก็จะมีให้
+ // ชนิดข้อมูลนี้ไม่เป็นมาตรฐานภาษาแต่คอมไพเลอร์ปาสกาลก็มักจะมีให้
// ทั่ว ๆ ไปแล้ว จะเป็นอะเรย์ของ char ความยาวตั้งต้น 255
s : string[50];
// แบบนี้คือ กำหนดความยาว string เอง ให้เก็บ char 50 ตัว
// แบบนี้ก็ทำให้ประหยัดหน่วยความจำมากขึ้นนั่นเอง
my_str: ch_array;
// ชนิดตัวแปร ใช้เป็นชนิดที่เรากำหนดเองก็ได้ อย่างตอนนี้
- // ch_array เป็น "ชนิดข้อมูล" ที่เราสร้างขึ้นมาเอง ด้านบนที่บล็อค type
+ // ch_array เป็น "ชนิดข้อมูล" ที่เราสร้างขึ้นมาในบล็อค type
my_2d : md_array;
// ตัวแปรแบบอะเรย์ที่ไม่ประกาศขนาด (dynamically sized array)
// ก่อนเอาไปใช้จริงต้องระบุขนาดก่อนใช้เสมอ
@@ -126,11 +129,13 @@ var
li : longint; // มีช่วงข้อมูล [-2,147,483,648..2,147,483,647]
lw : longword; // มีช่วงข้อมูล [0..4,294,967,295]
c : cardinal; // ก็คือ longword
- i64 : int64; // มีช่วงข้อมูล [-9223372036854775808..9223372036854775807]
+ i64 : int64; // มีช่วงข้อมูล
+ // [-9223372036854775808..9223372036854775807]
qw : qword; // มีช่วงข้อมูล [0..18,446,744,073,709,551,615]
// ชนิดข้อมูลแบบ real เพิ่มเติม
- rr : real; // มีช่วงข้อมูลที่ขึ้นกับระบบปฏิบัติการ (เช่นเป็นแบบ 8-bit, 16-bit, ฯลฯ)
+ rr : real; // มีช่วงข้อมูลที่ขึ้นกับระบบปฏิบัติการ
+ // (เช่นเป็นแบบ 8-bit, 16-bit, ฯลฯ)
rs : single; // มีช่วงข้อมูล [1.5E-45..3.4E38]
rd : double; // มีช่วงข้อมูล [5.0E-324 .. 1.7E308]
re : extended; // มีช่วงข้อมูล [1.9E-4932..1.1E4932]
@@ -157,25 +162,26 @@ Begin
bool := true xor true; // bool = false
r := 3 / 2; // หารด้วย / จะได้ผลเป็น real เสมอ
- r := int; // เรากำหนดค่า integer ให้ตัวแปร real ได้ แต่ทำกลับกันไม่ได้
+ r := int; // เรากำหนดค่า integer ให้ตัวแปร real ได้
+ // แต่ทำกลับกัน โดยกำหนด real ให้ integer ไม่ได้
c := str[1]; // กำหนดค่าแรกใน array str ให้ตัวแปร c ที่เป็น char
str := 'hello' + 'world'; // เรารวม string เข้าด้วยกันด้วย +
- my_str[0] := 'a'; // กำหนดค่าให้ string เฉพาะตำแหน่งได้แบบตัวแปรอะเรย์ทั่วไป
+ my_str[0] := 'a'; // กำหนดค่าให้ string เฉพาะตำแหน่งแบบอะเรย์ทั่วไป
setlength(my_2d,10,10); // ปรับขนาดอะเรย์ 2 มิติให้เป็นขนาด 10x10
// โดยตัวแปร my_2d นี้สร้างแล้วด้านบน
for c := 0 to 9 do // อะเรย์เริ่มจาก 0 และจบที่ ความยาว-1
- for d := 0 to 9 do // ตัวนับ (counter) จำเป็นต้องประกาศมาก่อนนำมาใช้ตรงนี้
+ for d := 0 to 9 do // ตัวนับ (counter) จำเป็นต้องประกาศก่อนใช้
my_2d[c,d] := c * d;
- // เรากำหนดอะเรย์หลายมิติได้ด้วยการใช้วงเล็บก้ามปู (square brackets) ชุดเดียว
+ // กำหนดอะเรย์หลายมิติ ด้วยการใช้วงเล็บก้ามปู (square brackets)
End.
// จบโปรแกรมบริบูรณ์ ด้วย "."
```
-ด้านล่าง เป็นตัวอย่างการเขียนโปรแกรมปาสกาลชื่อ Functional_Programming
+ด้านล่าง เป็นตัวอย่างการเขียนโปรแกรมปาสกาลชื่อ Functional\_Programming
```pascal
program Functional_Programming;
@@ -200,9 +206,10 @@ Begin
End; // จบ ฟังก์ชั่น ด้วย ";" หลัง End ไม่เหมือนกับจบ โปรแกรม ที่จะใช้ "."
procedure get_integer(var i : integer; dummy : integer);
-{ เรารับ input จากผู้ใช้มาเก็บใน parameter i ที่เป็น integer ที่ตั้งขึ้นในพารามิเตอร์
- โดยใช้ var ประกาศ ทำให้ค่าที่รับเข้ามาจะเปลี่ยนปรับได้จากภายนอกการประกาศพารามิเตอร์นี้
- ส่วน dummy เป็นตัวแปรที่ปรับเปลี่ยนได้ "เฉพาะจากภายในฟังก์ชั่น,โพรซีเยอร์นั้น ๆ }
+{ เรารับ input จากผู้ใช้มาเก็บใน parameter i ที่เป็น integer ที่ตั้งขึ้นใน
+ พารามิเตอร์ โดยใช้ var ประกาศ ทำให้ค่าที่รับเข้ามาจะเปลี่ยนปรับได้จาก
+ ภายนอกการประกาศพารามิเตอร์นี้ ส่วน dummy เป็นตัวแปรที่ปรับเปลี่ยนได้
+ "เฉพาะจากภายในฟังก์ชั่น,โพรซีเยอร์นั้น ๆ }
Begin
write('Enter an integer: ');
readln(i);
@@ -217,11 +224,13 @@ Begin
get_integer(i, dummy);
writeln(i, '! = ', factorial_recursion(i));
// พิมพ์ค่า i!
- writeln('dummy = ', dummy); // จะให้ค่าเป็น '3' เสมอ เพราะจะไม่เปลี่ยนเนื่องด้วย
- // การประกาศพารามิเตอร์ในโพรซีเยอร์ get_integer ด้านบน
+ writeln('dummy = ', dummy); // จะให้ค่าเป็น '3' เสมอ
+ // เพราะจะไม่เปลี่ยนเนื่องด้วย
+ // การประกาศพารามิเตอร์ใน
+ // โพรซีเยอร์ get_integer ด้านบน
End.
```
[1]: https://en.wikipedia.org/wiki/Pascal_(programming_language)
-[2]: https://www.freepascal.org/ \ No newline at end of file
+[2]: https://www.freepascal.org/
diff --git a/tmux.html.markdown b/tmux.html.markdown
index b28a4f59..1c2c2da3 100644
--- a/tmux.html.markdown
+++ b/tmux.html.markdown
@@ -78,7 +78,7 @@ combinations called 'Prefix' keys.
p # Change to the previous window
{ # Swap the current pane with the previous pane
} # Swap the current pane with the next pane
- ] # Enter Copy Mode to copy text or view history.
+ [ # Enter Copy Mode to copy text or view history.
s # Select a new session for the attached client
interactively
diff --git a/toml.html.markdown b/toml.html.markdown
index 814e57e7..385a2437 100755
--- a/toml.html.markdown
+++ b/toml.html.markdown
@@ -32,7 +32,7 @@ boolean = true
dateTime = 1979-05-27T07:32:00-08:00
scientificNotation = 1e+12
"key can be quoted" = true # Both " and ' are fine
-"key may contains" = "letters, numbers, underscores, and dashes"
+"key may contain" = "letters, numbers, underscores, and dashes"
# A bare key must be non-empty, but an empty quoted key is allowed
"" = "blank" # VALID but discouraged
@@ -225,26 +225,26 @@ color = "gray"
# sub-table will belong to the nearest table element above it.
[[fruit]]
- name = "apple"
+ name = "apple" # I am a property in fruit table/map
- [fruit.Geometry]
+ [fruit.geometry]
shape = "round"
- note = "I am an fruit's property"
+ note = "I am a property in geometry table/map"
[[fruit.color]]
name = "red"
- note = "I am an array's item in apple"
+ note = "I am an array item in apple fruit's table/map"
[[fruit.color]]
name = "green"
- note = "I am in the same array than red"
+ note = "I am in the same array as red"
[[fruit]]
name = "banana"
[[fruit.color]]
name = "yellow"
- note = "I am an array's item too but banana's one"
+ note = "I am an array item in banana fruit's table/map"
```
In JSON land, this code will be:
diff --git a/tr-tr/clojure-tr.html.markdown b/tr-tr/clojure-tr.html.markdown
new file mode 100644
index 00000000..64970945
--- /dev/null
+++ b/tr-tr/clojure-tr.html.markdown
@@ -0,0 +1,490 @@
+---
+language: clojure
+lang: tr-tr
+filename: learnclojure-tr.clj
+contributors:
+ - ["Adam Bard", "http://adambard.com/"]
+translators:
+ - ["Seçkin KÜKRER", "https://leavenha.github.io"]
+---
+
+[JVM]: https://tr.wikipedia.org/wiki/Java_sanal_makinesi
+[STM]: https://en.wikipedia.org/wiki/Software_transactional_memory
+
+Clojure, Lisp dialekti, barınan bir dildir. [JVM][JVM] üzerinde barınıyor. Clojure, Lisp'in tüm gücü ve kendi mantalitesi ile mükemmel bir genel-amaçlı programlama dilidir. Clojure, Eş-zamanlı programlama, Makrolar, Fonksiyonel Programlama, Tembel yapılar ve daha fazlasını vaadediyor.
+
+(Bu örnekleri çalıştırmak için Clojure 1.2 versionu veya daha yenisine sahip olmalısınız.)
+
+
+```clojure
+; Noktalı Virgül, satırı yorumlamak için kullanılır.
+
+; Clojure programları formlardan meydana gelir,
+; Parantezlerle çevirili değerler, boşluk ile ayrılır. --Virgül ile değil--
+;
+; Clojure okuyucusu*, listedeki ilk elemanı çağırılacak bir fonksiyon
+; Veya makro, geri kalan ifadeleri o çağırıma argüman olarak kabul eder.
+;
+
+; Bir dosyadaki ilk çağırım isim-uzayı tanımlamak için `ns` olmalı.
+(ns clojure-öğren)
+
+;
+; Bir diğer yorumlama seçeneği de, ifade-içi. Bu diyez (`#`), ve alt çizgi
+; İle başlar ve herhangi bir s-ifade'ye uygulanabilir.
+;
+#_(bu çağırım değerlendirilmeyecektir)
+
+; Öncelikle fonksiyon çağırımları ve temel işlemler:
+
+; Örnek bir fonksiyon çağırımı:
+; (örnek-bir-fonksiyon ilk-argüman ikinci-argüman)
+
+; `str` aldığı argümanları bir karakter katarı olarak geri verir.
+(str "Merhaba" " " "dünya!") ; => "Merhaba dünya!"
+
+; Matematik, oldukça sezgisel ve basit
+(+ 1 1) ; => 2
+(- 2 1) ; => 1
+(* 1 2) ; => 2
+(/ 2 1) ; => 2
+
+; Eşitlik için `=`
+(= 1 1) ; => true
+(= 2 1) ; => false
+
+; `not` beklediğiniz gibi, mantıksal ifadeleri tersine çevirir.
+(not true) ; => false
+
+; Clojure formları, iç-içe çağırılabilir
+; Değerlendirilen çağırımlar bir üst form'a argüman
+; Olarak verilir.
+(+ 1 (- 3 2)) ; = 1 + (3 - 2) => 2
+
+; Tipler
+;;;;;;;;;;;;;
+
+; Clojure, Java'nın temel tipleri olan mantıksal (boolean),
+; Tam sayılar (int) ve karakter katarlarını (string) kullanır.
+; Değerleri denetlemek için `class` fonksiyonunu kullanın.
+(class 1) ; Tam sayı sabitleri ön-tanımlı olarak `java.lang.Long` ile tanımlanır.
+(class 1.); Kayan noktalı sayı sabitleri
+; Ön-tanımlı olarak `java.lang.Double` ile tanımlanır.
+(class ""); Karakter katarı sabitleri her zaman, --sadece-- çift tırnak
+; ile tanımlanır ve ön-tanımlı olarak `java.lang.String` tipindedir.
+(class false) ; Mantıksal değer sabitleri, `java.lang.Boolean`.
+(class nil); "Null", (tanımsız) değerler `nil` ile tanımlanır.
+
+; Clojure okuyucusu her paranter ifadesini bir çağırım olarak
+; değerlendirdiğinden bir liste tanımlamak için çağırımı durdurmalıyız.
+'(+ 1 2) ; => (+ 1 2)
+; ((quote (+ 1 2)) için bir kısa yoldur)
+
+; Alıntılanmış listeleri çağırabilirsiniz.
+(eval '(+ 1 2)) ; => 3
+
+; Koleksiyonlar ve Ardışıklar
+;;;;;;;;;;;;;;;;;;;
+
+; Listeler bağlı-liste veri yapısı,
+; Vektörler dizi altyapısı kullanır.
+(class '(1 2 3)); => clojure.lang.PersistentList
+(class [1 2 3]); => clojure.lang.PersistentVector
+
+; Bir liste `(1 2 3)` şeklinde gösterilebilir, yazılabilir.
+; Fakat bu listeyi, Alıntılamalıyız --Quote--.
+; Bu, onu bir fonksiyon çağırımı olarak değil,
+; bir liste olarak değerlendirilmesini sağlayacaktır.
+; Ayrıca, `(list 1 2 3)` tamamen `'(1 2 3)` ifadesi ile
+; eşdeğerdir.
+
+; 'Koleksiyonlar' sadece bir veri grubudur.
+; Vektörler ve Listeler, koleksiyondur:
+(coll? '(1 2 3)) ; => true
+(coll? [1 2 3]) ; => true
+
+; 'Ardışıklar' (seqs), bir veri listesinin soyut tanımlamasıdır.
+; Sadece listeler ardışıktır.
+(seq? '(1 2 3)) ; => true
+(seq? [1 2 3]) ; => false
+
+; Bir ardışık, ulaşıldığında sadece giriş verisi vermelidir.
+; Yani, ardışıklar tembel olabilir. | Sonsuz ardışıklar tanımlanabilir.
+(range 4) ; => (0 1 2 3)
+(range) ; => (0 1 2 3 4 ...) (sonsuz bir ardışık)
+(take 4 (range)) ; (0 1 2 3)
+
+; Bu yapılarda ekleme işlemi için `cons` kullanılır.
+(cons 4 [1 2 3]) ; => (4 1 2 3)
+(cons 4 '(1 2 3)) ; => (4 1 2 3)
+
+; `conj` bir koleksiyona en verimli şekilde veri ekler.
+; Bu, listeler için liste başına, vektörler için ise vektör sonuna demektir.
+(conj [1 2 3] 4) ; => [1 2 3 4]
+(conj '(1 2 3) 4) ; => (4 1 2 3)
+
+; `concat` koleksiyonları birleştirmek için kullanılır.
+(concat [1 2] '(3 4)) ; => (1 2 3 4)
+
+; `filter` ve `map` koleksiyonlarla işlem yapmak için
+; ön-tanımlı yüksek-seviyeli fonksiyonlardır.
+;
+; ps: `inc` argümanını bir arttıran bir fonksiyon.
+(map inc [1 2 3]) ; => (2 3 4)
+(filter even? [1 2 3]) ; => (2)
+
+; Koleksiyonları indirgemek için `reduce` kullanılır.
+(reduce + [1 2 3 4])
+; = (+ (+ (+ 1 2) 3) 4)
+; => 10
+
+; Reduce, bir ilk-tanım değeri alabilir.
+(reduce conj [] '(3 2 1))
+; = (conj (conj (conj [] 3) 2) 1)
+; => [3 2 1]
+
+; Fonksiyonlar
+;;;;;;;;;;;;;;;;;;;;;
+
+; Yeni bir fonksiyon oluşturmak için `fn` kullanın.
+; Bir fonksiyon her zaman son ifadesini döndürür.
+(fn [] "Merhaba Dünya!") ; => fn
+
+; Fonksiyonu çağırmak için bir çift paranteze daha ihtiyaç var.
+((fn [] "Merhaba Dünya!")) ; => "Merhaba Dünya!"
+
+; İsim uzayında bir değişken tanımlamak için `def`
+; kullanılır.
+(def x 1)
+x ; => 1
+
+; Bir değişkene fonksiyon değeri atamak için,
+(def merhaba-dünya (fn [] "Merhaba Dünya!"))
+(merhaba-dünya) ; => "Merhaba Dünya!"
+
+; Bu süreci, `defn` ile kısaltabiliriz.
+(defn hello-world [] "Merhaba Dünya!")
+
+; `defn` fonksiyon çağırımındaki üçüncü eleman
+; --vektör-- bir argüman listesidir. Fonksiyonun alacağı
+; argümanları tanımlar.
+(defn merhaba [isim]
+ (str "Merhaba " isim))
+(merhaba "Dünya!") ; => "Merhaba Dünya!"
+
+; Ayrıca, `#()` kısa yolunu, fonksiyon deklare etmek için
+; kullanabiliriz.
+(def merhaba2 #(str "Merhaba " %1))
+(merhaba2 "Dünya!") ; => "Merhaba Dünya!"
+
+; Çok düzeyli fonksiyonlar da tanımlanabilir,
+(defn merhaba3
+ ([] "Merhaba Dünya!")
+ ([isim] (str "Merhaba " isim)))
+(merhaba3) ; => "Merhaba Dünya!"
+(merhaba3 "A. NESİN!") ; => "Hello A. NESİN!"
+
+; Fonksiyonlar, belirsiz-sayıda argüman alabilir,
+; ve bunları sizin için bir ardışıkta depolayabilir.
+(defn argüman-sayısı [& argümanlarım]
+ (str "Verilen argüman sayısı:" (count argümanlarım) ", argümanlar: " argümanlarım))
+(argüman-sayısı "Öğün" "Çalış" "Güven")
+; => "Verilen argüman sayısı:3, argümanlar: ("Öğün" "Çalış" "Güven")"
+
+; Elbette, sıradan ve belirsiz-sayılı fonksiyon argümanlarını
+; harmanlayabilirsiniz.
+(defn merhabalar [ev-sahibi & misafirler]
+ (str "Merhabalar, " misafirler ". Benim adım " ev-sahibi "."))
+(merhabalar "İklim" "Ayşe" "Fatma" "Nurdan")
+; => "Merhabalar, (\"Ayşe\" \"Fatma\" \"Nurdan\"). Benim adım İklim."
+
+
+; Eşlemeler
+;;;;;;;;;;
+
+; Hash-Maps, Array-Maps
+; Hash-Eşlemeleri ve Dizi-Eşlemeleri bir arayüzü paylaşırlar.
+; Hash-Eşlemeleri daha hızlıdır, fakat anahtar sıralaması tutmazlar.
+(class {:a 1 :b 2 :c 3}) ; => clojure.lang.PersistentArrayMap
+(class (hash-map :a 1 :b 2 :c 3)) ; => clojure.lang.PersistentHashMap
+
+; Dizi-Eşlemeleri bir çok işlem sırasında otomatik olarak Hash-Eşlemelerine
+; dönüşürler. Eğer yeterince büyürlerse, endişelenmenize gerek yoktur.
+
+; Eşlemeler anahtar değeri olarak herhangi hash-ifadesi (hashable)
+; alabilirler. Ama çoğunlukla, bu iş için anahtar-kelimeler `keyword`
+; kullanılır.
+; Anahtar-kelimeler, karakter katarları gibidirler, fakat
+; bir kaç artıları vardır.
+(class :a) ; => clojure.lang.Keyword
+
+(def karakterkatarı-eşlemesi {"a" 1, "b" 2, "c" 3})
+karakterkatarı-eşlemesi ; => {"a" 1, "b" 2, "c" 3}
+
+(def anahtar-eşlemesi {:a 1, :b 2, :c 3})
+anahtar-eşlemesi ; => {:a 1, :c 3, :b 2}
+
+; Bu arada, virgüller her zaman boşluk olarak değerlendirilir
+; ve etkisizdirler.
+
+; Bir eşlemeleden fonksiyon notasyonu ile değer çağırmak,
+(karakterkatarı-eşlemesi "a") ; => 1
+(anahtar-eşlemesi :a) ; => 1
+
+; Keyword tipleri kendi değerlerini argüman olarak aldıkları bir
+; eşlemeden değer notasyonu ile çağırabilirler.
+(:b anahtar-eşlemesi) ; => 2
+
+; Bu notasyonu, bir karakter katarı ile denemeyiniz.
+;("a" karakterkatarı-eşlemesi)
+; => Exception: java.lang.String cannot be cast to clojure.lang.IFn
+
+; Verilmemiş bir değeri çağırmak, `nil` döndürecektir.
+(karakterkatarı-eşlemesi "d") ; => nil
+
+; Eşlemelere yeni değerler eklemek için `assoc` kullanırız.
+(def yeni-anahtar-eşlemesi (assoc anahtar-eşlemesi :d 4))
+yeni-anahtar-eşlemesi ; => {:a 1, :b 2, :c 3, :d 4}
+
+; Ama unutmayın, Clojure veri yapıları değişmezdir!
+anahtar-eşlemesi ; => {:a 1, :b 2, :c 3}
+
+; Değer silmek için ise `dissoc` kullanılır.
+(dissoc anahtar-eşlemesi :a :b) ; => {:c 3}
+
+; Kümeler
+;;;;;;
+
+(class #{1 2 3}) ; => clojure.lang.PersistentHashSet
+(set [1 2 3 1 2 3 3 2 1 3 2 1]) ; => #{1 2 3}
+
+; `conj` ile bir değer eklenir.
+(conj #{1 2 3} 4) ; => #{1 2 3 4}
+
+; `disj` ile değer çıkarılır.
+(disj #{1 2 3} 1) ; => #{2 3}
+
+; Fonksiyon notasyonu kümelerde de tanımlıdır.
+; Kendi içlerinde değer arayan bir fonksiyon olarak
+; kullanılabilirler.
+(#{1 2 3} 1) ; => 1
+(#{1 2 3} 4) ; => nil
+
+; `clojure.sets` isim-uzayında daha fazla fonksiyon vardır.
+
+; Kullanışlı Formlar
+;;;;;;;;;;;;;;;;;
+
+; Clojure için mantıksal yapılar bir özel-form'dur.
+; Ve diğer fonksiyonlar gibi kullanılabilir.
+; `if` fonksiyonunun ilk argümanı bir test ifadesidir.
+(if true "ya şundadır" "ya bunda") ; => "ya şundadır"
+; İkinci ifade doğru, üçüncü ifade ise yanlışsa ifadeleridir.
+; Eğer test terimi doğru olarak değerlendirilirse,
+; doğru ifadesi, yanlışsa yanlış ifadesi değerlendirilir ve döndürülür.
+;
+; Bir yanlışsa ifadesi yoksa `nil` döndürülür.
+(if false "a") ; => nil
+
+; Yerel geçici-değişken tanımlamak için `let` kullanılır.
+; İfadelerin varlığı `let` çağırımı ile sınırlıdır.
+(let [a 1 b 2]
+ (> a b)) ; => false
+
+; İfade ve çağırımları `do` ile gruplayabilirsiniz.
+; Çağırımların sonuncusu `do` ifadesinin değeri olarak
+; döndürülecektir.
+(do
+ (print "Selamlar!")
+ "Dünya!") ; => "Dünya!" (prints "Selamlar!")
+
+; Fonksiyonlar kapalı bir `do` ifadesi ile çevrelenmiştir.
+(defn yazdır-ve-selamla! [isim]
+ (println "Merhaba, " isim "!")
+ (str "Merhaba, " isim "!"))
+(yazdır-ve-selamla! "Zübeyde") ;=> "Merhaba, Zübeyde!" ("Merhaba, Zübeyde!" yazdırır.)
+
+; `let` ifadesi de kapalı bir `do` ile gelmektedir.
+(let [isim "Ayten"]
+ (print "Merhabalar, " isim)
+ (str "Merhabalar, " isim)) ; => "Merhabalar, " ("Merhabalar, Ayten" yazdırır)
+
+; Sıralama-makroları (-> ve ->>) ile veri dönüşümünü daha temiz ifade
+; edebilirsiniz.
+; Bu makrolar ilk argümanı sonraki her çağırımın içine yerleştirir.
+;
+; `->` makrosu, ifadeyi çağırımların ilk argümanı olacak şekilde yerleştirir.
+(->
+ {:a 1 :b 2}
+ (assoc :c 3) ;=> (assoc {:a 1 :b 2} :c 3)
+ (dissoc :b))
+
+; Bu ifade aşağıdaki şekilde yazılabilir:
+; (dissoc (assoc {:a 1 :b 2} :c 3) :b)
+; ve `{:a 1 :c 3}` olarak değer bulur.
+
+; Sondan-Sıralama-Makrosu (->>) ise aynı şeyi yapar,
+; tek fark ise, ifadeyi, çağırımların son argümanı olarak yerleştirir.
+;
+(->>
+ (range 10) ;=> '(0 1 2 3 4 5 6 7 8 9)
+ (map inc) ;=> (map inc (range 10))
+ (filter odd?) ;=> (filter odd? (map inc (range 10)))
+ (into [])) ;=> (into [] (filter odd? (map inc (range 10))))
+ ; Sonuç: [1 3 5 7 9]
+
+; Bir ifadedeki önceki veri dönüşümlerinin sonucunu nereye
+; koyacağınız konusunda daha fazla özgürlük istediğiniz bir durumda,
+; Sıralama-Makrolarından daha özgür bi' şey kullanmak istersiniz;
+; `as->` makrosu ile dönüşümlerin çıktısına bir isim atayabilir
+; ve ardışık çağırımlarda yer tutucu olarak kullanabilirsiniz.
+
+(as-> [1 2 3] girdi
+ (map inc girdi);=> ifadeyi isterseniz çağırımın son argümanı olarak,
+ (nth girdi 2) ;=> veya çağırımın ilk argümanı olarak,
+ (conj [4 5 6] girdi [8 9 10])) ;=> ya da istediğiniz sırada kullanabilirsiniz.
+;=> [4 5 6 4 [8 9 10]]
+
+
+
+; Modüller
+;;;;;;;;;;;;;;;
+
+; `use` çağırdığınız modüldeki tüm tanımlara erişmenize olanak verir.
+(use 'clojure.set)
+
+; Şu anda, küme fonksiyonlarını kullanabiliriz.
+(intersection #{1 2 3} #{2 3 4}) ; => #{2 3}
+(difference #{1 2 3} #{2 3 4}) ; => #{1}
+
+; Ayrıca eklenecek fonksiyonları seçebilirsiniz de:
+(use '[clojure.set :only [intersection]])
+
+; Bir modülü eklemek için `require` kullanılır.
+(require 'clojure.string)
+
+; İsim-uzayı kapsamlı çağırımlar aşağıdaki şekildedir:
+; isim-uzayı/fonksiyon-ismi --isim uzayı ismi ve fonksiyon ismi
+; arasına eğik çizgi koymanız yeterli.
+; Burada, modül `clojure.string` ve fonksiyon ismi `blank?`
+(clojure.string/blank? "") ; => true
+
+; Ekleme sırasında, bir modüle takma-ad verilebilir.
+(require '[clojure.string :as str])
+(str/replace "Bu bir özet metindir, test için kullanılabilir!"
+ #"[aeıioöuü]" str/upper-case)
+; => "BU bIr ÖzEt mEtIndIr, tEst IçIn kUllAnIlAbIlIr!"
+; (#"", burada düzenli ifadeler için bir sözdizimsel-şekerlemeyi ifade eder)
+
+; Bir isim-uzayı tanımlamasında `require` kullanılabilir.
+; `ns` bir makrodur ve `require` (ve `use`, ama lütfen kullanmayın)
+; dahil olmak üzere bir çok çağırım için işlevsellik sağlamaktadır.
+; Bu notasyonu kullanırsanız, modüllerinizi alıntılamak zorunda kalmazsınız.
+(ns test
+ (:require
+ [clojure.string :as str]
+ [clojure.set :as set]))
+
+
+; Java
+;;;;;;;;;;;;;;;;;
+
+; Java, kocaman ve kullanışlı bir standart kütüphaneye sahip,
+; Clojure, Java etkileşimi ile, bundan yararlanabilirsiniz.
+
+; `import` diğer modüller gibi, bir java modülü de ele alabilir.
+; Date, bir Java modülü.
+(import java.util.Date)
+
+; `ns` çağırımında da kullanabilirsiniz.
+(ns test
+ (:import java.util.Date
+ java.util.Calendar))
+
+; Bir Java nesnesinden oluşturmak için `new` çağırımını kullanabilirsiniz.
+(new Date)
+
+; Ayrıca Clojure Okuyucusu, size bunun daha farklı bir yolunu sunar:
+; Sınıf isminin sonuna koyulacak bir nokta `.` ile
+; bu yapılabilir.
+(Date.) ; <bir tarih nesnesi>
+
+; `.` --nokta-- çağırımı, size nesnelerdeki metotlara erişme imkanı verir.
+(. (new Date) getTime) ; <bir zaman-damgası>
+(.getTime (Date.)) ; Üstteki ifade ile tamamen aynı sonucu verir.
+
+; Sınıf içindeki statik metotlara erişmek için `/` ayracını
+; sınıf ile metot ismi birleştirmek için kullanabilirsiniz.
+; (örnekSınıf/statikMetot)
+(System/currentTimeMillis) ; <bir zaman-damgası> (`system` her zaman sunulur)
+
+; Sınıflarla işlem yaparken, `doto` bu süreci kolaylaştırabilir.
+; İlk argüman sınıf nesnesi, sonraki her çağırım, nesne üzerinde yapılır.
+(import java.util.Calendar)
+(doto (Calendar/getInstance)
+ (.set 2000 1 1 0 0 0) ; => `set` metodu, `doto` ifadesine verilen
+ ; sınıf nesnesi üzerinde çağırılır.
+ .getTime) ; => Bir tarih nesnesi. set to 2000-01-01 00:00:00
+
+
+; STM
+;;;;;;;;;;;;;;;;;
+
+; 'Software Transactional Memory' Clojure'un değişmez veri yapılarını
+; ele alırken kullandığı bir mekanizmadır. Clojure içinde bunu kullanan
+; birkaç yapı vardır.
+
+; Bir `atom` en basitidir. Bir ilkleme-değeri verin.
+(def benim-atomum (atom {}))
+
+; Bir atomu güncellemek için `swap!` kullanılır.
+; `swap!` fonksiyonu, ilk argüman olarak aldığı atomu, ikinci argüman
+; olarak aldığı fonksiyona uygular. Bu fonksiyona ek argümanlar ise
+; fonksiyondan sonra gelirler.
+(swap! benim-atomum assoc :a 1)
+; benim-atomum'un değerini (assoc {} :a 1) ifadesinin sonucu ile değiştirir.
+(swap! benim-atomum assoc :b 2)
+; benim-atomum'un değerini (assoc {:a 1} :b 2) ifadesinin sonucu ile değiştirir.
+
+; `deref` ile, atomun değerini çözümleyebilirsiniz.
+benim-atomum ;=> Atom<#...> (Atom ifadesi döndürür)
+@benim-atomum ; => {:a 1 :b 2}
+
+; İşte, `atom` kullanan basit bir sayaç.
+(def sayaç (atom 0)) ;=> Şu anki isim uzayına, `sayaç` ile, 0 başlangıç
+; değeri ile bir atom tanımladık.
+(defn sayaç-arttır [benim-atomum]
+ (swap! sayaç inc)) ;=> Atom'un değerini bir arttır.
+
+(sayaç-arttır sayaç)
+(sayaç-arttır sayaç)
+(sayaç-arttır sayaç)
+(sayaç-arttır sayaç)
+(sayaç-arttır sayaç)
+(sayaç-arttır sayaç)
+
+@sayaç ; => 6
+
+; Diğer STM yapıları `ref`'ler ve `agent`'lar.
+; Ref'ler: http://clojure.org/refs
+; Agent'lar: http://clojure.org/agents
+```
+
+### Çevirim-içi içerikler
+
+Bu içerik, Rich Hickey'nin derin yazılım geliştirme anlayışına ve John McCarthy'nin vizyonu olan Lisp'in, Clojure'a miras verdiklerini anlamak için elbette yeterli değildir. Fakat fonksiyonel paradigma ve bu paradigmanın modern bir Lisp lehçesinde kullanımına göz kırpmış oldunuz.
+
+Clojure.org, bir çok içerik ve makale var. (İngilizce içerik):
+[http://clojure.org/](http://clojure.org/)
+
+Clojuredocs.org, örneklerle bezenmiş Clojure dökümantasyonu:
+[http://clojuredocs.org/quickref/Clojure%20Core](http://clojuredocs.org/quickref/Clojure%20Core)
+
+4Clojure, interaktif bir şekilde FP ve Clojure yeteneklerinizi geliştirmenize olanak veriyor:
+[http://www.4clojure.com/](http://www.4clojure.com/)
+
+Clojure-doc.org, Başlangıç için bir içeriklere sahip:
+[http://clojure-doc.org/](http://clojure-doc.org/)
+
+BraveClojure, bir başka clojure öğreten web sitesi:
+[https://www.braveclojure.com/](https://www.braveclojure.com/)
diff --git a/tr-tr/html-tr.html.markdown b/tr-tr/html-tr.html.markdown
new file mode 100644
index 00000000..b4afe7df
--- /dev/null
+++ b/tr-tr/html-tr.html.markdown
@@ -0,0 +1,157 @@
+---
+language: html
+filename: learnhtml-tr.txt
+contributors:
+ - ["Christophe THOMAS", "https://github.com/WinChris"]
+translators:
+ - ["Kemal MUTLU", "https://github.com/kemtake"]
+ - ["Nuri Akman", "https://github.com/vedia"]
+lang: tr-tr
+---
+
+HTML, HyperText Markup Language (Hiper Metin İşaretleme Dili) anlamına gelir.
+
+Web sayfaları yazmamızı sağlayan bir dildir. Bu işaretleme dili, metin ve verilerin nasıl gösterilmesi gerektiği kodlanarak web sayfaları yazmamızı sağlar. Aslında, html dosyaları basit metin dosyalarıdır.
+
+Bu işaretleme nedir? Sayfanın verilerini, açılış etiketleri ve kapanış etiketleri ile çevreleyerek düzenleme yöntemidir. Bu işaretleme, içerdiği metne anlam vermeyi sağlar. Diğer bilgisayar dillerinde olduğu gibi, HTML’nin birçok sürümü vardır. Burada HTML5 hakkında konuşacağız.
+
+**NOT :** Etkilerin nasıl çalıştıklarını anlamak, çıktılarını görebilmek için [codepen](https://codepen.io/) gibi bir siteden de faydalanabilirsiniz. Bu makale temel olarak HTML sözdizimi ve bazı yararlı ipuçlarıyla ilgilidir.
+
+```html
+<!-- Yorumlar bu satır gibi eklenir! -->
+
+<!--
+ Yorumlar
+ birden
+ fazla
+ satıra
+ yayılabilir!
+-->
+
+<!-- #################### Başlık #################### -->
+
+<!-- İşte, analiz edeceğimiz örnek bir HTML dosyası. -->
+
+
+<!doctype html>
+ <html>
+ <head>
+ <title>Benim Sitem</title>
+ </head>
+ <body>
+ <h1>Merhaba dünya!</h1>
+ <a href="http://codepen.io/anon/pen/xwjLbZ">
+ Bunun ne olduğuna bir bak.
+ </a>
+ <p>Bu bir paragraftır.</p>
+ <p>Bu başka bir paragraf.</p>
+ <ul>
+ <li>Bu, numaralandırılmamış bir listede bulunan bir öğe/maddedir (madde imi)</li>
+ <li>Bu başka bir öğe</li>
+ <li>Ve bu listedeki son öğe </li>
+ </ul>
+ </body>
+ </html>
+
+<!--
+Bir HTML dosyası, tarayıcıya her zaman sayfanın HTML olduğunu belirterek başlar.
+-->
+<!doctype html>
+
+<!-- Bundan sonra, bir <html> etiketi açılarak başlar. -->
+<html>
+
+<!-- dosyanın sonu </html> etiketi ile kapatılır. -->
+</html>
+
+<!-- Sayfada, bu son etiketten sonra hiçbir şey bulunmamalıdır. -->
+
+<!-- Açılış ve kapanış etiketleri arasında (<html> </html>) şunları bulunur: -->
+
+<!-- <head> ile tanımlanan bir sayfa başlığu (bu, </head> ile kapatılmalıdır). -->
+<!-- Baslik, gösterilmeyen bazi aciklamalar ve ek bilgiler icerir; buna üstveri denir. -->
+
+<head>
+ <!-- <title> etiketi, tarayıcıda gösterilecek başlığı gösterir. Pencerenin başlık çubuğu ve sekme adı.-->
+ <title>Benim Sitem</title>
+</head>
+
+<!-- <head> bölümünden sonra, <body> etiketi gelir. -->
+<!-- Bu noktaya kadar, tarif edilen hiçbir şey tarayıcı penceresinde görünmez. -->
+<!-- <body> etiketinden sonra görüntülenecek içeriğe yer verilir. -->
+
+<body>
+ <!-- h1 etiketi bir başlık oluşturur. -->
+ <h1>Merhaba Dünya!</h1>
+ <!--
+ Ayrıca başlıklar <h1> etiketinden <h6> etiketine kadar gidebilir.
+ <h1> etiketi en önemli, <h6> etiketi en düşük öncelikli başlığı yazmamızı sağlar.
+ -->
+
+ <!-- href="" özniteliğine verilen URL'ye bir köprü oluşturur. -->
+ <a href="http://codepen.io/anon/pen/xwjLbZ">
+ Bunun ne olduğuna bir bak.
+ </a>
+
+ <!-- <p> etiketi, html sayfasına metin eklememize izin verir. -->
+ <p>Bu bir paragraftır.</p>
+ <p>Bu başka bir paragraf.</p>
+
+ <!-- <ul> etiketi bir madde imi listesi oluşturur. -->
+ <!--
+ Numaralandırılmış bir listeye sahip olmak için <ol> etiketi de kullanılabilir. Bu durumda 1. madde 2. madde vb. şekilde gider.
+ -->
+ <ul>
+ <li>Bu, numaralandırılmamış bir bir liste kalemidir (madde imi)</li>
+ <li>Bu başka bir öğe</li>
+ <li>Ve bu listedeki son öğe</li>
+ </ul>
+</body>
+
+<!-- İşte bir html dosyası oluşturmak bu kadar basit. -->
+
+<!-- Ancak birçok farklı HTML etiketi türü de eklenebilir. -->
+
+<!-- <img /> etiketi bir resim eklemek için kullanılır. -->
+<!--
+Resmin kaynağı, src = "" özniteliği kullanılarak belirtilir.
+Kaynak, bir URL veya bilgisayarınızdaki bir dosyanın yolu olabilir.
+-->
+<img src="http://i.imgur.com/XWG0O.gif"/>
+
+<!-- HTML'de bir Tablo oluşturmak da mümkündür. -->
+
+<!-- Bir <table> elemanı açarız. -->
+<table>
+
+ <!-- <tr> bir satır oluşturmamızı sağlar. -->
+ <tr>
+ <!-- <th> tablo sütununa bir başlık vermemize izin verir. -->
+ <th>Birinci Başlık</th>
+ <th>İkinci Başlık</th>
+ </tr>
+
+ <tr>
+ <!-- <td> bir tablo hücresi oluşturmamızı sağlar. -->
+ <td>ilk satırın, ilk hücresi (sutunu)</td>
+ <td>ilk satırın, ikinci hücresi (sutunu)</td>
+ </tr>
+
+ <tr>
+ <td>ikinci satırın, ilk hücresi (sutunu) </td>
+ <td>ikinci satırın, ikinci hücresi (sutunu)</td>
+ </tr>
+</table>
+
+```
+
+## Kullanım
+
+HTML içeriği, .html veya .htm ile biten dosyalara yazılır. Mim türü text/html .
+HTML olarak yazılmış dosyalar, `.html` veya `.htm` dosya uzantısına sahiptirler. mime type'ı ise `text/html` dir.
+
+## Daha fazla bilgi için
+
+* [wikipedia](https://en.wikipedia.org/wiki/HTML)
+* [HTML tutorial](https://developer.mozilla.org/en-US/docs/Web/HTML)
+* [W3School](http://www.w3schools.com/html/html_intro.asp)
diff --git a/tr-tr/python-tr.html.markdown b/tr-tr/python-tr.html.markdown
index 01285080..99a3eb4e 100644
--- a/tr-tr/python-tr.html.markdown
+++ b/tr-tr/python-tr.html.markdown
@@ -458,7 +458,7 @@ Human.grunt() #=> "*grunt*"
# Modülleri sayfaya dahil edebilirsiniz
import math
-print math.sqrt(16) #=> 4
+print math.sqrt(16) #=> 4.0
# Modül içerisinden spesifik bir fonksiyonu getirebilirsiniz
from math import ceil, floor
diff --git a/typescript.html.markdown b/typescript.html.markdown
index 6feaca45..cf2111d5 100644
--- a/typescript.html.markdown
+++ b/typescript.html.markdown
@@ -203,8 +203,8 @@ p1.age = 25; // Error, p1.x is read-only
var p2 = { name: "John", age: 60 };
var p3: Person = p2; // Ok, read-only alias for p2
-p3.x = 35; // Error, p3.x is read-only
-p2.x = 45; // Ok, but also changes p3.x because of aliasing
+p3.age = 35; // Error, p3.age is read-only
+p2.age = 45; // Ok, but also changes p3.age because of aliasing
class Car {
readonly make: string;
@@ -223,6 +223,43 @@ moreNumbers[5] = 5; // Error, elements are read-only
moreNumbers.push(5); // Error, no push method (because it mutates array)
moreNumbers.length = 3; // Error, length is read-only
numbers = moreNumbers; // Error, mutating methods are missing
+
+// Tagged Union Types for modelling state that can be in one of many shapes
+type State =
+ | { type: "loading" }
+ | { type: "success", value: number }
+ | { type: "error", message: string };
+
+declare const state: State;
+if (state.type === "success") {
+ console.log(state.value);
+} else if (state.type === "error") {
+ console.error(state.message);
+}
+
+// Iterators and Generators
+
+// for..of statement
+// iterate over the list of values on the object being iterated
+let arrayOfAnyType = [1, "string", false];
+for (const val of arrayOfAnyType) {
+ console.log(val); // 1, "string", false
+}
+
+let list = [4, 5, 6];
+for (const i of list) {
+ console.log(i); // 4, 5, 6
+}
+
+// for..in statement
+// iterate over the list of keys on the object being iterated
+for (const i in list) {
+ console.log(i); // 0, 1, 2
+}
+
+
+
+
```
## Further Reading
diff --git a/uk-ua/python-ua.html.markdown b/uk-ua/python-ua.html.markdown
index 2406678d..23bc1796 100644
--- a/uk-ua/python-ua.html.markdown
+++ b/uk-ua/python-ua.html.markdown
@@ -654,7 +654,7 @@ i.age # => виникає помилка атрибуту
# Ви можете імпортувати модулі
import math
-print(math.sqrt(16)) # => 4
+print(math.sqrt(16)) # => 4.0
# Ви можете імпортувати окремі функції з модуля
from math import ceil, floor
diff --git a/vim.html.markdown b/vim.html.markdown
index 0eb2c37e..5b84a3ea 100644
--- a/vim.html.markdown
+++ b/vim.html.markdown
@@ -94,10 +94,10 @@ that aims to make getting started with vim more approachable!
Vim is based on the concept on **modes**.
-Command Mode - vim starts up in this mode, used to navigate and write commands
-Insert Mode - used to make changes in your file
-Visual Mode - used to highlight text and do operations to them
-Ex Mode - used to drop down to the bottom with the ':' prompt to enter commands
+- Command Mode - vim starts up in this mode, used to navigate and write commands
+- Insert Mode - used to make changes in your file
+- Visual Mode - used to highlight text and do operations to them
+- Ex Mode - used to drop down to the bottom with the ':' prompt to enter commands
```
i # Puts vim into insert mode, before the cursor position
@@ -122,9 +122,9 @@ Ex Mode - used to drop down to the bottom with the ':' prompt to enter comm
Vim can be thought of as a set of commands in a
'Verb-Modifier-Noun' format, where:
-Verb - your action
-Modifier - how you're doing your action
-Noun - the object on which your action acts on
+- Verb - your action
+- Modifier - how you're doing your action
+- Noun - the object on which your action acts on
A few important examples of 'Verbs', 'Modifiers', and 'Nouns':
diff --git a/visualbasic.html.markdown b/visualbasic.html.markdown
index 63f224b7..221c1eb3 100644
--- a/visualbasic.html.markdown
+++ b/visualbasic.html.markdown
@@ -139,7 +139,7 @@ Module Module1
'Five
Private Sub WorkingCalculator()
- Console.Title = "The Working Calculator| Learn X in Y Minutes"
+ Console.Title = "The Working Calculator | Learn X in Y Minutes"
'However if you'd like the calculator to subtract, divide, multiple and
'add up.
'Copy and paste the above again.
diff --git a/vyper.html.markdown b/vyper.html.markdown
new file mode 100644
index 00000000..fec1a79f
--- /dev/null
+++ b/vyper.html.markdown
@@ -0,0 +1,872 @@
+---
+language: Vyper
+filename: learnVyper.vy
+contributors:
+ - ["Kenny Peluso", "kennyp.herokuapp.com"]
+---
+
+> The content of this document is largely inspired by ["Learn Solidity in Y Minutes"](https:#github.com/adambard/learnxinyminutes-docs/blob/master/solidity.html.markdown)
+
+Vyper lets you program on [Ethereum](https:#www.ethereum.org/), a
+blockchain-based virtual machine that allows the creation and
+execution of smart contracts, without requiring centralized or trusted parties. It was
+designed to improve upon Solidity, another smart contract language for Ethereum, by
+limiting unsafe practices and enhancing readability; Vyper seeks to optimize the
+security and auditability of smart contracts.
+
+Vyper is an experimental, statically typed, contract programming language meant to
+resemble Python. Like objects in OOP, each contract contains state variables, functions,
+and common data types. Contract-specific features include event notifiers for listeners,
+and custom global variables, global constants.
+
+Some Ethereum contract examples include crowdfunding, voting, and blind auctions.
+
+---
+
+## Table of Contents
+
+- Intro
+- Example
+1. Data types and associated methods
+2. Data structures
+3. Simple operators
+4. Global variables of note
+5. Functions and more
+ a. functions
+ b. events
+6. Branching and loops
+7. Objects/contracts
+ a. calling external contracts
+ b. ERC20 built-in
+ c. following an interface
+8. Other keywords
+ a. selfdestruct
+9. Contract design notes
+ a. obfuscation
+ b. storage optimization
+ c. data access in blockchain
+ d. cron job
+ e. observer pattern
+10. Security
+11. Style notes
+12. Natspec comments
+- Other documents
+
+---
+
+## Intro
+
+From [the docs](https://media.readthedocs.org/pdf/vyper/latest/vyper.pdf)
+the foundational tenants of Vyper are:
+
+1. *Security*
+2. *Language and compiler simplicity*
+3. *Auditability*
+
+This allows for the following features:
+
+1. *Bounds and overflow checking*
+ - On the arithmetic and array level
+ - There are no dynamic arrays in Vyper
+2. *Support for signed integers and decimal fixed point numbers*
+3. *Decidability* - You can always compute precise upper bound on gas cost
+4. *Strong typing* - for built-in and custom types
+5. *Small and understandable compiler code*
+6. *Limited support for pure functions*
+ - Anything marked `@constant` is not allowed to change the state
+
+Following the principles and goals, Vyper does not provide the following features:
+
+1. *Modifiers* (defining parts of functions elsewhere)
+2. *Class inheritance*
+3. *Inline assembly*
+4. *Function overloading*
+5. *Operator overloading*
+6. *Recursive calling*
+7. *Infinite-length loops*
+8. *Binary fixed point* (decimal fixed point is used for its exactness)
+
+WITH THE RAPID CHANGES IN ETHEREUM, THIS DOCUMENT IS UNLIKELY TO STAY UP TO
+DATE, SO YOU SHOULD FOLLOW THE LATEST VYPER DOCS AND ETHEREUM BLOG FOR THE LATEST.
+ALL CODE HERE IS PROVIDED AS IS, WITH SUBSTANTIAL RISK OF ERRORS OR DEPRECATED CODE
+PATTERNS.
+
+This document primarily discusses syntax, and so excludes many
+popular design patterns.
+
+As Vyper and Ethereum are under active development, experimental or beta
+features are typically marked, and subject to change. Pull requests welcome.
+
+This document describes Vyper version `0.1.0-beta.8`.
+
+*All of the following code exists for educational purposes only!*
+*None of the following code should be used in production as-is!*
+
+## Example
+
+```python
+# First, a simple todo list contract
+# Implements CRUD operations for tasks
+
+# todo.vy (note .vy extension)
+### **** START EXAMPLE **** ###
+
+# Start with Natspec comment
+# used for documentation
+
+# @title SimpleBank v1
+# @author kennyp
+# @notice This is a simple bank.
+
+# Vyper contracts must obey a particular order:
+# struct -> interface -> events -> globals and constants -> functions
+# Additionally, like Python, Vyper functions must be defined in the file
+# before they're called.
+
+# Structs
+
+struct Task:
+ done: bool
+ deleted: bool
+ task: string[100]
+ metadata: bytes32
+
+# Interfaces
+
+contract AnotherContract():
+ def fetch() -> bytes32: constant
+ def inform(_taskId: uint256, _status: uint256) -> bool: modifying
+
+# Events
+
+# Events - publicize actions to external listeners
+# `indexed` means that it's easier to search/filter on this field
+TaskStatus: event({_taskId: indexed(uint256), _status: uint256})
+
+# Global Variables
+
+# State variables are values which are permanently stored in contract storage
+# State vars consist of any value persisting beyond any function's scope
+# and are permanently stored in contract storage
+
+# You can define your own, custom, unmutable constants
+CREATED: constant(uint256) = 0
+COMPLETED: constant(uint256) = 1
+DELETED: constant(uint256) = 2
+
+# The `public` built-in allows for this address to be read externally
+# without defining a `get()` constant function
+owner: public(address)
+other: public(address)
+
+# uint256 means "unsigned positive integer between 0 and 2^256 - 1"
+# Overflow protection is built-in to Vyper
+taskCount: uint256
+tasks: map(uint256, Task) # dictionary: key=uint256, value: Task struct
+
+# Private Functions
+
+# Start each function with Pythonic decorators
+# These decorators resemble Natspec but are actually enforced by Vyper's compiler
+# These decorators are:
+# @public XOR @private (either one or the other)
+# @public (if any contract/user can call it)
+# @private (if only internal functions can call it)
+# @payable (if the function is payable i.e. accepting ETH)
+# @constant (if the function is not modifying anything on-chain)
+@private
+def _changeTaskStatus( \
+ _sender: address, \
+ _taskId: uint256, \
+ _status: uint256, \
+ ):
+ # backslashes (\) allow for multi-line code
+ # Natspec comments are particularly helpful for documentation and readibility
+ # Natspec can be included using familiar Pythonic docstring syntax
+ """
+ @notice
+ @dev `_sender` MUST be `self.owner`
+ @param _sender Who is triggering this function
+ @param _task The description of the task (only useful when task added)
+ """
+ # NOTE: Private functions do not have access to `msg.sender`
+ # SIDE NOTE: `msg.sender` refers to whoever immediately called the function of
+ # immediate scope. In other words, if I call a function that calls another
+ # in-contract, public function, then `msg.sender` turns from my address to
+ # the address of the current contract.
+ assert _sender == self.owner # failed assertions cause calls/transactions to fail
+ # Note that unlike Solidity, `self.` is required to query the contract's state
+ # Control flow is Pythonic, as is much of Vyper:
+ _task: string[100] # initialized to default value
+ _data: bytes32 = sha3(convert(_sender, bytes32)) # owner is obfuscated (but still visible in logs)
+ if _status == CREATED: # control flow mimics python
+ # How a new struct is instantiated:
+ self.tasks[_taskId] = Task({ \
+ done: False, deleted: False, task: _task, metadata: _data \
+ })
+ elif _status == COMPLETED:
+ # Modifying an existing struct:
+ self.tasks[_taskId].done = True
+ elif _status == DELETED:
+ self.tasks[_taskId].deleted = True
+ AnotherContract(self.other).inform(_taskId, _status) # modifying external call
+ log.TaskStatus(_taskId, _status) # emit an event
+
+# Public Functions
+
+# Pythonic constructor - can receive none or many arguments
+@public
+def __init__(_owner: address, _other_contract: address):
+ """
+ @dev Called once and only upon contract depoyment
+ """
+ self.owner = _owner
+ self.other = _other_contract
+
+# NOTE: Pythonic whitespace rules are mandated in Vyper
+
+@public
+def addTask(_task: string[100]) -> uint256:
+ """
+ @notice Adds a task to contract
+ @param _task Description of task
+ @return Id of newly minted task
+ """
+ # msg.sender gives the address of who/what contract is calling this function
+ self._changeTaskStatus(msg.sender, self.taskCount, CREATED)
+ self.tasks[self.taskCount].task = _task
+ self.taskCount += 1
+ return self.taskCount - 1
+
+@public
+def addSpecialTask(_task: string[100]) -> uint256:
+ """
+ @notice Adds a task with metadata pulled from elsewhere
+ @param _task Description of task
+ @return Id of newly minted task
+ """
+ self._changeTaskStatus(msg.sender, self.taskCount, CREATED)
+ self.tasks[self.taskCount].task = _task
+ self.tasks[self.taskCount].metadata = AnotherContract(self.other).fetch()
+ self.taskCount += 1
+ return self.taskCount - 1
+
+@public
+def completeTask(_taskId: uint256):
+ """
+ @notice Marks a task as "completed"
+ @param _taskId Id of task to complete
+ """
+ self._changeTaskStatus(msg.sender, _taskId, COMPLETED)
+
+@public
+def deleteTask(_taskId: uint256):
+ """
+ @notice Adds a task to contract
+ @param _taskId Id of task to delete
+ """
+ self._changeTaskStatus(msg.sender, _taskId, DELETED)
+
+@public
+@constant # allows function to run locally/off blockchain
+def getTask(_taskId: uint256) -> string[100]:
+ """
+ @notice Getter for a task's description
+ @param _taskId Id of task with desired description
+ @return Description of task
+ """
+ return self.tasks[_taskId].task
+
+### **** END EXAMPLE **** ###
+
+
+# Now, the basics of Vyper
+
+
+# ---
+
+
+# 1. DATA TYPES AND ASSOCIATED METHODS
+# uint256 used for currency amount and for dates (in unix time)
+x: uint256
+
+# int of 128 bits, cannot be changed after contract deployment
+# with 'constant', compiler replaces each occurrence with actual value
+a: constant(int128) = 5
+
+# All state variables (those outside a function)
+# are by default 'internal' and accessible inside contract
+# Need to explicitly set to 'public' to allow external contracts to access
+# A getter is automatically created, but NOT a setter
+# Can only be called in the contract's scope (not within functions)
+# Add 'public' field to indicate publicly/externally accessible
+a: public(int128)
+
+# No random functions built in, use other contracts for randomness
+
+# Type casting is limited but exists
+b: int128 = 5
+x: uint256 = convert(b, uint256)
+
+# Types of accounts:
+# Contract Account: f(creator_addr, num_transactions)=address set on contract creation
+# External Account: (person/external entity): f(public_key)=address
+
+# Addresses - An address type can hold an Ethereum address which
+# equates to 20 bytes or 160 bits. It returns in hexadecimal notation
+# with a leading 0x. No arithmetic allowed
+owner: public(address)
+
+# Members can be invoked on all addresses:
+owner.balance # returns balance of address as `wei_value`
+owner.codesize # returns code size of address as `int128`
+owner.is_contract # `True` if Contract Account
+
+# All addresses can be sent ether via `send()` built-in
+@public
+@payable
+def sendWei(any_addr: address):
+ send(any_addr, msg.value)
+
+# Bytes available
+a: bytes[2]
+b: bytes[32]
+c: bytes32
+# `b` and `c` are 2 different types
+
+# Bytes are preferable to strings since Vyper currently offers better
+# support for bytes i.e. more built-ins to deal with `bytes32`, `bytes32`
+# can be returned from functions and strings[] can't be, UTF8 (string encoding)
+# uses more storage, etc.
+
+# There are no dynamically sized bytes, similar to how there are no
+# dynamic arrays
+
+# Fixed-size byte arrays (Strings)
+a: string[100]
+b: string[8]
+c: string[108] = concat(a, b) # check the latest docs for more built-ins
+
+# Time
+t1: timedelta
+t2: timestamp
+# Both types are built-in "custom type" variants of `uint256`
+# `timedelta` values can be added but not `timestamp` values
+
+# Money
+m: wei_value
+# Also has the base type `uint256` like `timestamp` and `timedelta`
+# 1 unit of WEI (a small amount of ETH i.e. ether)
+
+# Custom types
+# specify units used in the contract:
+units: {
+ cm: "centimeter",
+ km: "kilometer"
+}
+# usage:
+a: int128(cm)
+b: uint256(km)
+
+# BY DEFAULT: all values are set to 0 on instantiation
+
+# `clear()` can be called on most types
+# Does NOT destroy value, but sets value to 0, the initial value
+
+
+# ---
+
+
+# 2. DATA STRUCTURES
+# Arrays
+bytes32[5] nicknames; # static array
+bytes32[] names; # dynamic array
+uint newLength = names.push("John"); # adding returns new length of the array
+# Length
+names.length; # get length
+names.length = 1; # lengths can be set (for dynamic arrays in storage only)
+
+# Multidimensional Arrays
+# At initialization, array dimensions must be hard-coded or constants
+# Initialize a 10-column by 3-row, multidimensional fixed array
+ls: (uint256[10])[3] # parentheses are optional
+@public
+def setToThree():
+ # Multidimensional Array Access and Write
+ # access indices are reversed
+ # set element in row 2 (3rd row) column 5 (6th column) to 3
+ self.ls[2][5] = 3
+
+# Dictionaries (any simple type to any other type including structs)
+theMap: map(uint256, bytes32)
+theMap[5] = sha3("charles")
+# theMap[255] result is 0, all non-set key values return zeroes
+# To make read public, make a getter that accesses the mapping
+@public
+def getMap(_idx: uint256) -> bytes32:
+ """
+ @notice Get the value of `theMap` at `_idx`
+ """
+ return self.theMap[_idx]
+
+self.getMap(5) # returns sha3("charles") in bytes32
+
+# Nested mappings
+aMap: map(address, map(address, uint256))
+# NOTE: Mappings are only allowed as state variables
+# NOTE: Mappings are not iterable; can only be accessed
+
+# To delete (reset the mapping's value to default at a key)
+clear(balances["John"])
+clear(balances); # sets all elements to 0
+
+# Unlike other languages, CANNOT iterate through all elements in
+# mapping, without knowing source keys - can build data structure
+# on top to do this
+
+# Structs
+struct Struct:
+ owner: address
+ _balance: uint256 # balance is a reserved keyword, is a member for addresses
+
+exampleStuct: Struct
+
+@public
+def foo() -> uint256:
+ self.exampleStuct = Struct({owner: msg.sender, _balance: 5})
+ self.exampleStuct._balance = 10
+ self.exampleStuct._balance = 5 # set to new value
+ clear(self.exampleStuct._balance)
+ clear(self.exampleStuct)
+ return self.exampleStuct._balance
+
+
+# Data locations: Memory vs. storage vs. calldata - all complex types (arrays,
+# structs) have a data location
+# 'memory' does not persist, 'storage' does
+# Default is 'storage' for local and state variables; 'memory' for func params
+# stack holds small local variables
+
+# for most types, can explicitly set which data location to use
+
+
+# ---
+
+
+# 3. SIMPLE OPERATORS
+# Comparisons, bit operators and arithmetic operators are provided
+# exponentiation: **
+# modulo: %
+# maximum: max(x, y)
+# AND: bitwise_and(x, y)
+# bitwise shift: shift(x, _shift)
+# where x,y are uint256
+# _shift is int128
+
+# 4. GLOBAL VARIABLES OF NOTE
+# ** self **
+self # address of contract
+# often used at end of contract life to transfer remaining balance to party:
+self.balance # balance of current contract
+self.someFunction() # calls func externally via call, not via internal jump
+
+# ** msg - Current message received by the contract **
+# Ethereum programmers take NOTE: this `msg` object is smaller than elsewhere
+msg.sender # address of sender
+msg.value # amount of ether provided to this contract in wei, the function should be marked `@payable`
+msg.gas # remaining gas
+
+# ** tx - This transaction **
+# Ethereum programmers take NOTE: this `tx` object is smaller than elsewhere
+tx.origin # address of sender of the transaction
+
+# ** block - Information about current block **
+block.timestamp # time at current block (uses Unix time)
+# Note that `block.timestamp` can be manipulated by miners, so be careful
+block.number # current block number
+block.difficulty # current block difficulty
+
+# ** storage - Persistent storage hash **
+storage['abc'] = 'def'; # maps 256 bit words to 256 bit words
+
+
+# ---
+
+
+# 5. FUNCTIONS AND MORE
+
+# A. FUNCTIONS
+# Simple function
+function increment(uint x) returns (uint) {
+ x += 1;
+ return x;
+}
+
+# Functions can return many arguments
+@public
+@constant
+def increment(x: uint256, y: uint256) -> (uint256, uint256):
+ x += 1
+ y += 1
+ return (x, y)
+
+# Call previous functon
+@public
+@constant
+def willCall() -> (uint256, uint256):
+ return self.increment(1,1)
+
+# One should never have to call a function / hold any logic outside
+# outside the scope of a function in Vyper
+
+# '@constant'
+# indicates that function does not/cannot change persistent vars
+# Constant function execute locally, not on blockchain
+y: uint256
+@public
+@constant
+def increment(x: uint256) -> uint256:
+ x += 1
+ y += 1 # this line would fail
+ # y is a state variable => can't be changed in a constant function
+
+
+# 'Function Decorators'
+# Used like python decorators but are REQUIRED by Vyper
+# @public - visible externally and internally (default for function)
+# @private - only visible in the current contract
+# @constant - doesn't change state
+# @payable - receive ether/ETH
+# @nonrentant(<unique_key>) - Function can only be called once, both externally
+# and internally. Used to prevent reentrancy attacks
+
+# Functions hare not hoisted
+# Functions cannot be assigned to a variable
+# Functions cannot be recursive
+
+# All functions that receive ether must be marked 'payable'
+@public
+@payable
+def depositEther():
+ self.balances[msg.sender] += msg.value
+
+
+# B. EVENTS
+# Events are notify external parties; easy to search and
+# access events from outside blockchain (with lightweight clients)
+# typically declare after contract parameters
+
+# Declare
+LogSent: event({_from: indexed(address), address: indexed(_to), _amount: uint256})
+# Call
+log.LogSent(from, to, amount)
+
+/**
+For an external party (a contract or external entity), to watch using
+the Web3 Javascript library:
+
+# The following is Javascript code, not Vyper code
+Coin.LogSent().watch({}, '', function(error, result) {
+ if (!error) {
+ console.log("Coin transfer: " + result.args.amount +
+ " coins were sent from " + result.args.from +
+ " to " + result.args.to + ".");
+ console.log("Balances now:\n" +
+ "Sender: " + Coin.balances.call(result.args.from) +
+ "Receiver: " + Coin.balances.call(result.args.to));
+ }
+}
+**/
+
+# Common paradigm for one contract to depend on another (e.g., a
+# contract that depends on current exchange rate provided by another)
+
+
+# ---
+
+
+# 6. BRANCHING AND LOOPS
+
+# All basic logic blocks from Python work - including if/elif/else, for,
+# while, break, continue, return - but no switch
+
+# Syntax same as Python, but no type conversion from non-boolean
+# to boolean (comparison operators must be used to get the boolean val)
+
+# REMEMBER: Vyper does not allow resursive calls or infinite loops
+
+
+# ---
+
+
+# 7. OBJECTS/CONTRACTS
+# REMEMBER: Vyper does not allow for inheritance or imports
+
+# A. CALLING EXTERNAL CONTRACTS
+# You must define an interface to an external contract in the current contract
+
+contract InfoFeed():
+ def getInfo() -> uint256: constant
+
+info: uint256
+
+@public
+def __init__(_source: address):
+ self.info = InfoFeed(_source).getInfo()
+
+
+# B. ERC20 BUILT-IN
+# Using the `ERC20` keyword implies that the contract at the address
+# follows the ERC20 token standard, allowing you to safely call
+# functions like `transfer()`, etc.
+
+tokenAddress: address(ERC20)
+
+@public
+def transferIt(_to: address, _amt: uint256(wei)):
+ self.tokenAddress.transfer(_to, _amt)
+
+
+# C. FOLLOWING AN INTERFACE
+# Vyper is experimenting with using the following syntax at the top of
+# a `.vy` file to specify what interfaces are followed by the contract
+# This allows interfaces to be better organized, registered, and recognized
+
+import interfaces.some_interface as SomeInterface
+implements: SomeInterface
+# <rest of contract>
+
+
+# ---
+
+
+# 8. OTHER KEYWORDS
+
+# A. selfdestruct()
+# selfdestruct current contract, sending funds to address (often creator)
+selfdestruct(SOME_ADDRESS);
+
+# removes storage/code from current/future blocks
+# helps thin clients, but previous data persists in blockchain
+
+# Common pattern, lets owner end the contract and receive remaining funds
+@public
+def endItAll() {
+ assert msg.sender == self.creator # Only let the contract creator do this
+ selfdestruct(self.creator) # Makes contract inactive, returns funds
+
+# May want to deactivate contract manually, rather than selfdestruct
+# (ether sent to selfdestructed contract is lost)
+
+
+# B. sha3()
+# Encrypts strings and other data
+# Very important on the blockchain
+# Takes 1 argument, `concat()` can be called beforehand
+# All strings passed are concatenated before hash action
+sha3(concat("ab", "cd")) # returns bytes32
+
+
+# ---
+
+
+# 9. CONTRACT DESIGN NOTES
+
+# A. Obfuscation
+# All variables are publicly viewable on blockchain, so anything
+# that is private needs to be obfuscated (e.g., hashed w/secret)
+# Oftentimes, a "commit-reveal" scheme is employed
+
+# Step 1. Commit
+# Place a commitment by sending output of `sha3()`
+sha3("a secret"); # btyes32 commit
+sha3(concat("secret", "other secret", "salt")); # commit multiple things
+# The `sha3()` calculation should occur off-chain, only the bytes32
+# output should be inputted into some `commit()` function
+commits: map(address, bytes32)
+@public
+def commit(commitment: bytes32):
+ self.commits[msg.sender] = commitment
+
+# Step 2. Reveal
+# Send your previously committed data so the contract can check
+# if your commitment was honest
+@public
+def reveal(_secret: string[100], _salt: string[100]) -> bool:
+ return sha3(concat(_secret, _salt)) == self.commits[msg.sender]
+
+
+# B. Storage optimization
+# Writing to blockchain can be expensive, as data stored forever; encourages
+# smart ways to use memory (eventually, compilation will be better, but for now
+# benefits to planning data structures - and storing min amount in blockchain)
+
+# Cost can often be high for items like multidimensional arrays
+# (cost is for storing data - not declaring unfilled variables)
+
+
+# C. Data access in blockchain
+# Cannot restrict human or computer from reading contents of
+# transaction or transaction's state
+
+# While 'private' prevents other *contracts* from reading data
+# directly - any other party can still read data in blockchain
+
+# All data to start of time is stored in blockchain, so
+# anyone can observe all previous data and changes
+
+
+# D. Cron Job
+# Contracts must be manually called to handle time-based scheduling;
+# can create external code to regularly ping or provide incentives
+# (ether) for others to ping
+
+
+# E. Observer Pattern
+# An Observer Pattern lets you register as a subscriber and
+# register a function which is called by the oracle (note, the oracle
+# pays for this action to be run)
+# Some similarities to subscription in Pub/sub
+
+# This is an abstract contract, both client and server classes import,
+# the client should implement
+
+### **** START EXAMPLE **** ###
+
+contract SomeOracleCallback():
+ def oracleCallback(_value: uint256, _time: timestamp, _info: bytes32): modifying
+
+MAX_SUBS: constant(uint256) = 100
+numSubs: public(uint256) # number of subscribers
+subs: map(uint256, address) # enumerates subscribers
+
+@public
+def addSub(_sub: address) -> uint256:
+ """
+ @notice Add subscriber
+ @param _sub Address to add
+ @return Id of newly added subscriber
+ """
+ self.subs[self.numSubs] = _sub
+ self.numSubs += 1
+ return self.numSubs - 1
+
+@private
+def notify(_value: uint256, _time: timestamp, _info: bytes32) -> bool:
+ """
+ @notice Notify all subscribers
+ @dev Check `numSubs` first; Watch out for gas costs!
+ @param _value whatever
+ @param _time what have you
+ @param _info what else
+ @return True upon successful completion
+ """
+ j: uint256
+ for i in range(MAX_SUBS):
+ j = convert(i, uint256) # `i` is int128 by default
+ if j == self.numSubs:
+ return True
+ SomeOracleCallback(self.subs[j]).oracleCallback(_value, _time, _info)
+
+@public
+def doSomething():
+ """
+ @notice Do something and notify subscribers
+ """
+ # ...something...
+ whatever: uint256 = 6
+ what_have_you: timestamp
+ what_else: bytes32 = sha3("6")
+ self.notify(whatever, what_have_you, what_else)
+
+# Now, your client contract can addSubscriber by importing SomeOracleCallback
+# and registering with Some Oracle
+
+### **** END EXAMPLE **** ###
+
+
+# ---
+
+
+# 10. SECURITY
+# Bugs can be disastrous in Ethereum contracts - and even popular patterns in
+# Vyper may be found to be antipatterns
+
+# See security links at the end of this doc
+
+
+# ---
+
+
+# 11. STYLE NOTES
+# Based on Python's PEP8 style guide
+# Full Style guide: http:#solidity.readthedocs.io/en/develop/style-guide.html
+
+# Quick summary:
+# 4 spaces for indentation
+# Two lines separate contract declarations (and other top level declarations)
+# Avoid extraneous spaces in parentheses
+# Can omit curly braces for one line statement (if, for, etc)
+# else should be placed on own line
+
+# Specific to Vyper:
+# arguments: snake_case
+# events, interfaces, structs: PascalCase
+# public functions: camelCase
+# private functions: _prefaceWithUnderscore
+
+
+# ---
+
+
+# 12. NATSPEC COMMENTS
+# used for documentation, commenting, and external UIs
+
+# Contract natspec - always above contract definition
+# @title Contract title
+# @author Author name
+
+# Function natspec
+# Should include in docstring of functions in typical Pythonic fashion
+# @notice Information about what function does; shown when function to execute
+# @dev Function documentation for developer
+
+# Function parameter/return value natspec
+# @param someParam Some description of what the param does
+# @return Description of the return value
+
+```
+
+## Additional resources
+- [Installation](https://vyper.readthedocs.io/en/latest/installing-vyper.html)
+- [Vyper Docs](https://media.readthedocs.org/pdf/vyper/latest/vyper.pdf)
+- [Vyper GitHub (under active dev)](https://github.com/ethereum/vyper)
+- [Tools and Resources](https://github.com/ethereum/vyper/wiki/Vyper-tools-and-resources)
+- [Online Compiler](https://vyper.online/)
+
+## Sample contracts
+- [Uniswap](https://github.com/Uniswap/contracts-vyper)
+- [Generalized Governance](https://github.com/kpeluso/gdg)
+- [Dynamic Arrays](https://github.com/kpeluso/vyper-dynamic-array)
+
+## Security
+Vyper is secure by design, but it may be helpful to understand what Vyper is
+protecting you from.
+- [Thinking About Smart Contract Security](https:#blog.ethereum.org/2016/06/19/thinking-smart-contract-security/)
+- [Smart Contract Security](https:#blog.ethereum.org/2016/06/10/smart-contract-security/)
+- [Hacking Distributed Blog](http:#hackingdistributed.com/)
+
+## Style
+- [Vyper Style Guide WIP](https://github.com/ethereum/vyper/issues/905)
+ - Heavily derived from [Solidity's style guide](http:#solidity.readthedocs.io/en/latest/style-guide.html) ...
+ - ... which, in turn, is heavily derived from Python's [PEP 8](https:#www.python.org/dev/peps/pep-0008/) style guide.
+
+## Editors
+- [Vyper for VS Code (alpha)](https://github.com/p-/vscode-vyper)
+
+## Future To Dos
+- Update to current Vyper release
+- List of common design patterns
+
+*Feel free to send a pull request with any edits - or email* `pelusoken -/at-/ gmail`
+
diff --git a/wasm.html.markdown b/wasm.html.markdown
new file mode 100644
index 00000000..98bfc000
--- /dev/null
+++ b/wasm.html.markdown
@@ -0,0 +1,227 @@
+---
+language: WebAssembly
+filename: learn-wasm.wast
+contributors:
+ - ["Dean Shaff", "http://dean-shaff.github.io"]
+---
+
+```
+;; learn-wasm.wast
+
+(module
+ ;; In WebAssembly, everything is included in a module. Moreover, everything
+ ;; can be expressed as an s-expression. Alternatively, there is the
+ ;; "stack machine" syntax, but that is not compatible with Binaryen
+ ;; intermediate representation (IR) syntax.
+
+ ;; The Binaryen IR format is *mostly* compatible with WebAssembly text format.
+ ;; There are some small differences:
+ ;; local_set -> local.set
+ ;; local_get -> local.get
+
+ ;; We have to enclose code in functions
+
+ ;; Data Types
+ (func $data_types
+ ;; WebAssembly has only four types:
+ ;; i32 - 32 bit integer
+ ;; i64 - 64 bit integer (not supported in JavaScript)
+ ;; f32 - 32 bit floating point
+ ;; f64 - 64 bit floating point
+
+ ;; We can declare local variables with the "local" keyword
+ ;; We have to declare all variables before we start doing anything
+ ;; inside the function
+
+ (local $int_32 i32)
+ (local $int_64 i64)
+ (local $float_32 f32)
+ (local $float_64 f64)
+
+ ;; These values remain uninitialized.
+ ;; To set them to a value, we can use <type>.const:
+
+ (local.set $int_32 (i32.const 16))
+ (local.set $int_32 (i64.const 128))
+ (local.set $float_32 (f32.const 3.14))
+ (local.set $float_64 (f64.const 1.28))
+ )
+
+ ;; Basic operations
+ (func $basic_operations
+
+ ;; In WebAssembly, everything is an s-expression, including
+ ;; doing math, or getting the value of some variable
+
+ (local $add_result i32)
+ (local $mult_result f64)
+
+ (local.set $add_result (i32.add (i32.const 2) (i32.const 4)))
+ ;; the value of add_result is now 6!
+
+ ;; We have to use the right data type for each operation:
+ ;; (local.set $mult_result (f32.mul (f32.const 2.0) (f32.const 4.0))) ;; WRONG! mult_result is f64!
+ (local.set $mult_result (f64.mul (f64.const 2.0) (f64.const 4.0))) ;; WRONG! mult_result is f64!
+
+ ;; WebAssembly has some builtin operations, like basic math and bitshifting.
+ ;; Notably, it does not have built in trigonometric functions.
+ ;; In order to get access to these functions, we have to either
+ ;; - implement them ourselves (not recommended)
+ ;; - import them from elsewhere (later on)
+ )
+
+ ;; Functions
+ ;; We specify arguments with the `param` keyword, and specify return values
+ ;; with the `result` keyword
+ ;; The current value on the stack is the return value of a function
+
+ ;; We can call other functions we've defined with the `call` keyword
+
+ (func $get_16 (result i32)
+ (i32.const 16)
+ )
+
+ (func $add (param $param0 i32) (param $param1 i32) (result i32)
+ (i32.add
+ (local.get $param0)
+ (local.get $param1)
+ )
+ )
+
+ (func $double_16 (result i32)
+ (i32.mul
+ (i32.const 2)
+ (call $get_16))
+ )
+
+ ;; Up until now, we haven't be able to print anything out, nor do we have
+ ;; access to higher level math functions (pow, exp, or trig functions).
+ ;; Moreover, we haven't been able to use any of the WASM functions in Javascript!
+ ;; The way we get those functions into WebAssembly
+ ;; looks different whether we're in a Node.js or browser environment.
+
+ ;; If we're in Node.js we have to do two steps. First we have to convert the
+ ;; WASM text representation into actual webassembly. If we're using Binyaren,
+ ;; we can do that with a command like the following:
+
+ ;; wasm-as learn-wasm.wast -o learn-wasm.wasm
+
+ ;; We can apply Binaryen optimizations to that file with a command like the
+ ;; following:
+
+ ;; wasm-opt learn-wasm.wasm -o learn-wasm.opt.wasm -O3 --rse
+
+ ;; With our compiled WebAssembly, we can now load it into Node.js:
+ ;; const fs = require('fs')
+ ;; const instantiate = async function (inFilePath, _importObject) {
+ ;; var importObject = {
+ ;; console: {
+ ;; log: (x) => console.log(x),
+ ;; },
+ ;; math: {
+ ;; cos: (x) => Math.cos(x),
+ ;; }
+ ;; }
+ ;; importObject = Object.assign(importObject, _importObject)
+ ;;
+ ;; var buffer = fs.readFileSync(inFilePath)
+ ;; var module = await WebAssembly.compile(buffer)
+ ;; var instance = await WebAssembly.instantiate(module, importObject)
+ ;; return instance.exports
+ ;; }
+ ;;
+ ;; const main = function () {
+ ;; var wasmExports = await instantiate('learn-wasm.wasm')
+ ;; wasmExports.print_args(1, 0)
+ ;; }
+
+ ;; The following snippet gets the functions from the importObject we defined
+ ;; in the JavaScript instantiate async function, and then exports a function
+ ;; "print_args" that we can call from Node.js
+
+ (import "console" "log" (func $print_i32 (param i32)))
+ (import "math" "cos" (func $cos (param f64) (result f64)))
+
+ (func $print_args (param $arg0 i32) (param $arg1 i32)
+ (call $print_i32 (local.get $arg0))
+ (call $print_i32 (local.get $arg1))
+ )
+ (export "print_args" (func $print_args))
+
+ ;; Loading in data from WebAssembly memory.
+ ;; Say that we want to apply the cosine function to a Javascript array.
+ ;; We need to be able to access the allocated array, and iterate through it.
+ ;; This example will modify the input array inplace.
+ ;; f64.load and f64.store expect the location of a number in memory *in bytes*.
+ ;; If we want to access the 3rd element of an array, we have to pass something
+ ;; like (i32.mul (i32.const 8) (i32.const 2)) to the f64.store function.
+
+ ;; In JavaScript, we would call `apply_cos64` as follows
+ ;; (using the instantiate function from earlier):
+ ;;
+ ;; const main = function () {
+ ;; var wasm = await instantiate('learn-wasm.wasm')
+ ;; var n = 100
+ ;; const memory = new Float64Array(wasm.memory.buffer, 0, n)
+ ;; for (var i=0; i<n; i++) {
+ ;; memory[i] = i;
+ ;; }
+ ;; wasm.apply_cos64(n)
+ ;; }
+ ;;
+ ;; This function will not work if we allocate a Float32Array on the JavaScript
+ ;; side.
+
+ (memory (export "memory") 100)
+
+ (func $apply_cos64 (param $array_length i32)
+ ;; declare the loop counter
+ (local $idx i32)
+ ;; declare the counter that will allow us to access memory
+ (local $idx_bytes i32)
+ ;; constant expressing the number of bytes in a f64 number.
+ (local $bytes_per_double i32)
+
+ ;; declare a variable for storing the value loaded from memory
+ (local $temp_f64 f64)
+
+ (local.set $idx (i32.const 0))
+ (local.set $idx_bytes (i32.const 0)) ;; not entirely necessary
+ (local.set $bytes_per_double (i32.const 8))
+
+ (block
+ (loop
+ ;; this sets idx_bytes to bytes offset of the value we're interested in.
+ (local.set $idx_bytes (i32.mul (local.get $idx) (local.get $bytes_per_double)))
+
+ ;; get the value of the array from memory:
+ (local.set $temp_f64 (f64.load (local.get $idx_bytes)))
+
+ ;; now apply the cosine function:
+ (local.set $temp_64 (call $cos (local.get $temp_64)))
+
+ ;; now store the result at the same location in memory:
+ (f64.store
+ (local.get $idx_bytes)
+ (local.get $temp_64))
+
+ ;; do it all in one step instead
+ (f64.store
+ (local.get $idx_bytes)
+ (call $cos
+ (f64.load
+ (local.get $idx_bytes))))
+
+ ;; increment the loop counter
+ (local.set $idx (i32.add (local.get $idx) (i32.const 1)))
+
+ ;; stop the loop if the loop counter is equal the array length
+ (br_if 1 (i32.eq (local.get $idx) (local.get $array_length)))
+ (br 0)
+ )
+ )
+ )
+ (export "apply_cos64" (func $apply_cos64))
+)
+
+```
diff --git a/wolfram.html.markdown b/wolfram.html.markdown
index 4514006d..5fddbc82 100644
--- a/wolfram.html.markdown
+++ b/wolfram.html.markdown
@@ -123,8 +123,8 @@ myHash[["Green"]] (* 2, use it *)
myHash[["Green"]] := 5 (* 5, update it *)
myHash[["Puce"]] := 3.5 (* 3.5, extend it *)
KeyDropFrom[myHash, "Green"] (* Wipes out key Green *)
-Keys[myHash] (* {Red} *)
-Values[myHash] (* {1} *)
+Keys[myHash] (* {Red, Puce} *)
+Values[myHash] (* {1, 3.5} *)
(* And you can't do any demo of Wolfram without showing this off *)
Manipulate[y^2, {y, 0, 20}] (* Return a reactive user interface that displays y^2
diff --git a/yaml.html.markdown b/yaml.html.markdown
index 8683971e..f1393c09 100644
--- a/yaml.html.markdown
+++ b/yaml.html.markdown
@@ -38,6 +38,8 @@ however: 'A string, enclosed in quotes.'
'Keys can be quoted too.': "Useful if you want to put a ':' in your key."
single quotes: 'have ''one'' escape pattern'
double quotes: "have many: \", \0, \t, \u263A, \x0d\x0a == \r\n, and more."
+# UTF-8/16/32 characters need to be encoded
+Superscript two: \u00B2
# Multiple-line strings can be written either as a 'literal block' (using |),
# or a 'folded block' (using '>').
@@ -121,7 +123,7 @@ other_anchor: *anchor_name
base: &base
name: Everyone has same name
-# The regexp << is called Merge Key Language-Independent Type. It is is used to
+# The regexp << is called Merge Key Language-Independent Type. It is used to
# indicate that all the keys of one or more specified maps should be inserted
# into the current map.
diff --git a/zfs.html.markdown b/zfs.html.markdown
index fad6b62d..6795b1fa 100644
--- a/zfs.html.markdown
+++ b/zfs.html.markdown
@@ -221,7 +221,7 @@ Delete dataset
```bash
# Datasets cannot be deleted if they have any snapshots
-zfs destroy tank/root/home
+$ zfs destroy tank/root/home
```
Get / set properties of a dataset
@@ -294,6 +294,7 @@ tank/home/sarlalian@now 0 - 259M -
tank/home/alice@now 0 - 156M -
tank/home/bob@now 0 - 156M -
...
+```
Destroy snapshots
@@ -313,13 +314,13 @@ Renaming Snapshots
$ zfs rename tank/home/sarlalian@now tank/home/sarlalian@today
$ zfs rename tank/home/sarlalian@now today
-# zfs rename -r tank/home@now @yesterday
+$ zfs rename -r tank/home@now @yesterday
```
Accessing snapshots
```bash
-# CD Into a snapshot directory
+# CD into a snapshot directory
$ cd /home/.zfs/snapshot/
```
@@ -335,11 +336,11 @@ $ zfs send tank/home/sarlalian@now | zfs recv backups/home/sarlalian
# Send a snapshot to a remote host
$ zfs send tank/home/sarlalian@now | ssh root@backup_server 'zfs recv tank/home/sarlalian'
-# Send full dataset with snapshos to new host
+# Send full dataset with snapshots to new host
$ zfs send -v -R tank/home@now | ssh root@backup_server 'zfs recv tank/home'
```
-Cloneing Snapshots
+Cloning Snapshots
```bash
# Clone a snapshot
diff --git a/zh-cn/awk-cn.html.markdown b/zh-cn/awk-cn.html.markdown
index 3fea782b..8ee2db2c 100644
--- a/zh-cn/awk-cn.html.markdown
+++ b/zh-cn/awk-cn.html.markdown
@@ -1,5 +1,6 @@
---
-language: awk
+category: tool
+tool: awk
contributors:
- ["Marshall Mason", "http://github.com/marshallmason"]
translators:
diff --git a/zh-cn/dart-cn.html.markdown b/zh-cn/dart-cn.html.markdown
index b0287f0c..79db8e5c 100644
--- a/zh-cn/dart-cn.html.markdown
+++ b/zh-cn/dart-cn.html.markdown
@@ -176,23 +176,47 @@ example13() {
match(s2);
}
-// 布尔表达式必需被解析为 true 或 false,
-// 因为不支持隐式转换。
+// 布尔表达式支持隐式转换以及动态类型
example14() {
- var v = true;
- if (v) {
- print("Example14 value is true");
+ var a = true;
+ if (a) {
+ print("Example14 true, a is $a");
}
- v = null;
+ a = null;
+ if (a) {
+ print("Example14 true, a is $a");
+ } else {
+ print("Example14 false, a is $a"); // 执行到这里
+ }
+
+ // 动态类型的null可以转换成bool型
+ var b;// b是动态类型
+ b = "abc";
try {
- if (v) {
- // 不会执行
+ if (b) {
+ print("Example14 true, b is $b");
} else {
- // 不会执行
+ print("Example14 false, b is $b");
}
} catch (e) {
- print("Example14 null value causes an exception: '${e}'");
+ print("Example14 error, b is $b"); // 这段代码可以执行但是会报错
}
+ b = null;
+ if (b) {
+ print("Example14 true, b is $b");
+ } else {
+ print("Example14 false, b is $b"); // 这行到这里
+ }
+
+ // 静态类型的null不能转换成bool型
+ var c = "abc";
+ c = null;
+ // 编译出错
+ // if (c) {
+ // print("Example14 true, c is $c");
+ // } else {
+ // print("Example14 false, c is $c");
+ // }
}
// try/catch/finally 和 throw 语句用于异常处理。
diff --git a/zh-cn/git-cn.html.markdown b/zh-cn/git-cn.html.markdown
index 4ef3ffb8..d471ab5d 100644
--- a/zh-cn/git-cn.html.markdown
+++ b/zh-cn/git-cn.html.markdown
@@ -131,7 +131,7 @@ $ git help init
```bash
-# 显示分支,为跟踪文件,更改和其他不同
+# 显示分支,未跟踪文件,更改和其他不同
$ git status
# 查看其他的git status的用法
diff --git a/zh-cn/lambda-calculus-cn.html.markdown b/zh-cn/lambda-calculus-cn.html.markdown
new file mode 100644
index 00000000..7719ee71
--- /dev/null
+++ b/zh-cn/lambda-calculus-cn.html.markdown
@@ -0,0 +1,223 @@
+---
+category: Algorithms & Data Structures
+name: Lambda Calculus
+lang: zh-cn
+contributors:
+ - ["Max Sun", "http://github.com/maxsun"]
+ - ["Yan Hui Hang", "http://github.com/yanhh0"]
+translators:
+ - ["Maoyin Sun", "https://github.com/simonmysun"]
+---
+
+# Lambda 演算
+
+Lambda 演算(lambda calculus, λ-calculus),
+最初由[阿隆佐·邱奇][]([Alonzo Church][])提出,
+是世界上最小的编程语言.
+尽管没有数字, 字符串, 布尔或者任何非函数的数据类型,
+lambda 演算仍可以表示任何图灵机.
+
+[阿隆佐·邱奇]: https://zh.wikipedia.org/wiki/%E9%98%BF%E9%9A%86%E4%BD%90%C2%B7%E9%82%B1%E5%A5%87
+[Alonzo Church]: https://en.wikipedia.org/wiki/Alonzo_Church
+
+Lambda 演算由三种元素组成: **变量**(variables)、**函数**(functions)和**应用**(applications)。
+
+| 名称 | 语法 | 示例 | 解释 |
+|------|----------------------|-----------|--------------------------------------------------|
+| 变量 | `<变量名>` | `x` | 一个名为"x"的变量 |
+| 函数 | `λ<参数>.<函数体>` | `λx.x` | 一个以"x"(前者)为参数、以"x"(后者)为函数体的函数 |
+| 应用 | `<函数><变量或函数>` | `(λx.x)a` | 以"a"为参数调用函数"λx.x" |
+
+最基本的函数为恒等函数: `λx.x`, 它等价于`f(x) = x`.
+第一个"x"为函数的参数, 第二个为函数体.
+
+## 自由变量和约束变量:
+
+- 在函数`λx.x`中, "x"被称作约束变量因为它同时出现在函数体和函数参数中.
+- 在`λx.y`中, "y"被称作自由变量因为它没有被预先声明.
+
+## 求值:
+
+求值操作是通过[β-归约][]([β-Reduction][])完成的,
+它本质上是词法层面上的替换.
+
+[β-归约]: https://zh.wikipedia.org/wiki/%CE%9B%E6%BC%94%E7%AE%97#'%22%60UNIQ--postMath-0000006F-QINU%60%22'-%E6%AD%B8%E7%B4%84
+[β-Reduction]: https://en.wikipedia.org/wiki/Lambda_calculus#Beta_reduction
+
+当对表达式`(λx.x)a`求值时, 我们将函数体中所有出现的"x"替换为"a".
+
+- `(λx.x)a`计算结果为: `a`
+- `(λx.y)a`计算结果为: `y`
+
+你甚至可以创建高阶函数:
+
+- `(λx.(λy.x))a`计算结果为: `λy.a`
+
+尽管 lambda 演算传统上仅支持单个参数的函数,
+但我们可以通过一种叫作[柯里化][]([Currying][])的技巧创建多个参数的函数.
+
+[柯里化]: https://zh.wikipedia.org/wiki/%E6%9F%AF%E9%87%8C%E5%8C%96
+[Currying]: https://en.wikipedia.org/wiki/Currying
+
+- `(λx.λy.λz.xyz)`等价于`f(x, y, z) = ((x y) z)`
+
+有时`λxy.<body>`与`λx.λy.<body>`可以互换使用.
+
+----
+
+认识到传统的 **lambda 演算没有数字, 字符或者任何非函数的数据类型**很重要.
+
+## 布尔逻辑:
+
+在 lambda 演算中没有"真"或"假". 甚至没有 1 或 0.
+
+作为替换:
+
+`T`表示为: `λx.λy.x`
+
+`F`表示为: `λx.λy.y`
+
+首先, 我们可以定义一个"if"函数`λbtf`, 它当`b`为真时返回`t`,
+`b`为假时返回`f`
+
+`IF`等价于: `λb.λt.λf.b t f`
+
+通过`IF`, 我们可以定义基本的布尔逻辑运算符:
+
+`a AND b`等价于: `λab.IF a b F`
+
+`a OR b`等价于: `λab.IF a T b`
+
+`NOT a`等价于: `λa.IF a F T`
+
+*注意: `IF a b c`本质上指: `IF((a b) c)`*
+
+## 数字:
+
+尽管 lambda 演算中没有数字,
+我们还可以用[邱奇编码][]([Church numerals][])将数字嵌入到 lambda 演算中.
+
+[邱奇编码]: https://zh.wikipedia.org/wiki/%E9%82%B1%E5%A5%87%E7%BC%96%E7%A0%81
+[Church numerals]: https://en.wikipedia.org/wiki/Church_encoding
+
+对于任意数字 n: <code>n = λf.f<sup>n</sup></code> 所以:
+
+`0 = λf.λx.x`
+
+`1 = λf.λx.f x`
+
+`2 = λf.λx.f(f x)`
+
+`3 = λf.λx.f(f(f x))`
+
+要增加一个邱奇数, 我们使用后继函数`S(n) = n + 1`:
+
+`S = λn.λf.λx.f((n f) x)`
+
+使用后继函数, 我们可以定义加法:
+
+`ADD = λab.(a S)b`
+
+**挑战**: 试定义乘法函数!
+
+## 变得更小: SKI, SK 和 Iota
+
+### SKI 组合子演算
+
+令 S, K, I 为下列函数:
+
+`I x = x`
+
+`K x y = x`
+
+`S x y z = x z (y z)`
+
+我们可以将 lambda 演算中的表达式转换为 SKI 组合子演算中的表达式:
+
+1. `λx.x = I`
+2. `λx.c = Kc`
+3. `λx.(y z) = S (λx.y) (λx.z)`
+
+以邱奇数 2 为例:
+
+`2 = λf.λx.f(f x)`
+
+对于里面的部分 `λx.f(f x)`:
+
+```
+ λx.f(f x)
+= S (λx.f) (λx.(f x)) (case 3)
+= S (K f) (S (λx.f) (λx.x)) (case 2, 3)
+= S (K f) (S (K f) I) (case 2, 1)
+```
+
+所以:
+
+```
+ 2
+= λf.λx.f(f x)
+= λf.(S (K f) (S (K f) I))
+= λf.((S (K f)) (S (K f) I))
+= S (λf.(S (K f))) (λf.(S (K f) I)) (case 3)
+```
+
+对于第一个参数`λf.(S (K f))`有:
+
+```
+ λf.(S (K f))
+= S (λf.S) (λf.(K f)) (case 3)
+= S (K S) (S (λf.K) (λf.f)) (case 2, 3)
+= S (K S) (S (K K) I) (case 2, 3)
+```
+
+对于第二个参数`λf.(S (K f) I)`有:
+
+```
+ λf.(S (K f) I)
+= λf.((S (K f)) I)
+= S (λf.(S (K f))) (λf.I) (case 3)
+= S (S (λf.S) (λf.(K f))) (K I) (case 2, 3)
+= S (S (K S) (S (λf.K) (λf.f))) (K I) (case 1, 3)
+= S (S (K S) (S (K K) I)) (K I) (case 1, 2)
+```
+
+综上:
+
+```
+ 2
+= S (λf.(S (K f))) (λf.(S (K f) I))
+= S (S (K S) (S (K K) I)) (S (S (K S) (S (K K) I)) (K I))
+```
+
+如果展开这个表达式, 我们最终又会得到邱奇数 2 的相同的表达式.
+
+### SK 组合子演算
+
+SKI 组合子演算还可以进一步简化. 我们可以通过`I = SKK`移除 I 组合子.
+我们可以将所有的 `I` 替换为 `SKK`.
+
+### ι 组合子
+
+SK 组合子仍不是最简的. 定义:
+
+```
+ι = λf.((f S) K)
+```
+
+我们有:
+
+```
+I = ιι
+K = ι(ιI) = ι(ι(ιι))
+S = ι(K) = ι(ι(ι(ιι)))
+```
+
+## 更多阅读:
+
+1. [A Tutorial Introduction to the Lambda Calculus](http://www.inf.fu-berlin.de/lehre/WS03/alpi/lambda.pdf)(英文)
+2. [Cornell CS 312 Recitation 26: The Lambda Calculus](https://courses.cs.cornell.edu/cs312/2008sp/recitations/rec26.html)(英文)
+3. [Wikipedia - Lambda Calculus](https://en.wikipedia.org/wiki/Lambda_calculus)(英文)
+4. [Wikipedia - SKI combinator calculus](https://en.wikipedia.org/wiki/SKI_combinator_calculus)(英文)
+5. [Wikipedia - Iota and Jot](https://en.wikipedia.org/wiki/Iota_and_Jot)(英文)
+6. [λ演算 - 维基百科,自由的百科全书](https://zh.wikipedia.org/wiki/SKI%E7%BB%84%E5%90%88%E5%AD%90%E6%BC%94%E7%AE%97)
+7. [SKI组合子演算 - 维基百科,自由的百科全书](https://zh.wikipedia.org/wiki/SKI%E7%BB%84%E5%90%88%E5%AD%90%E6%BC%94%E7%AE%97)
diff --git a/zh-cn/make-cn.html.markdown b/zh-cn/make-cn.html.markdown
index 4cdf1e63..76dde941 100644
--- a/zh-cn/make-cn.html.markdown
+++ b/zh-cn/make-cn.html.markdown
@@ -1,5 +1,6 @@
---
-language: make
+category: tool
+tool: make
contributors:
- ["Robert Steed", "https://github.com/robochat"]
- ["Jichao Ouyang", "https://github.com/jcouyang"]
@@ -38,7 +39,7 @@ Makefile 用于定义如何创建目标文件, 比如如何从源码到可执行
# …
# prerequisites(依赖) 是可选的, recipe(做法) 也可以多个或者不给.
-# 下面这个任务没有给 prerequisites, 只会在目标文件 file0.txt 文件不存在是跑
+# 下面这个任务没有给 prerequisites, 只会在目标文件 file0.txt 文件不存在时执行
file0.txt:
echo "foo" > file0.txt
# 试试 `make file0.txt`
@@ -46,12 +47,12 @@ file0.txt:
# 注意: 即使是这些注释, 如果前面有 TAB, 也会发送给 shell, 注意看 `make file0.txt` 输出
# 如果提供 prerequisites, 则只有 prerequisites 比 target 新时会执行
-# 比如下面这个任务只有当 file1.txt 比 file0.txt 新时才会执行.
+# 比如下面这个任务只有当 file0.txt 比 file1.txt 新时才会执行.
file1.txt: file0.txt
cat file0.txt > file1.txt
- # 这里跟shell里的命令式一毛一样的.
+ # 这里跟shell里的命令式一模一样.
@cat file0.txt >> file1.txt
- # @ 不会把命令往 stdout 打印.
+ # @ 不会把命令打印到 stdout.
-@echo 'hello'
# - 意思是发生错误了也没关系.
# 试试 `make file1.txt` 吧.
@@ -234,7 +235,7 @@ ls: *
# include foo.mk
sport = tennis
-# 一些逻辑语句 if else 什么的, 顶个写
+# 流程控制语句 (如if else 等等) 顶格写
report:
ifeq ($(sport),tennis)
@echo 'game, set, match'
diff --git a/zh-cn/markdown-cn.html.markdown b/zh-cn/markdown-cn.html.markdown
index 2bd8d11a..9b3d96ab 100644
--- a/zh-cn/markdown-cn.html.markdown
+++ b/zh-cn/markdown-cn.html.markdown
@@ -5,6 +5,7 @@ contributors:
translators:
- ["Fangzhou Chen","https://github.com/FZSS"]
- ["Luffy Zhong", "https://github.com/mengzhongshi"]
+ - ["Yuchen Liu", "https://github.com/smallg0at"]
filename: learnmarkdown-cn.md
lang: zh-cn
---
@@ -46,6 +47,16 @@ Markdown 是 HTML 的父集,所以任何 HTML 文件都是有效的 Markdown
##### 这是一个 <h5>
###### 这是一个 <h6>
```
+
+实际效果(最终显示时会因设置而看起来不同):
+# 这是一个
+## 这也是一个
+### 这还是一个
+#### 这依旧是一个
+##### 这真的是一个
+###### 这...是一个
+
+
对于 `<h1>` 和 `<h2>` 元素,Markdown 额外提供了两种添加方式。
```md
@@ -58,7 +69,7 @@ Markdown 是 HTML 的父集,所以任何 HTML 文件都是有效的 Markdown
## 文本样式
-文本的斜体,粗体在 Markdown 中可以轻易实现。
+文本的*斜体*,**粗体**在 Markdown 中可以轻易实现。
```md
*此文本为斜体。*
@@ -72,7 +83,7 @@ __此文本也是__
*__这个也是!__*
```
-GitHub 也支持 Markdown,在 GitHub 的 Markdown 解析器中,我们可以使用删除线:
+GitHub 也支持 Markdown,在 GitHub 的 Markdown 解析器中,我们可以使用~~删除线~~:
```md
~~此文本为删除线效果。~~
@@ -80,6 +91,7 @@ GitHub 也支持 Markdown,在 GitHub 的 Markdown 解析器中,我们可以
## 段落
段落由一个句子或是多个中间没有空行的句子组成,每个段落由一个或是多个空行分隔开来。
+(注:部分解析器有无需空行就能换行的设置,这个主要看个人喜好)
```md
这是第一段落. 这句话在同一个段落里,好玩么?
@@ -92,7 +104,9 @@ GitHub 也支持 Markdown,在 GitHub 的 Markdown 解析器中,我们可以
```
如果你想插入一个 `<br />` 标签,你可以在段末加入两个以上的空格,然后另起一
-段。(译者注:试了一下,很多解析器,并不需要空两个空格,直接换行就会添加一个`<br />`)
+段。
+
+(译者注:试了一下,很多解析器,并不需要空两个空格,直接换行就会添加一个`<br />`)
```md
此段落结尾有两个空格(选中以显示)。
@@ -102,6 +116,8 @@ GitHub 也支持 Markdown,在 GitHub 的 Markdown 解析器中,我们可以
段落引用可由 `>` 字符轻松实现。
+> 对的很轻松
+
```md
> 这是一个段落引用。 你可以
> 手动断开你的句子,然后在每句句子前面添加 `>` 字符。或者让你的句子变得很长,以至于他们自动得换行。
@@ -113,7 +129,7 @@ GitHub 也支持 Markdown,在 GitHub 的 Markdown 解析器中,我们可以
```
## 列表
-无序列表可由星号,加号或者减号来创建
+- 无序列表可由星号,加号或者减号来创建
```md
* 项目
@@ -172,6 +188,7 @@ GitHub 也支持 Markdown,在 GitHub 的 Markdown 解析器中,我们可以
下面这个选择框将会是选中状态
- [x] 这个任务已经完成
```
+- [ ] 你看完了这个任务(注:此选择框是无法直接更改的,即禁用状态。)
## 代码块
@@ -217,7 +234,10 @@ end
---
- - -
****************
+
+下面这个就是示例
```
+---
## 链接
@@ -294,33 +314,45 @@ Markdown同样支持引用形式的链接
我希望 *将这段文字置于星号之间* 但是我不希望它被
斜体化, 这么做: \*这段置文字于星号之间\*。
```
+对比一下:*将这段文字置于星号之间* 和 \*将这段文字置于星号之间\*
### 键盘上的功能键
-在 GitHub 的 Markdown中,你可以使用 `<kbd>` 标签来表示功能键。
+在 GitHub 的 Markdown 中,你可以使用 `<kbd>` 标签来表示功能键。
```md
你的电脑死机了?试试
<kbd>Ctrl</kbd>+<kbd>Alt</kbd>+<kbd>Del</kbd>
```
<kbd>Ctrl</kbd>+<kbd>Alt</kbd>+<kbd>Del</kbd>
+
+(译注:可能由于网站本身样式问题,效果不明显)
+
### 表格
-表格只被 GitHub 的 Markdown 支持,并且有一点笨重,但如果你真的要用的话: (译者注:其实现在大部分markdown都已经支持)
+下面示例的表格长这样:
+
+| 第一列 | 第二列 | 第三列 |
+| :----------- | :-------: | ----------: |
+| 我是左对齐 | 居个中 | 右对齐 |
+| 注意 | 冒 | 号 |
+
+工整一点的写法是这样的:
```md
| 第一列 | 第二列 | 第三列 |
-| :--------- | :------: | ----------: |
-| 左对齐 | 居个中 | 右对齐 |
-| 某某某 | 某某某 | 某某某 |
+| :----------- | :-------: | ----------: |
+| 我是左对齐 | 居个中 | 右对齐 |
+| 注意 | 冒 | 号 |
```
-
-或者, 同样的
+好吧,强行对齐字符是很难的。但是,至少比下面这种写法好一点——
```md
-第一列 | 第二列 | 第三列
+我是超级超级长的第一列 | 第二列 | 第三列
:-- | :-: | --:
-这太丑了 | 药不能 | 停
+这真的太丑了 | 药不能 | 停!!!!
```
+真的是*看着令人头晕*
+
更多信息, 请于[此处](http://daringfireball.net/projects/Markdown/syntax)参见 John Gruber 关于语法的官方帖子,及于[此处](https://github.com/adam-p/Markdown-here/wiki/Markdown-Cheatsheet) 参见 Adam Pritchard 的摘要笔记。
diff --git a/zh-cn/python-cn.html.markdown b/zh-cn/python-cn.html.markdown
index deb94cdc..65f125d1 100644
--- a/zh-cn/python-cn.html.markdown
+++ b/zh-cn/python-cn.html.markdown
@@ -439,7 +439,7 @@ Human.grunt() # => "*grunt*"
# 我们可以导入其他模块
import math
-print math.sqrt(16) # => 4
+print math.sqrt(16) # => 4.0
# 我们也可以从一个模块中导入特定的函数
from math import ceil, floor
diff --git a/zh-cn/ruby-cn.html.markdown b/zh-cn/ruby-cn.html.markdown
index 657a913d..9918c022 100644
--- a/zh-cn/ruby-cn.html.markdown
+++ b/zh-cn/ruby-cn.html.markdown
@@ -6,11 +6,25 @@ contributors:
- ["David Underwood", "http://theflyingdeveloper.com"]
- ["Joel Walden", "http://joelwalden.net"]
- ["Luke Holder", "http://twitter.com/lukeholder"]
+ - ["Tristan Hume", "http://thume.ca/"]
+ - ["Nick LaMuro", "https://github.com/NickLaMuro"]
+ - ["Marcos Brizeno", "http://www.about.me/marcosbrizeno"]
+ - ["Ariel Krakowski", "http://www.learneroo.com"]
+ - ["Dzianis Dashkevich", "https://github.com/dskecse"]
+ - ["Levi Bostian", "https://github.com/levibostian"]
+ - ["Rahil Momin", "https://github.com/iamrahil"]
+ - ["Gabriel Halley", "https://github.com/ghalley"]
+ - ["Persa Zula", "http://persazula.com"]
+ - ["Jake Faris", "https://github.com/farisj"]
+ - ["Corey Ward", "https://github.com/coreyward"]
+ - ["Jannik Siebert", "https://github.com/janniks"]
+ - ["Keith Miyake", "https://github.com/kaymmm"]
- ["lidashuang", "https://github.com/lidashuang"]
- ["ftwbzhao", "https://github.com/ftwbzhao"]
translators:
- ["Lin Xiangyu", "https://github.com/oa414"]
- ["Jiang Haiyun", "https://github.com/haiiiiiyun"]
+ - ["woclass", "https://github.com/inkydragon"]
---
```ruby
@@ -18,26 +32,27 @@ translators:
=begin
这是多行注释
-没人用这个
-你也不该用
=end
-# 首先,也是最重要的,所有东西都是对象
+# 在 Ruby 中,(几乎)所有东西都是对象
# 数字是对象
-
-3.class #=> Fixnum
-
+3.class #=> Integer
3.to_s #=> "3"
+# 字符串是对象
+"Hello".class #=> String
+
+# 甚至方法也是对象
+"Hello".method(:class).class #=> Method
-# 一些基本的算术符号
-1 + 1 #=> 2
-8 - 1 #=> 7
-10 * 2 #=> 20
-35 / 5 #=> 7
-2**5 #=> 32
-5 % 3 #=> 2
+# 一些基本的算术操作
+1 + 1 #=> 2
+8 - 1 #=> 7
+10 * 2 #=> 20
+35 / 5 #=> 7
+2 ** 5 #=> 32
+5 % 3 #=> 2
# 位运算符
3 & 5 #=> 1
@@ -48,6 +63,7 @@ translators:
# 实际上是调用对象的方法
1.+(3) #=> 4
10.* 5 #=> 50
+100.methods.include?(:/) #=> true
# 特殊的值也是对象
nil # 相当于其它语言中的 null
@@ -66,11 +82,11 @@ false.class #=> FalseClass
1 != 1 #=> false
2 != 1 #=> true
-# 除了false自己,nil是唯一的另一个值为false的对象
-
-!nil #=> true
-!false #=> true
-!0 #=> false
+# 除了 false 自己,nil 是唯一的另一个值为 false 的对象
+!!nil #=> false
+!!false #=> false
+!!0 #=> true
+!!"" #=> true
# 更多比较
1 < 10 #=> true
@@ -90,11 +106,11 @@ true || false #=> true
!true #=> false
# 也有优先级更低的逻辑运算符
-# 它们用于控制流结构中,用来串接语句,直到返回true或false。
+# 它们用于控制流结构中,用来串接语句,直到返回 true 或 false。
-# `do_something_else` 只当 `do_something` 返回true时才会被调用
+# `do_something_else` 只当 `do_something` 返回 true 时才会被调用
do_something() and do_something_else()
-# `log_error` 只当 `do_something` 返回false时才会被调用
+# `log_error` 只当 `do_something` 返回 false 时才会被调用
do_something() or log_error()
@@ -114,6 +130,7 @@ placeholder = "use string interpolation"
'hello ' + 'world' #=> "hello world"
'hello ' + 3 #=> TypeError: can't convert Fixnum into String
'hello ' + 3.to_s #=> "hello 3"
+"hello #{3}" #=> "hello 3"
# 合并字符串及其运算符
'hello ' * 3 #=> "hello hello hello "
@@ -141,7 +158,7 @@ x = y = 10 #=> 10
x #=> 10
y #=> 10
-# 按照惯例,使用类似snake_case风格的变量名
+# 按照惯例,使用类似 snake_case 风格的变量名
snake_case = true
# 使用有意义的变量名
@@ -174,6 +191,7 @@ array = [1, 2, 3, 4, 5] #=> [1, 2, 3, 4, 5]
# 数组可以被索引
# 从前面开始
array[0] #=> 1
+array.first #=> 1
array[12] #=> nil
# 像运算符一样,[var] 形式的访问
@@ -189,13 +207,13 @@ array.last #=> 5
# 同时指定开始的位置和长度
array[2, 3] #=> [3, 4, 5]
+# 或者指定一个区间
+array[1..3] #=> [2, 3, 4]
+
# 将数组逆序
a=[1,2,3]
a.reverse! #=> [3,2,1]
-# 或者指定一个区间
-array[1..3] #=> [2, 3, 4]
-
# 像这样往数组增加一个元素
array << 6 #=> [1, 2, 3, 4, 5, 6]
# 或者像这样
@@ -217,14 +235,18 @@ hash['number'] #=> 5
# 查询一个不存在的键将会返回nil
hash['nothing here'] #=> nil
-# 从Ruby 1.9开始,用符号作为键的时候有特别的记号表示:
+# 从 Ruby 1.9 开始,用符号作为键的时候有特别的记号表示:
new_hash = { defcon: 3, action: true }
new_hash.keys #=> [:defcon, :action]
+# 检查键值是否存在
+hash.key?(:defcon) #=> true
+hash.value?(3) #=> true
+
# 小贴士:数组和哈希表都是可枚举的
-# 它们共享一些有用的方法,比如each,map,count等等
+# 它们共享一些有用的方法,比如 each, map, count 等等
# 控制流
@@ -236,6 +258,8 @@ else
"else, also optional"
end
+# 循环
+
for counter in 1..5
puts "iteration #{counter}"
end
@@ -246,14 +270,14 @@ end
#=> iteration 5
-# 但是,没有人用for循环。
-# 你应该使用"each"方法,然后再传给它一个块。
-# 所谓块就是可以传给像"each"这样的方法的代码段。
-# 它类似于其它语言中的lambdas, 匿名函数或闭包。
+# 但是,没有人用 for 循环。
+# 你应该使用 "each" 方法,然后再传给它一个块。
+# 所谓块就是可以传给像 "each" 这样的方法的代码段。
+# 它类似于其它语言中的 lambdas, 匿名函数或闭包。
#
-# 区间上的"each"方法会对区间中的每个元素运行一次块代码。
-# 我们将counter作为一个参数传给了块。
-# 调用带有块的"each"方法看起来如下:
+# 区间上的 "each" 方法会对区间中的每个元素运行一次块代码。
+# 我们将 counter 作为一个参数传给了块。
+# 调用带有块的 "each" 方法看起来如下:
(1..5).each do |counter|
puts "iteration #{counter}"
@@ -275,7 +299,7 @@ hash.each do |key, value|
puts "#{key} is #{value}"
end
-# 如果你还需要索引值,可以使用"each_with_index",并且定义
+# 如果你还需要索引值,可以使用 "each_with_index",并且定义
# 一个索引变量
array.each_with_index do |element, index|
puts "#{element} is number #{index} in the array"
@@ -293,7 +317,7 @@ end
#=> iteration 5
# Ruby 中还有很多有用的循环遍历函数,
-# 如"map","reduce","inject"等等。
+# 如 "map", "reduce", "inject" 等等。
# 以map为例,它会遍历数组,并根据你在
# 块中定义的逻辑对它进行处理,然后返回
# 一个全新的数组。
@@ -388,19 +412,26 @@ surround { puts 'hello world' }
# {
# hello world
# }
+# => nil
# 可以向函数传递一个块
# "&"标记传递的块是一个引用
def guests(&block)
- block.call 'some_argument'
+ block.class #=> Proc
+ block.call(4)
end
+guests { |n| "You have #{n} guests." }
+# => "You have 4 guests."
+
# 可以传递多个参数,这些参数会转成一个数组,
# 这也是使用星号符 ("*") 的原因:
def guests(*array)
array.each { |guest| puts guest }
end
+# 结构
+
# 如果函数返回一个数组,在赋值时可以进行拆分:
def foods
['pancake', 'sandwich', 'quesadilla']
@@ -409,21 +440,42 @@ breakfast, lunch, dinner = foods
breakfast #=> 'pancake'
dinner #=> 'quesadilla'
-# 按照惯例,所有返回布尔值的方法都以?结尾
+# 有些情况下,你会想使用解构操作符 `*` 来解构数组
+ranked_competitors = ["John", "Sally", "Dingus", "Moe", "Marcy"]
+
+def best(first, second, third)
+ puts "Winners are #{first}, #{second}, and #{third}."
+end
+
+best *ranked_competitors.first(3) #=> Winners are John, Sally, and Dingus.
+
+# 结构操作符也可放在参数里面
+def best(first, second, third, *others)
+ puts "Winners are #{first}, #{second}, and #{third}."
+ puts "There were #{others.count} other participants."
+end
+
+best *ranked_competitors
+#=> Winners are John, Sally, and Dingus.
+#=> There were 2 other participants.
+
+# 按照惯例,所有返回布尔值的方法都以 ? 结尾
5.even? # false
5.odd? # true
-# 如果方法名末尾有!,表示会做一些破坏性的操作,比如修改调用者自身。
-# 很多方法都会有一个!的版本来进行修改,和一个非!的版本
-# 只用来返回更新了的结果
+# 如果方法名末尾有感叹号 !,表示会做一些破坏性的操作,比如修改调用者自身。
+# 很多方法都会有一个 ! 的版本来进行修改,
+# 和一个只返回更新结果的非 ! 版本
company_name = "Dunder Mifflin"
company_name.upcase #=> "DUNDER MIFFLIN"
company_name #=> "Dunder Mifflin"
-company_name.upcase! # we're mutating company_name this time!
+# 这次我们修改了 company_name
+company_name.upcase! #=> "DUNDER MIFFLIN"
company_name #=> "DUNDER MIFFLIN"
+# 类
-# 用class关键字定义一个类
+# 用 class 关键字定义一个类
class Human
# 一个类变量,它被这个类的所有实例变量共享
@@ -431,30 +483,30 @@ class Human
# 基本构造函数
def initialize(name, age = 0)
- # 将参数值赋给实例变量"name"
+ # 将参数值赋给实例变量 "name"
@name = name
- # 如果没有给出age,那么会采用参数列表中的默认值
+ # 如果没有给出 age,那么会采用参数列表中的默认值
@age = age
end
- # 基本的setter方法
+ # 基本的 setter 方法
def name=(name)
@name = name
end
- # 基本地getter方法
+ # 基本地 getter 方法
def name
@name
end
- # 以上的功能也可以用下面的attr_accessor来封装
+ # 以上的功能也可以用下面的 attr_accessor 来封装
attr_accessor :name
- # Getter/setter方法也可以像这样单独创建
+ # Getter/setter 方法也可以像这样单独创建
attr_reader :name
attr_writer :name
- # 类方法通过使用self与实例方法区别开来。
+ # 类方法通过使用 self 与实例方法区别开来。
# 它只能通过类来调用,不能通过实例调用。
def self.say(msg)
puts "#{msg}"
@@ -468,7 +520,6 @@ end
# 初始化一个类
jim = Human.new("Jim Halpert")
-
dwight = Human.new("Dwight K. Schrute")
# 让我们来调用一些方法
@@ -483,15 +534,15 @@ dwight.name #=> "Dwight K. Schrute"
Human.say('Hi') #=> "Hi"
# 变量的作用域由它们的名字格式定义
-# 以$开头的变量具有全局域
+# 以 $ 开头的变量具有全局域
$var = "I'm a global var"
defined? $var #=> "global-variable"
-# 以@开头的变量具有实例作用域
+# 以 @ 开头的变量具有实例作用域
@var = "I'm an instance var"
defined? @var #=> "instance-variable"
-# 以@@开头的变量具有类作用域
+# 以 @@ 开头的变量具有类作用域
@@var = "I'm a class var"
defined? @@var #=> "class variable"
@@ -568,7 +619,6 @@ Book.foo # => 'foo'
Book.new.foo # => NoMethodError: undefined method `foo'
# 当包含或扩展一个模块时,相应的回调代码会被执行。
-
module ConcernExample
def self.included(base)
base.extend(ClassMethods)
diff --git a/zh-cn/solidity-cn.html.markdown b/zh-cn/solidity-cn.html.markdown
new file mode 100644
index 00000000..ec684997
--- /dev/null
+++ b/zh-cn/solidity-cn.html.markdown
@@ -0,0 +1,825 @@
+---
+language: Solidity
+filename: learnSolidity-cn.sol
+lang: zh-cn
+contributors:
+ - ["Nemil Dalal", "https://www.nemil.com"]
+ - ["Joseph Chow", ""]
+ - ["Bhoomtawath Plinsut", "https://github.com/varshard"]
+ - ["Shooter", "https://github.com/liushooter"]
+translators:
+ - ["Bob Jiang", "https://github.com/bobjiang"]
+---
+
+Solidity 使你在[以太坊](https://www.ethereum.org/)上编程,一个基于区块链的虚拟机,
+允许创建和执行智能合约,无需中心化的或可信的一方。
+
+Solidity 是一种与 Javascript 和 C 的相似的、静态类型的合约编程语言。与OOP(面向对象)中
+的对象一样,每个合约都包含状态变量、函数和公共数据类型。合约特定功能包括修饰符(guard)子句,
+事件通知的侦听器及自定义的全局变量。
+
+以太坊合约的例子包括众筹、投票以及盲拍(私密拍卖)。
+
+Solidity 代码中存在高风险和高成本的错误,因此你必须非常小心地进行测试并慢慢地发布。**随着
+以太坊的快速变化,本文档不可能是最新的,所以你应该关注最新的的 solidity 聊天室和以太网博客。
+照搬这里的代码,会存在重大错误或弃用代码模式的风险。(说人话--别照抄例子中的代码)**
+
+与其他代码不同,可能还需要添加如暂停、弃用和限制使用的设计模式,来降低风险。本文档主要讨论语法,
+因此排除了许多流行的设计模式。
+
+由于 Solidity 和以太坊正在积极开发,通常会标记为实验或 beta 特性,并很可能会更改。因此欢迎
+提交更改请求。
+
+```javascript
+// 首先,一个简单的银行合约
+// 允许存款、取款、以及检查余额
+
+// simple_bank.sol (注意 .sol 后缀)
+/* **** 例子开始 **** */
+
+// 声明源文件的编译器版本
+pragma solidity ^0.4.19;
+
+// 开始 Natspec 注释(三个斜杠)
+// 用作文档 - 及UI元素、动作的描述性数据
+
+/// @title SimpleBank
+/// @author nemild
+
+/* 'contract' 和其他语言的 'class' 类似 (类变量、继承等) */
+contract SimpleBank { // 单词首字母大写
+ // 声明函数外的状态变量,合约生命周期内可用
+
+ // 地址映射到余额的字典,总是要小心数字的溢出攻击
+ mapping (address => uint) private balances;
+
+ // "private" 的意思是其他合约不能直接查询余额,但对于区块链上的其他方来说,数据仍然是可见的。
+
+ address public owner;
+ // 'public' 使用户或合约可以从外部读取(不可写)
+
+ // Events(事件) - 向外部监听器发布动作
+ event LogDepositMade(address accountAddress, uint amount);
+
+ // Constructor(构造函数)(译者注:solidity 从0.4.22开始使用 constructor() 作为构造函数)
+ function SimpleBank() public {
+ // msg 提供了发送给合约的消息详情
+ // msg.sender 是合约的调用者(这里是合约创建者的地址)
+ owner = msg.sender;
+ }
+
+ /// @notice 存款 ether (以太币)
+ /// @return 存款后用户的余额
+ function deposit() public payable returns (uint) {
+ // 使用 'require' 来检测用户的输入,'assert' 是内部常量
+ // 我们要确保不会发生溢出问题(上溢)
+ require((balances[msg.sender] + msg.value) >= balances[msg.sender]);
+
+ balances[msg.sender] += msg.value;
+ // 状态变量不需要 "this." 或 "self."
+ // 默认情况下,所有值都设置为数据类型的初始值
+
+ LogDepositMade(msg.sender, msg.value); // 触发事件
+
+ return balances[msg.sender];
+ }
+
+ /// @notice 从银行取款以太币 (ether)
+ /// @dev 不会返回任何多余的以太币(ether)
+ /// @param withdrawAmount 取款的数量
+ /// @return 用户还剩下的余额
+ function withdraw(uint withdrawAmount) public returns (uint remainingBal) {
+ require(withdrawAmount <= balances[msg.sender]);
+
+ // 注意在发送任何交易,即通过 .transfer .send 调用外部函数之前,马上减掉取款数量
+ // 这可以允许调用者使用递归请求大于其余额的金额。目标是在调用外部函数之前提交状态,
+ // 包括.transfer / .send
+ balances[msg.sender] -= withdrawAmount;
+
+ // 这会自动引发失败,也就是说还原了更新的余额
+ msg.sender.transfer(withdrawAmount);
+
+ return balances[msg.sender];
+ }
+
+ /// @notice 获取余额
+ /// @return 用户的余额
+ // 'view' 防止函数编辑状态变量;允许函数本地运行或链下运行
+ function balance() view public returns (uint) {
+ return balances[msg.sender];
+ }
+}
+// ** 例子结束 **
+
+
+// 下面, solidity 基础
+
+// 1. 数据类型与关联的方法
+// uint 类型用作现金数量(没有双浮点型或单浮点型)及日期(用 unix 时间)
+uint x;
+
+// 256字节的 int, 实例化后不能改变
+int constant a = 8;
+int256 constant a = 8; // 和上一行一样,这里256字节显性化了
+uint constant VERSION_ID = 0x123A1; // 16进制常量
+// 'constant' 关键字, 编译器在每个出现的地方替换为实际的值
+
+// 所有的状态变量(函数之外的那些),默认是 'internal' 的,只能在合约及所有继承的合约内
+// 可以访问。需要显性的设置为 'public' 才能允许外部合约访问。
+int256 public a = 8;
+
+// 对于 int 和 uint,可以显性的设置位数(从8位到256位,8位跳跃),如int8, int16, int24
+uint8 b;
+int64 c;
+uint248 e;
+
+// 当心不要溢出以及免收此类攻击,例如,对于加法最好这么做:
+uint256 c = a + b;
+assert(c >= a); // assert 测试内部不变的值;require 用来测试用户输入
+// 更多通用算法问题的例子,参考 Zeppelin's SafeMath library
+// https://github.com/OpenZeppelin/zeppelin-solidity/blob/master/contracts/math/SafeMath.sol
+
+
+// 没有内建的随机函数,使用其他合约获得随机数
+
+// 类型转换
+int x = int(b);
+
+bool b = true; // 或 'var b = true;' 隐含的类型
+
+// 地址 - 20个字节或160位以太坊地址(16进制数字),不允许进行运算
+address public owner;
+
+// 账户类型:
+// 合约账户:在创建时设置地址(创建者地址函数,交易发送)
+// 外部账户:(个人账户)从公钥创建的地址
+
+// 'public' 的含义是自动创建的 getter 方法,而不是 setter 方法可以公开的、外部访问。
+
+// 所有地址都可以进行转账
+owner.transfer(SOME_BALANCE); // 失败后还原
+
+// 还可以调用较低级别的 .send , 转账失败会返回 false
+if (owner.send) {}
+// 记住:用 'if' 包着 send 函数,因为合约地址执行这些函数转账时,可能会失败
+// 另外,确保转账前先减掉余额,因为存在递归调用的风险。
+
+// 检查余额
+owner.balance; // 所有者的余额(用户或合约)
+
+
+// 字符类型,从1到32位可用
+byte a; // byte 等同于 byte1
+bytes2 b;
+bytes32 c;
+
+// 动态大小的字符
+bytes m; // 特殊的数组,等同于 byte[],比 byte1 到 byte32 更贵
+// 尽可能不用 bytes
+
+// 等同于 bytes,但不允许长度或索引的访问
+string n = "hello"; // UTF8存储,注意双引号而不是单引号
+// 字符功能未来会增加,推荐使用 bytes32 或 bytes
+
+// 推断类型
+// var 会根据第一次赋值决定类型,不能用来作为函数的参数
+var a = true;
+// 小心使用,推断可能带来错误的类型,例如,int8,而计数器需要的是 int16
+
+// 函数可以用 var 类型赋值给变量
+function a(uint x) returns (uint) {
+ return x * 2;
+}
+var f = a;
+f(22); // 调用
+
+// 默认的,所有值实例化后都设为 0
+
+// 大多数类型上可以调用删除(不会销毁值,而是设置为0,初始值)
+uint x = 5;
+
+
+// 集合
+(x, y) = (2, 7); // 多值的赋值
+
+
+// 2. 数据结构
+// 数组
+bytes32[5] nicknames; // 静态数组
+bytes32[] names; // 动态数组
+uint newLength = names.push("John"); // 添加返回数组的新长度
+// 长度
+names.length; // 获得数组长度
+names.length = 1; // 可以设定长度(仅针对 storage 中的动态数组)
+
+// 多维数组
+uint x[][5]; // 5个动态数组元素的数组(和多数语言的顺序相反)
+
+// 字典类型 (任一类型到其他类型的映射)
+mapping (string => uint) public balances;
+balances["charles"] = 1;
+// balances["ada"]得到 0, 所有没有设定key值的,返回0
+// 'public' 允许跟着(调用)另一份合约
+contractName.balances("charles"); // returns 1
+// 'public' 创建 getter (而不是 setter )如下:
+function balances(string _account) returns (uint balance) {
+ return balances[_account];
+}
+
+// 内嵌的 mapping
+mapping (address => mapping (address => uint)) public custodians;
+
+// 删除
+delete balances["John"];
+delete balances; // 所有元素设为 0
+
+// 不像其他语言,不知道 keys 的话不能列出 mapping 中的所有元素 - 可以在这之上构建数据结构
+
+// 结构
+struct Bank {
+ address owner;
+ uint balance;
+}
+Bank b = Bank({
+ owner: msg.sender,
+ balance: 5
+});
+// 或
+Bank c = Bank(msg.sender, 5);
+
+c.balance = 5; // 设为新值
+delete b;
+// 设为初始值,结构内所有变量设为0,除了 mapping
+
+// 枚举
+enum State { Created, Locked, Inactive }; // 常常作为状态机
+State public state; // 声明枚举变量
+state = State.Created;
+// 枚举类型可以显性化的转换为 ints
+uint createdState = uint(State.Created); // 0
+
+// 数据位置:内存(Memory) vs. 存储(storage) vs. 调用数据(calldata)
+// 所有复杂类型(数据、结构)都有一个数据位置,内存数据不持久,而存储的数据是持久的。
+// 本地变量和状态变量默认是存储,函数参数默认是内存。堆栈存放较小的本地变量
+
+// 多数类型,可以显性化的设定使用的数据位置
+
+
+// 3. 简单操作符
+// solidity 提供了比较、位运算及数学运算的功能
+// 指数运算: **
+// 异或运算: ^
+// 按位取反: ~
+
+
+// 4. 值得注意的全局变量
+// ** this **
+this; // 合约的地址
+// 常常用在合约生命周期结束前,转走剩下的余额
+this.balance;
+this.someFunction(); // 通过 call 的方式而不是内部跳转的方式,从外部调用函数
+
+// ** msg - 合约收到的当前消息 ** **
+msg.sender; // 发送者的地址
+msg.value; // 该合约内的以太币数量(单位 wei),该函数应该标记为 "payable"
+msg.data; // 字符,完整的调用数据
+msg.gas; // 剩余 gas
+
+// ** tx - 交易信息 **
+tx.origin; // 本次交易的发送者地址
+tx.gasprice; // 本次交易的 gas price
+
+// ** block - 当前区块信息 **
+now; // 当前时间(大概)block.timestamp的别名 (采用的 Unix 时间)
+// 注意这个可能被矿工操纵,因此请小心使用
+
+block.number; // 当前区块号
+block.difficulty; // 当前区块难度
+block.blockhash(1); // 返回 bytes32,只对最近 256 个区块有效
+block.gasLimit();
+
+// ** 存储 - 持久化存储哈希 **
+storage['abc'] = 'def'; // 256 位单词 到 256 位单词的映射
+
+
+// 4. 函数及更多
+// A. 函数
+// 简单函数
+function increment(uint x) returns (uint) {
+ x += 1;
+ return x;
+}
+
+// 函数可以通过指定返回的参数名,来返回多个参数
+function increment(uint x, uint y) returns (uint x, uint y) {
+ x += 1;
+ y += 1;
+}
+// 调用前一个函数
+uint (a,b) = increment(1,1);
+
+// 'view' ('constant'的别名)
+// 表明函数不会改变持久化的变量,View函数会本地执行,而不是链上运行。
+// 注意:constant 关键字很快会废弃。
+uint y = 1;
+
+function increment(uint x) view returns (uint x) {
+ x += 1;
+ y += 1; // 这一行会失败
+ // y 是一个状态变量,不能在 view 的函数里改变 y
+}
+
+// 'pure' 比 'view' 或 'constant' 更加严格,甚至不允许读取状态变量
+// 具体的规则很复杂,请参考
+// view/pure:
+// http://solidity.readthedocs.io/en/develop/contracts.html#view-functions
+
+// '函数可见性指示器'
+// 'view'可以有以下修饰符,包括:
+// public - 内部及外部可见(函数的默认值)
+// external - 仅外部可见(包括 this 发起的调用)
+// private - 仅当前合约可见
+// internal - 仅当前合约及继承的合约可见
+
+// 通常,显性的标记每个函数是个好主意
+
+// 函数的挂起 - 可以将函数赋值给变量
+function a() {
+ var z = b;
+ b();
+}
+
+function b() {
+
+}
+
+// 所有接收 ether 的函数必须标记为 'payable'
+function depositEther() public payable {
+ balances[msg.sender] += msg.value;
+}
+
+
+// 首选循环来递归(最大的调用堆栈深度是 1024),另外不要设置没有限制的循环,
+// 因为这可能会达到 gas limit
+
+// B. 事件
+// 事件通知外部各方; 易于搜索和访问来自外部区块链(使用轻客户端)的事件
+// 通常在合约参数之后声明
+
+// 通常,首字母大写并在前面加上 Log ,防止与函数混淆
+
+// 声明
+event LogSent(address indexed from, address indexed to, uint amount); // 注意 capital first letter
+
+// 调用
+LogSent(from, to, amount);
+
+/*
+ // 对于外部方(合约或外部实体),使用 Web3 Javascript 库来监听
+ // 以下是javascript代码,不是solidity代码
+ Coin.LogSent().watch({}, '', function(error, result) {
+ if (!error) {
+ console.log("Coin transfer: " + result.args.amount +
+ " coins were sent from " + result.args.from +
+ " to " + result.args.to + ".");
+ console.log("Balances now:\n" +
+ "Sender: " + Coin.balances.call(result.args.from) +
+ "Receiver: " + Coin.balances.call(result.args.to));
+ }
+ }
+
+*/
+
+// 一个合约依赖另一个合约的共同范例(例如,合约取决于另一个合约提供的当前汇率)
+
+// C. 修饰器
+// 修饰器验证函数的输入,例如最小余额或用户身份验证; 类似于其他语言的保护子句
+
+// '_' (下划线)经常用在代码的最后一行,表明被调用的函数放在那里
+modifier onlyAfter(uint _time) { require (now >= _time); _; }
+modifier onlyOwner { require(msg.sender == owner) _; }
+// 常用于状态机
+modifier onlyIfStateA (State currState) { require(currState == State.A) _; }
+
+// 修饰器紧跟在函数声明之后
+function changeOwner(newOwner)
+onlyAfter(someTime)
+onlyOwner()
+onlyIfState(State.A)
+{
+ owner = newOwner;
+}
+
+// 下划线可以包含在代码结束之前,但明显地返回将跳过后面的代码,因此谨慎使用
+modifier checkValue(uint amount) {
+ _;
+ if (msg.value > amount) {
+ uint amountToRefund = amount - msg.value;
+ msg.sender.transfer(amountToRefund);
+ }
+}
+
+
+// 6. 判断和循环
+
+// 所有基本的逻辑判断都有效 - 包括 if else, for, while, break, continue
+// return - 但不跳转
+
+// 语法同 javascript, 但没有从非布尔值到布尔值的类型转换
+// (必须使用比较操作符获得布尔变量值)
+
+// 请注意由用户行为决定的循环 - 因为合约对于代码块具有最大量的 gas 限制 -
+// 如果超过限制该代码则将失败
+// 例如:
+for(uint x = 0; x < refundAddressList.length; x++) {
+ refundAddressList[x].transfer(SOME_AMOUNT);
+}
+
+// 上述两个错误:
+// 1. 转账失败会阻塞循环完成,钱被占用
+// 2. 该循环可能会很长(根据需要赔偿的用户数量而定),并且也可能由于超过一个区块最大 gas 限制
+// 而总是失败。你应该让人们自己从他们的子账户取款并标记取款完成
+// 例如,首选拉动式的付款,而不是推动式的付款
+
+
+// 7. 对象与合约
+
+// A. 调用外部合约
+contract InfoFeed {
+ function info() returns (uint ret) { return 42; }
+}
+
+contract Consumer {
+ InfoFeed feed; // 指向区块链上的一个合约
+
+ // 设置 feed 为已存在的合约实例
+ function setFeed(address addr) {
+ // 当心类型自动转换;不会调用构造函数
+ feed = InfoFeed(addr);
+ }
+
+ // 设置 feed 为一个合约的新实例
+ function createNewFeed() {
+ feed = new InfoFeed(); // 创建新实例,调用构造函数
+ }
+
+ function callFeed() {
+ // 最后的括号调用合约,可选择的增加自定义的 ether 或 gas 价格
+ feed.info.value(10).gas(800)();
+ }
+}
+
+// B. 继承
+
+// 和顺序有关,最后继承的合约(如 'def')可以覆盖之前已继承合约的部分
+contract MyContract is abc, def("a custom argument to def") {
+
+// 覆盖函数
+ function z() {
+ if (msg.sender == owner) {
+ def.z(); // 调用覆盖的函数
+ super.z(); // 调用继承的上层合约的函数
+ }
+ }
+}
+
+// 抽象函数
+function someAbstractFunction(uint x);
+// 不可以编译,因此用在基础或抽象合约中,等待实现
+
+// C. 导入
+
+import "filename";
+import "github.com/ethereum/dapp-bin/library/iterable_mapping.sol";
+
+
+// 8. 其他关键字
+
+// A. 自毁
+// 自毁当前的合约,转账资金到一个地址(常常是创建者的地址)
+selfdestruct(SOME_ADDRESS);
+
+// 从当前或以后的区块中移除存储或代码,会帮助客户端瘦身,但之前的数据会永久在区块链中
+
+// 常见模式,让所有者结束合约并收回剩余的资金
+function remove() {
+ if(msg.sender == creator) { // 只有合约的创建者可以这么做
+ selfdestruct(creator); // 自毁合约,返还资金
+ }
+}
+
+// 可能希望手动停用合约,而不是自毁
+// (发送到自毁合约的 ether 会丢失掉)
+
+
+// 9. 注意合约的设计
+
+// A. 困惑
+// 区块链上所有变量都是公开可见的,因此任何私有的需求变得很困惑。(好比哈希的秘密)
+
+// 步骤: 1. 承诺某事, 2. 揭示承诺
+keccak256("some_bid_amount", "some secret"); // commit
+
+// 以后调用合约的 reveal 函数,展示出用 SHA3 哈希的 bid 加 secret
+reveal(100, "mySecret");
+
+// B. 存储优化
+// 写入区块链可能很昂贵,因为数据是永久存储的;鼓励用巧妙的方法使用内存
+//(最终,编译会更好,但现在有利于规划数据结构 - 并将最小数量存储在区块链中)
+
+// 多维数组这样的变量可能会成本很高
+// (成本用于存储数据 - 而不是声明未填充的变量)
+
+// C. 区块链中的数据访问
+// 不能限制人或计算机读取交易或交易状态的内容
+
+// 然而 'private' 可以防止其他*合约*直接读取数据 - 任意其他方仍然可以从区块链读取数据
+
+// 从开始的所有数据都存在区块链上,因此任何人都可以查看之前的所有数据和变化
+
+// D. 定时任务
+// 必须手动调用合约来处理时间相关的调度;也可以创建外部代码来定期的ping,
+// 或为其他人提供激励(以太)
+
+// E. 观察者模式
+//观察者模式允许您注册为订阅者,然后注册一个由oracle调用的函数
+//(注意,oracle 需要付费来运行此操作)。与 Pub / sub 中的订阅有些相似之处
+
+// 这是一个抽象合约,包括客户端和服务器端的类的导入,客户端应该要实现
+contract SomeOracleCallback {
+ function oracleCallback(int _value, uint _time, bytes32 info) external;
+}
+
+contract SomeOracle {
+ SomeOracleCallback[] callbacks; // 所有订阅者的数组
+
+ // 注册订阅者
+ function addSubscriber(SomeOracleCallback a) {
+ callbacks.push(a);
+ }
+
+ function notify(value, time, info) private {
+ for(uint i = 0;i < callbacks.length; i++) {
+ // 所有调用的订阅者必须实现 oracleCallback
+ callbacks[i].oracleCallback(value, time, info);
+ }
+ }
+
+ function doSomething() public {
+ // 实现的代码
+
+ // 通知所有的订阅者
+ notify(_value, _time, _info);
+ }
+}
+
+// 现在你的客户端合约可以通过 importing SomeOracleCallback 和注册某些 Oracle 来
+// addSubscriber 添加订阅者
+
+// F. 状态机
+// 参见如下的例子,枚举类型的 State 和 修饰器 inState
+
+
+// *** 例子: 众筹的例子(与 Kickstarter 大致相似)***
+// ** 开始例子 **
+
+// CrowdFunder.sol
+pragma solidity ^0.4.19;
+
+/// @title CrowdFunder
+/// @author nemild
+/// @translator bobjiang
+contract CrowdFunder {
+ // 由创建者创建的变量
+ address public creator;
+ address public fundRecipient; // 创建者可能和收件人不同
+ uint public minimumToRaise; // 需要提示,否则每个人都会得到退款
+ string campaignUrl;
+ byte constant version = 1;
+
+ // 数据结构
+ enum State {
+ Fundraising,
+ ExpiredRefund,
+ Successful
+ }
+ struct Contribution {
+ uint amount;
+ address contributor;
+ }
+
+ // 状态变量State variables
+ State public state = State.Fundraising; // 创建时实例化
+ uint public totalRaised;
+ uint public raiseBy;
+ uint public completeAt;
+ Contribution[] contributions;
+
+ event LogFundingReceived(address addr, uint amount, uint currentTotal);
+ event LogWinnerPaid(address winnerAddress);
+
+ modifier inState(State _state) {
+ require(state == _state);
+ _;
+ }
+
+ modifier isCreator() {
+ require(msg.sender == creator);
+ _;
+ }
+
+ // 允许合约销毁之前,最终合约状态后要等待24周
+ modifier atEndOfLifecycle() {
+ require(((state == State.ExpiredRefund || state == State.Successful) &&
+ completeAt + 24 weeks < now));
+ _;
+ }
+
+ function CrowdFunder(
+ uint timeInHoursForFundraising,
+ string _campaignUrl,
+ address _fundRecipient,
+ uint _minimumToRaise)
+ public
+ {
+ creator = msg.sender;
+ fundRecipient = _fundRecipient;
+ campaignUrl = _campaignUrl;
+ minimumToRaise = _minimumToRaise;
+ raiseBy = now + (timeInHoursForFundraising * 1 hours);
+ }
+
+ function contribute()
+ public
+ payable
+ inState(State.Fundraising)
+ returns(uint256 id)
+ {
+ contributions.push(
+ Contribution({
+ amount: msg.value,
+ contributor: msg.sender
+ }) // 采用数组,因此可以遍历
+ );
+ totalRaised += msg.value;
+
+ LogFundingReceived(msg.sender, msg.value, totalRaised);
+
+ checkIfFundingCompleteOrExpired();
+ return contributions.length - 1; // 返回 id
+ }
+
+ function checkIfFundingCompleteOrExpired()
+ public
+ {
+ if (totalRaised > minimumToRaise) {
+ state = State.Successful;
+ payOut();
+
+ // 可以激励在这里发起状态改变的人
+ } else if ( now > raiseBy ) {
+ state = State.ExpiredRefund; // 支持者可以通过调用 getRefund(id) 收取退款
+ }
+ completeAt = now;
+ }
+
+ function payOut()
+ public
+ inState(State.Successful)
+ {
+ fundRecipient.transfer(this.balance);
+ LogWinnerPaid(fundRecipient);
+ }
+
+ function getRefund(uint256 id)
+ inState(State.ExpiredRefund)
+ public
+ returns(bool)
+ {
+ require(contributions.length > id && id >= 0 && contributions[id].amount != 0 );
+
+ uint256 amountToRefund = contributions[id].amount;
+ contributions[id].amount = 0;
+
+ contributions[id].contributor.transfer(amountToRefund);
+
+ return true;
+ }
+
+ function removeContract()
+ public
+ isCreator()
+ atEndOfLifecycle()
+ {
+ selfdestruct(msg.sender);
+ // 创建者获得所有未被声明的钱
+ }
+}
+// ** 结束例子 **
+
+// 10. 其他原生的函数
+
+// 货币单位
+// 货币使用 wei 来定义,以太币的最小单位 = 1 wei;
+uint minAmount = 1 wei;
+uint a = 1 finney; // 1 ether == 1000 finney
+// 其他单位,请参阅: http://ether.fund/tool/converter
+
+// 时间单位
+1 == 1 second
+1 minutes == 60 seconds
+
+// 可以乘以带时间单位的变量,因为单位不会存储在变量中
+uint x = 5;
+(x * 1 days); // 5 天
+
+// 小心闰秒闰年与平等声明的时间
+// (相反,首选大于或小于)
+
+// 加密算法
+// 传递的所有字符串在哈希操作之前需要连接在一起
+sha3("ab", "cd");
+ripemd160("abc");
+sha256("def");
+
+// 11. 安全
+
+// 以太坊的合约中,错误可能是灾难性的 - 即使在 solidity 中是流行的模式,也可能发现是反模式的
+
+// 参见文档底部的安全链接
+
+// 12. 较低层次的函数
+// call - 较低层次,不会经常使用,不提供类型安全性
+successBoolean = someContractAddress.call('function_name', 'arg1', 'arg2');
+
+// callcode - 在调用合约的*上下文*中执行的目标地址上的代码
+// 提供库功能
+someContractAddress.callcode('function_name');
+
+
+// 13. 注意风格
+// 基于 Python 的 PEP8 风格指南
+// 全部风格指南: http://solidity.readthedocs.io/en/develop/style-guide.html
+
+// 快速总结:
+// 4个空格缩进
+// 两行隔开合约声明(和其他高级别的声明)
+// 避免括号内留出多余的空格
+// 可以省略一行语句的花括号 (if, for, 等)
+// else 应该单独一行
+
+
+// 14. NATSPEC 注释
+// 用于文档、注释和外部UI
+
+// 合约的 natspec - 总是在合约定义的上面
+/// @title 合约标题
+/// @author 作者名字
+
+// 函数的 natspec
+/// @notice 函数做什么的相关信息;展示什么时候执行该函数、
+/// @dev 开发者使用的函数文档
+
+// 函数参数、返回值的 natspec
+/// @param 有关参数用途的描述
+/// @return 返回值的描述
+```
+
+## 更多资源
+- [Solidity Docs](https://solidity.readthedocs.org/en/latest/)
+- [Smart Contract Best Practices](https://github.com/ConsenSys/smart-contract-best-practices)
+- [EthFiddle - The JsFiddle for Solidity](https://ethfiddle.com/)
+- [Browser-based Solidity Editor](https://remix.ethereum.org/)
+- [Gitter Solidity Chat room](https://gitter.im/ethereum/solidity)
+- [Modular design strategies for Ethereum Contracts](https://docs.erisindustries.com/tutorials/solidity/)
+
+## 重要的库文件
+- [Zeppelin](https://github.com/OpenZeppelin/zeppelin-solidity/): Libraries that provide common contract patterns (crowdfuding, safemath, etc)
+
+## 示例合约
+- [Dapp Bin](https://github.com/ethereum/dapp-bin)
+- [Solidity Baby Step Contracts](https://github.com/fivedogit/solidity-baby-steps/tree/master/contracts)
+- [ConsenSys Contracts](https://github.com/ConsenSys/dapp-store-contracts)
+- [State of Dapps](http://dapps.ethercasts.com/)
+
+## 安全
+- [Thinking About Smart Contract Security](https://blog.ethereum.org/2016/06/19/thinking-smart-contract-security/)
+- [Smart Contract Security](https://blog.ethereum.org/2016/06/10/smart-contract-security/)
+- [Hacking Distributed Blog](http://hackingdistributed.com/)
+
+## 风格
+- [Solidity Style Guide](http://solidity.readthedocs.io/en/latest/style-guide.html): Ethereum's style guide is heavily derived from Python's [PEP 8](https://www.python.org/dev/peps/pep-0008/) style guide.
+
+## 编辑器
+- [Emacs Solidity Mode](https://github.com/ethereum/emacs-solidity)
+- [Vim Solidity](https://github.com/tomlion/vim-solidity)
+- Editor Snippets ([Ultisnips format](https://gist.github.com/nemild/98343ce6b16b747788bc))
+
+## Future to Dos
+- 新关键字: protected, inheritable
+- 常见设计模式列表 (throttling, RNG, version upgrade)
+- 常见的安全反模式
+
+请随意发送 pull request 或者发邮件给作者 nemild -/at-/ gmail
+
+或者发邮件给译者 jiangxb -/at-/ gmail.com
diff --git a/zh-cn/sql.html.markdown b/zh-cn/sql.html.markdown
new file mode 100644
index 00000000..9d430bd1
--- /dev/null
+++ b/zh-cn/sql.html.markdown
@@ -0,0 +1,105 @@
+---
+language: SQL
+filename: learnsql.sql
+contributors:
+ - ["Bob DuCharme", "http://bobdc.com/"]
+translators:
+ - ["Shuxin Shu", "https://github.com/NamelessAshone"]
+lang: zh-cn
+---
+
+结构化查询语言(SQL)是一个ISO标准语言,用于创建和管理数据库,
+这种数据库存储一系列表。不同的实现通常会添加特有的语言扩展;
+[不同SQL实现的比较(Comparison of different SQL implementat-
+ions)](http://troels.arvin.dk/db/rdbms/)是一份很好的产品差
+异参考文档。
+
+不同的实现通常会提供一个命令行用于交互式键入命令和显示输出,
+同时这些实现也会提供一种执行脚本文件的方法。(如何退出命令行
+就是就是SQL中尚未被标准化部分的一个典型例子,绝大多数SQL实
+现支持关键字QUIT、EXIT或者两者。)
+
+本文的实例命令假设你已经加载了[github](https://github.com/datacharmer/test_db)上的[MySQL示例员工数据库](https://dev.mysql.com/doc/employee/en/)。
+运行脚本的语法取决于你使用的SQL实现。通常是一个命令行工具。
+
+```sql
+
+-- 注释以两个连字符开始。命令以分号结束。
+
+-- SQL关键字大小写不敏感。在下文的示例命令中关键字大写,
+-- 因为大写更容易区分数据库、表和列名。
+
+-- 创建和删除一个数据库。数据库名和表名是大小写敏感的。
+CREATE DATABASE someDatabase;
+DROP DATABASE someDatabase;
+
+-- 列出可用的数据库。
+SHOW DATABASES;
+
+-- 使用某个已经存在的数据库
+USE employees;
+
+-- 从当前的departments表,选择所有的行和列
+-- 解释器的默认行为是将结果打印在屏幕上。
+SELECT * FROM departments;
+
+-- 检索departments表中所有的行,但只取dept_no和dept_name列。
+-- 一条命令可以跨越多行
+SELECT dept_no,
+ dept_name FROM departments;
+
+-- 检索departments表中所有的行,但是只输出5行。
+SELECT * FROM departments LIMIT 5;
+
+-- 检索departments表中dept_name列包含子串'en'的行。
+SELECT dept_name FROM departments WHERE dept_name LIKE '%en%';
+
+-- 检索departmnets表中所有dept_name列值为'S'开头并且'S'后接4个字符的行。
+SELECT * FROM departments WHERE dept_name LIKE 'S____';
+
+-- 检索title表中所有行,不显示重复的行。
+SELECT DISTINCT title FROM titles;
+
+-- 和上面的查询相同,但是以title的值排序(大小写敏感)。
+SELECT DISTINCT title FROM titles ORDER BY title;
+
+-- 计算departments表的总行数。
+SELECT COUNT(*) FROM departments;
+
+-- 计算departments表中dept_name列以'en'字段开头的行的数量。
+SELECT COUNT(*) FROM departments WHERE dept_name LIKE '%en%';
+
+-- 不同表中信息的JOIN: titles表显示谁有什么工作,员工编号,
+-- 入职离职时间。检索这些信息,但是使用员工编号作为employees表
+-- 的交叉引用,而不是直接使用员工编号,来获得每个员工的名和姓。
+-- (同时只取10行)
+
+SELECT employees.first_name, employees.last_name,
+ titles.title, titles.from_date, titles.to_date
+FROM titles INNER JOIN employees ON
+ employees.emp_no = titles.emp_no LIMIT 10;
+
+-- 列出所有数据库中所有的表。不同实现通常提供各自的快捷命令
+-- 来列出当前使用数据库的所有表。
+SELECT * FROM INFORMATION_SCHEMA.TABLES
+WHERE TABLE_TYPE='BASE TABLE';
+
+-- 在当前使用的数据库中,创建一个名为tablename1的表,包含下
+-- 述两列。许多其它选项可用于定制列,比如列的数据类型。
+CREATE TABLE tablename1 (fname VARCHAR(20), lname VARCHAR(20));
+
+-- 向tablename1表插入一行数据。假设该表已经定义并且接受这些值。
+INSERT INTO tablename1 VALUES('Richard','Mutt');
+
+-- 更新tablename1表中lname为'Mutt'的行fname的值改为'John'。
+UPDATE tablename1 SET fname='John' WHERE lname='Mutt';
+
+-- 删除tablename1表lname列以'M'开头的行。
+DELETE FROM tablename1 WHERE lname like 'M%';
+
+-- 删除tablename1表的所有行,留下空表。
+DELETE FROM tablename1;
+
+-- 删除整个tablename1表。
+DROP TABLE tablename1;
+```
diff --git a/zh-tw/python-tw.html.markdown b/zh-tw/python-tw.html.markdown
index 553181d8..cd7481d7 100644
--- a/zh-tw/python-tw.html.markdown
+++ b/zh-tw/python-tw.html.markdown
@@ -627,7 +627,7 @@ i.age # => raises an AttributeError
# 你可以引入模組來做使用
import math
-print math.sqrt(16) # => 4
+print math.sqrt(16) # => 4.0
# math.sqrt()為取根號
# 你可以只從模組取出特定幾個函式