Professional Documents
Culture Documents
Learnxinyminutes PDF
Learnxinyminutes PDF
Basic concept
// The basic AMD API consists of nothing but two methods: `define` and `require`
// and is all about module definition and consumption:
// `define(id?, dependencies?, factory)` defines a module
// `require(dependencies, callback)` imports a set of dependencies and
// consumes them in the passed callback
// Now, let's define another module that depends upon our `awesomeAMD` module.
// Notice that there's an additional argument defining our
// module's dependencies now:
define('loudmouth', ['awesomeAMD'], function(awesomeAMD){
// dependencies will be passed to the factory's arguments
// in the order they are specified
var tellEveryone = function(){
if (awesomeAMD()){
alert('This is sOoOo rad!');
} else {
alert('Pretty dull, isn\'t it?');
}
};
return tellEveryone;
});
1
// To make this tutorial run code, let's implement a very basic
// (non-asynchronous) version of AMD right here on the spot:
function define(name, deps, factory){
// notice how modules without dependencies are handled
define[name] = require(factory ? deps : [], factory || deps);
}
In contrast to the introductory example, require.js (the most popular AMD library) actually implements
the A in AMD, enabling you to load modules and their dependencies asynchronously via XHR:
/* file: app/main.js */
require(['modules/someClass'], function(SomeClass){
// the callback is deferred until the dependency is loaded
var thing = new SomeClass();
});
console.log('So here we are, waiting!'); // this will run first
By convention, you usually store one module in one file. require.js can resolve module names based on
file paths, so you don’t have to name your modules, but can simply reference them using their location. In
the example someClass is assumed to be in the modules folder, relative to your configuration’s baseUrl:
• app/
• main.js
• modules/
– someClass.js
– someHelpers.js
– …
• daos/
– things.js
– …
This means we can define someClass without specifying a module id:
/* file: app/modules/someClass.js */
define(['daos/things', 'modules/someHelpers'], function(thingsDao, helpers){
// module definition, of course, will also happen asynchronously
function SomeClass(){
this.method = function(){/**/ };
// ...
}
2
return SomeClass;
});
To alter the default path mapping behavior use requirejs.config(configObj) in your main.js:
/* file: main.js */
requirejs.config({
baseUrl : 'app',
paths : {
// you can also load modules from other locations
jquery : '//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min',
coolLibFromBower : '../bower_components/cool-lib/coollib'
}
});
require(['jquery', 'coolLibFromBower', 'modules/someHelpers'], function($, coolLib, helpers){
// a `main` file needs to call require at least once,
// otherwise no code will ever run
coolLib.doFancyStuffWith(helpers.transform($('#foo')));
});
require.js-based apps will usually have a single entry point (main.js) that is passed to the require.js
script tag as a data-attribute. It will be automatically loaded and executed on pageload:
<!DOCTYPE html>
<html>
<head>
<title>A hundred script tags? Never again!</title>
</head>
<body>
<script src="require.js" data-main="app/main"></script>
</body>
</html>
Many people prefer using AMD for sane code organization during development, but still want to ship a single
script file in production instead of performing hundreds of XHRs on page load.
require.js comes with a script called r.js (that you will probably run in node.js, although Rhino is
supported too) that can analyse your project’s dependency graph, and build a single file containing all your
modules (properly named), minified and ready for consumption.
Install it using npm:
$ npm install requirejs -g
Now you can feed it with a configuration file:
$ r.js -o app.build.js
For our above example the configuration might look like:
/* file : app.build.js */
({
name : 'main', // name of the entry point
out : 'main-built.js', // name of the file to write the output to
baseUrl : 'app',
paths : {
// `empty:` tells r.js that this should still be loaded from the CDN, using
// the location specified in `main.js`
3
jquery : 'empty:',
coolLibFromBower : '../bower_components/cool-lib/coollib'
}
})
To use the built file in production, simply swap data-main:
<script src="require.js" data-main="app/main-built"></script>
An incredibly detailed overview of build options is available in the GitHub repo.
Further reading:
• Official Spec
• Why AMD?
• Universal Module Definition
Implementations:
• require.js
• dojo toolkit
• cujo.js
• curl.js
• lsjs
• mmd
Asciidoc
AsciiDoc is a markup language similar to Markdown and it can be used for anything from books to blogs.
Created in 2002 by Stuart Rackham the language is simple but it allows for a great amount of customization.
Document Header
Headers are optional and can’t contain blank lines. It must be offset from content by at least one blank line.
Title Only
= Document Title
4
Multiple Authors
= Document Title
John Doe <[email protected]>; Jane Doe<[email protected]>; Black Beard <[email protected]>
== Level 1 <h2>
5
* foo 1
** foo 2
*** foo 3
**** foo 4
***** foo 5
. foo 1
.. foo 2
... foo 3
.... foo 4
..... foo 5
Asymptotic Notations
6
Quadratic Function - an^2 + bn + c
Polynomial Function - an^z + . . . + an^2 + a*n^1 + a*n^0, where z is some
constant
Exponential Function - a^n, where a is some constant
These are some basic function growth classifications used in various notations. The list starts at the slowest
growing function (logarithmic, fastest execution time) and goes on to the fastest growing (exponential,
slowest execution time). Notice that as ‘n’, or the input, increases in each of those functions, the result
clearly increases much quicker in quadratic, polynomial, and exponential, compared to logarithmic and
linear.
One extremely important note is that for the notations about to be discussed you should do your best to
use simplest terms. This means to disregard constants, and lower order terms, because as the input size (or
n in our f(n) example) increases to infinity (mathematical limits), the lower order terms and constants are
of little to no importance. That being said, if you have constants that are 2ˆ9001, or some other ridiculous,
unimaginable amount, realize that simplifying will skew your notation accuracy.
Since we want simplest form, lets modify our table a bit…
Logarithmic - log n
Linear - n
Quadratic - n^2
Polynomial - n^z, where z is some constant
Exponential - a^n, where a is some constant
Big-O
Big-O, commonly written as O, is an Asymptotic Notation for the worst case, or ceiling of growth for a given
function. It provides us with an asymptotic upper bound for the growth rate of runtime of an algorithm.
Say f(n) is your algorithm runtime, and g(n) is an arbitrary time complexity you are trying to relate to
your algorithm. f(n) is O(g(n)), if for some real constant c (c > 0), f(n) <= c g(n) for every input size n
(n > 0).
Example 1
f(n) = 3log n + 100
g(n) = log n
Is f(n) O(g(n))? Is 3 log n + 100 O(log n)? Let’s look to the definition of Big-O.
3log n + 100 <= c * log n
Is there some constant c that satisfies this for all n?
3log n + 100 <= 150 * log n, n > 2 (undefined at n = 1)
Yes! The definition of Big-O has been met therefore f(n) is O(g(n)).
Example 2
f(n) = 3*n^2
g(n) = n
Is f(n) O(g(n))? Is 3 * nˆ2 O(n)? Let’s look at the definition of Big-O.
3 * n^2 <= c * n
Is there some constant c that satisfies this for all n? No, there isn’t. f(n) is NOT O(g(n)).
7
Big-Omega
Big-Omega, commonly written as Ω, is an Asymptotic Notation for the best case, or a floor growth rate for
a given function. It provides us with an asymptotic lower bound for the growth rate of runtime of an
algorithm.
f(n) is Ω(g(n)), if for some real constant c (c > 0), f(n) is >= c g(n) for every input size n (n > 0).
Note
The asymptotic growth rates provided by big-O and big-omega notation may or may not be asymptotically
tight. Thus we use small-o and small-omega notation to denote bounds that are not asymptotically tight.
Small-o
Small-o, commonly written as o, is an Asymptotic Notation to denote the upper bound (that is not asymp-
totically tight) on the growth rate of runtime of an algorithm.
f(n) is o(g(n)), if for any real constant c (c > 0), f(n) is < c g(n) for every input size n (n > 0).
The definitions of O-notation and o-notation are similar. The main difference is that in f(n) = O(g(n)), the
bound f(n) <= g(n) holds for some constant c > 0, but in f(n) = o(g(n)), the bound f(n) < c g(n) holds
for all constants c > 0.
Small-omega
Small-omega, commonly written as �, is an Asymptotic Notation to denote the lower bound (that is not
asymptotically tight) on the growth rate of runtime of an algorithm.
f(n) is �(g(n)), if for any real constant c (c > 0), f(n) is > c g(n) for every input size n (n > 0).
The definitions of Ω-notation and �-notation are similar. The main difference is that in f(n) = Ω(g(n)), the
bound f(n) >= g(n) holds for some constant c > 0, but in f(n) = �(g(n)), the bound f(n) > c g(n) holds for
all constants c > 0.
Theta
Theta, commonly written as Θ, is an Asymptotic Notation to denote the asymptotically tight bound on
the growth rate of runtime of an algorithm.
f(n) is Θ(g(n)), if for some real constants c1, c2 (c1 > 0, c2 > 0), c1 g(n) is < f(n) is < c2 g(n) for every
input size n (n > 0).
� f(n) is Θ(g(n)) implies f(n) is O(g(n)) as well as f(n) is Ω(g(n)).
Feel free to head over to additional resources for examples on this. Big-O is the primary notation use for
general algorithm time complexity.
Ending Notes
It’s hard to keep this kind of topic short, and you should definitely go through the books and online resources
listed. They go into much greater depth with definitions and examples. More where x=‘Algorithms & Data
Structures’ is on its way; we’ll have a doc up on analyzing actual code examples soon.
8
Books
• Algorithms
• Algorithm Design
Online Resources
• MIT
• KhanAcademy
• Big-O Cheatsheet - common structures, operations, and algorithms, ranked by complexity.
Bash
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.
Another recommened link: The Command Line Crash Course
#!/bin/bash
# First line of the script is 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.
# Or like this:
Variable= 'Some string'
# 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
# as a variable assignment valid only for the scope of the 'Some string'
# command.)
9
# Parameter expansion ${ }:
echo ${Variable}
# 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
# Below are other modifications that add onto this expansion
# Brace Expansion { }
# Used to generate arbitrary strings
echo {1..10}
echo {a..z}
# This will output the range from the start value to the end value
# Builtin variables:
# There are some useful builtin variables, like
echo "Last program's return value: $?"
echo "Script's PID: $$"
echo "Number of arguments passed to script: $#"
echo "All arguments passed to script: $@"
echo "Script's arguments separated into different variables: $1 $2..."
# If you get too much output in your terminal, or from a script, the command
# `clear` clears your screen
clear
# Ctrl-L also works for clearing output
10
echo Hello, $Name!
# To use && and || with if statements, you need multiple pairs of square brackets:
if [ "$Name" == "Steve" ] && [ "$Age" -eq 15 ]
then
echo "This will run if $Name is Steve AND $Age is 15."
fi
# 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:
ls -l | grep "\.txt"
11
cat file.txt
# Look into `scp` or `sftp` if you plan on exchanging files between computers.
# `scp` behaves very similarly to `cp`.
# `sftp` is more interactive.
# 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 .. # go up one directory
# (^^say, from /home/username/Downloads to /home/username)
cd /home/username/Documents # change to specified directory
cd ~/Documents/.. # still in home directory..isn't it??
# You can redirect command input and output (stdin, stdout, and stderr).
# Read from stdin until ^EOF$ and overwrite hello.py with the lines
# between "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
12
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
# 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"
# 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++:
case "$Variable" in
#List patterns for the conditions you want to meet
0) echo "There is a zero.";;
1) echo "There is a one.";;
*) echo "It is not null.";;
esac
13
echo $a
done
# while loop:
while [ true ]
do
echo "loop body here..."
break
done
# or simply
bar ()
{
echo "Another way to declare functions!"
return 0
}
14
cut -d ',' -f 1 file.txt
# replaces every occurrence of 'okay' with 'great' in file.txt, (regex compatible)
sed -i 's/okay/great/g' file.txt
# print to stdout all lines of file.txt which match some regex
# The example prints lines which begin with "foo" and end in "bar"
grep "^foo.*bar$" file.txt
# pass the option "-c" to instead print the number of lines matching the regex
grep -c "^foo.*bar$" file.txt
# Other useful options are:
grep -r "^foo.*bar$" someDir/ # recursively `grep`
grep -n "^foo.*bar$" file.txt # give line numbers
grep -rI "^foo.*bar$" someDir/ # recursively `grep`, but ignore binary files
# perform the same initial search, but filter out the lines containing "baz"
grep "^foo.*bar$" file.txt | grep -v "baz"
# trap command allows you to execute a command when a signal is received by your script.
# Here trap command will execute rm if any one of the three listed signals is received.
trap "rm $TEMP_FILE; exit" SIGHUP SIGINT SIGTERM
# Read Bash shell builtins documentation with the bash 'help' builtin:
help
help help
help for
help return
help source
help .
15
Bf
Brainfuck (not capitalized except at the start of a sentence) is an extremely minimal Turing-complete pro-
gramming language with just 8 commands.
You can try brainfuck on your browser with brainfuck-visualizer.
Any character not "><+-.,[]" (excluding quotation marks) is ignored.
This program prints out the letter 'A'. First, it increments cell #1 to 6.
Cell #1 will be used for looping. Then, it enters the loop ([) and moves
to cell #2. It increments cell #2 10 times, moves back to cell #1, and
decrements cell #1. This loop happens 6 times (it takes 6 decrements for
cell #1 to reach 0, at which point it skips to the corresponding ] and
continues on).
At this point, we're on cell #1, which has a value of 0, while cell #2 has a
value of 60. We move on cell #2, increment 5 times, for a value of 65, and then
print cell #2's value. 65 is 'A' in ASCII, so 'A' is printed to the terminal.
This program reads a character from the user input and copies the character into
cell #1. Then we start a loop. Move to cell #2, increment the value at cell #2,
move back to cell #1, and decrement the value at cell #1. This continues on
until cell #1 is 0, and cell #2 holds cell #1's old value. Because we're on
cell #1 at the end of the loop, move to cell #2, and then print out the value
in ASCII.
Also keep in mind that the spaces are purely for readability purposes. You
could just as easily write it as:
,[>+<-]>.
16
Try and figure out what this program does:
,>,< [ > [ >+ >+ << -] >> [- << + >>] <<< -] >>
This program takes two numbers for input, and multiplies them.
The gist is it first reads in two inputs. Then it starts the outer loop,
conditioned on cell #1. Then it moves to cell #2, and starts the inner
loop conditioned on cell #2, incrementing cell #3. However, there comes a
problem: At the end of the inner loop, cell #2 is zero. In that case,
inner loop won't work anymore since next time. To solve this problem,
we also increment cell #4, and then recopy cell #4 into cell #2.
Then cell #3 is the result.
And that’s brainfuck. Not that hard, eh? For fun, you can write your own brainfuck programs, or you can
write a brainfuck interpreter in another language. The interpreter is fairly simple to implement, but if you’re
a masochist, try writing a brainfuck interpreter… in brainfuck.
Binary-Search
Binary Search
Introduction
A simple approach to implement search is to do a linear search, but this approach takes a lot of time and
this time grows linearly with the amount or number of data points. i.e., start from the leftmost element of
arr[] and one by one compare x with each element of arr[], if x matches with an element, return the index.
If x doesn’t match with any of elements, return -1.
Linear Search: O (n) Linear Time
for i in range(len(arr)):
if arr[i] == x:
return i
return -1
17
Binary Search Algorithm
The basic requirement for binary search to work is that the data to search should be sorted (in any order).
### Algo
The idea of binary search is to use the information that the array is sorted and reduce the time complexity to
1) Compare x with the middle element.
2) If x matches with middle element, we return the mid index.
3) Else If x is greater than the mid element, then x can only lie in right half subarray after the mid element.
4) Else (x is smaller) recur for the left half.
Following is Recursive implementation of Binary Search.
Ending Notes
Books
• CLRS
• Algorithms
• Algorithm Design
Online Resources
• GeeksforGeeks
• Topcoder Tutorial
C++
C++ is a systems programming language that, according to its inventor Bjarne Stroustrup, was designed to
• be a “better C”
• support data abstraction
• support object-oriented programming
• support generic programming
Though its syntax can be more difficult or complex than newer languages, it is widely used because it compiles
to native instructions that can be directly run by the processor and offers tight control over hardware (like
C) while offering high-level features such as generics, exceptions, and classes. This combination of speed and
functionality makes C++ one of the most widely-used programming languages.
//////////////////
// Comparison to C
//////////////////
18
{
// Command line arguments are passed in by argc and argv in the same way
// they are in C.
// argc indicates the number of arguments,
// and argv is an array of C-style strings (char*)
// representing the arguments.
// The first argument is the name by which the program was called.
// argc and argv can be omitted if you do not care about arguments,
// giving the function signature of int main()
// In C
void func(); // function which may accept any number of arguments
int main()
{
printf("Hello, world!\n");
return 0;
}
///////////////////////
// Function overloading
///////////////////////
19
void print(int myInt)
{
printf("My int is %d", myInt);
}
int main()
{
print("Hello"); // Resolves to void print(const char*)
print(15); // Resolves to void print(int)
}
/////////////////////////////
// Default function arguments
/////////////////////////////
int main()
{
doSomethingWithInts(); // a = 1, b = 4
doSomethingWithInts(20); // a = 20, b = 4
doSomethingWithInts(20, 5); // a = 20, b = 5
}
/////////////
// Namespaces
/////////////
namespace First {
namespace Nested {
void foo()
{
printf("This is First::Nested::foo\n");
}
} // end namespace Nested
} // end namespace First
20
namespace Second {
void foo()
{
printf("This is Second::foo\n");
}
}
void foo()
{
printf("This is global foo\n");
}
int main()
{
// Includes all symbols from namespace Second into the current scope. Note
// that simply foo() no longer works, since it is now ambiguous whether
// we're calling the foo in namespace Second or the top level.
using namespace Second;
///////////////
// Input/Output
///////////////
using namespace std; // Streams are in the std namespace (standard library)
int main()
{
int myInt;
//////////
// Strings
21
//////////
using namespace std; // Strings are also in the namespace std (standard library)
/////////////
// References
/////////////
//The address of fooRef remains the same, i.e. it is still referring to foo.
22
// Like C, const values (and pointers and references) cannot be modified.
barRef += ". Hi!"; // Error, const references cannot be modified.
// assuming foo and bar exist, the object returned from tempObjectFun is
// passed to bar, and it is destroyed before foo is called.
// Now back to references. The exception to the "at the end of the enclosing
// expression" rule is if a temporary object is bound to a const reference, in
// which case its life gets extended to the current scope:
void constReferenceTempObjectFun() {
// constRef gets the temporary object, and it is valid until the end of this
// function.
const string& constRef = tempObjectFun();
...
}
string foo;
someFun(foo); // Calls the version with regular reference
someFun(tempObjectFun()); // Calls the version with temporary reference
// For example, you will see these two versions of constructors for
// std::basic_string:
basic_string(const basic_string& other);
basic_string(basic_string&& other);
// Idea being if we are constructing a new string from a temporary object (which
// is going to be destroyed soon anyway), we can have a more efficient
// constructor that "salvages" parts of that temporary string. You will see this
23
// concept referred to as "move semantics".
/////////////////////
// Enums
/////////////////////
// Enums are a way to assign a value to a constant most commonly used for
// easier visualization and reading of code
enum ECarTypes
{
Sedan,
Hatchback,
SUV,
Wagon
};
ECarTypes GetPreferredCarType()
{
return ECarTypes::Hatchback;
}
// As of C++11 there is an easy way to assign a type to the enum which can be
// useful in serialization of data and converting enums back-and-forth between
// the desired type and their respective constants
enum ECarTypes : uint8_t
{
Sedan, // 0
Hatchback, // 1
SUV = 254, // 254
Hybrid // 255
};
// On the other hand you may not want enums to be accidentally cast to an integer
// type or to other enums so it is instead possible to create an enum class which
// won't be implicitly converted
enum class ECarTypes : uint8_t
{
Sedan, // 0
Hatchback, // 1
SUV = 254, // 254
Hybrid // 255
};
24
void WriteByteToFile(uint8_t InputValue)
{
// Serialize the InputValue to a file
}
//////////////////////////////////////////
// Classes and object-oriented programming
//////////////////////////////////////////
// Declare a class.
// Classes are usually declared in header (.h or .hpp) files.
class Dog {
// Member variables and functions are private by default.
std::string name;
int weight;
// Default constructor
Dog();
25
// Along with constructors, C++ provides destructors.
// These are called when an object is deleted or falls out of scope.
// This enables powerful paradigms such as RAII
// (see below)
// The destructor should be virtual if a class is to be derived from;
// if it is not virtual, then the derived class' destructor will
// not be called if the object is destroyed through a base-class reference
// or pointer.
virtual ~Dog();
// Notice that "virtual" is only needed in the declaration, not the definition.
void Dog::print() const
{
std::cout << "Dog is " << name << " and weighs " << weight << "kg\n";
}
Dog::~Dog()
{
cout << "Goodbye " << name << "\n";
}
int main() {
Dog myDog; // prints "A dog has been constructed"
myDog.setName("Barkley");
myDog.setWeight(10);
myDog.print(); // prints "Dog is Barkley and weighs 10 kg"
return 0;
} // prints "Goodbye Barkley"
// Inheritance:
// This class inherits everything public and protected from the Dog class
// as well as private but may not directly access private members/methods
// without a public or protected method for doing so
26
class OwnedDog : public Dog {
// Override the behavior of the print function for all OwnedDogs. See
// http://en.wikipedia.org/wiki/Polymorphism_(computer_science)#Subtyping
// for a more general introduction if you are unfamiliar with
// subtype polymorphism.
// The override keyword is optional but makes sure you are actually
// overriding the method in a base class.
void print() const override;
private:
std::string owner;
};
//////////////////////////////////////////
// Initialization and Operator Overloading
//////////////////////////////////////////
#include <iostream>
using namespace std;
class Point {
public:
// Member variables can be given default values in this manner.
double x = 0;
double y = 0;
27
Point (double a, double b) :
x(a),
y(b)
{ /* Do nothing except initialize the values */ }
int main () {
Point up (0,1);
Point right (1,0);
// This calls the Point + operator
// Point up calls the + (function) with right as its parameter
Point result = up + right;
// Prints "Result is upright (1,1)"
cout << "Result is upright (" << result.x << ',' << result.y << ")\n";
return 0;
}
/////////////////////
// Templates
/////////////////////
// Templates in C++ are mostly used for generic programming, though they are
// much more powerful than generic constructs in other languages. They also
// support explicit and partial specialization and functional-style type
// classes; in fact, they are a Turing-complete functional language embedded
// in C++!
// We start with the kind of generic programming you might be familiar with. To
// define a class or function that takes a type parameter:
template<class T>
class Box {
public:
28
// In this class, T can be used as any other type.
void insert(const T&) { ... }
};
// Until C++11, you had to place a space between the two '>'s, otherwise '>>'
// would be parsed as the right shift operator.
// Notice that nothing is specified about the type parameters here. The compiler
// will generate and then type-check every invocation of the template, so the
// above function works with any type 'T' that has a const 'bark' method!
Dog fluffy;
fluffy.setName("Fluffy")
barkThreeTimes(fluffy); // Prints "Fluffy barks" three times.
// And you can explicitly specialize templates for more efficient code. Of
// course, most real-world uses of specialization are not as trivial as this.
29
// Note that you still need to declare the function (or class) as a template
// even if you explicitly specified all parameters.
template<>
void printMessage<10>() {
cout << "Learn C++ faster in only 10 minutes!" << endl;
}
/////////////////////
// Exception Handling
/////////////////////
// All exceptions thrown inside the _try_ block can be caught by subsequent
// _catch_ handlers.
try {
// Do not allocate exceptions on the heap using _new_.
throw std::runtime_error("A problem occurred");
}
///////
// RAII
///////
30
// To begin with, assume nothing can fail.
doSomethingWithTheFile(fh);
doSomethingElseWithIt(fh);
if (!doSomethingWithTheFile(fh))
goto failure;
if (!doSomethingElseWithIt(fh))
goto failure;
31
failure:
fclose(fh);
return false; // Propagate the error
}
try {
doSomethingWithTheFile(fh);
doSomethingElseWithIt(fh);
}
catch (...) {
fclose(fh); // Be sure to close the file if an error occurs.
throw; // Then re-throw the exception.
}
// All idiomatic C++ code uses RAII extensively for all resources.
32
// Additional examples include
// - Memory using unique_ptr and shared_ptr
// - Containers - the standard library linked list,
// vector (i.e. self-resizing array), hash maps, and so on
// all automatically destroy their contents when they fall out of scope.
// - Mutexes using lock_guard and unique_lock
///////////////////////////////////////
// Lambda Expressions (C++11 and above)
///////////////////////////////////////
sort(tester.begin(), tester.end(), [](const pair<int, int>& lhs, const pair<int, int>& rhs) {
return lhs.second < rhs.second;
});
33
// 2. a reference : [&x]
// 3. any variable currently in scope by reference [&]
// 4. same as 3, but by value [=]
// Example:
vector<int> dog_ids;
// number_of_dogs = 3;
for(int i = 0; i < 3; i++) {
dog_ids.push_back(i);
}
///////////////////////////////
// Range For (C++11 and above)
///////////////////////////////
// You can use "auto" and not worry about the type of the elements of the container
// For example:
/////////////////////
// Fun stuff
/////////////////////
// Aspects of C++ that may be surprising to newcomers (and even some veterans).
// This section is, unfortunately, wildly incomplete; C++ is one of the easiest
// languages with which to shoot yourself in the foot.
34
class FooSub : public Foo {
virtual void bar(); // Overrides Foo::bar!
};
// Calls Foo::Foo(const Foo&) or variant, but only copies the 'Foo' part of
// 'fooSub'. Any extra members of 'fooSub' are discarded. This sometimes
// horrifying behavior is called "object slicing."
FooSub fooSub;
Foo f1 = fooSub;
///////////////////////////////////////
// Tuples (C++11 and above)
///////////////////////////////////////
#include<tuple>
// Conceptually, Tuples are similar to old data structures (C-like structs) but instead of having named
// its elements are accessed by their order in the tuple.
35
// Printing elements of 'first' tuple
cout << get<0>(first) << " " << get<1>(first) << "\n"; //prints : 10 A
int first_int;
char first_char;
tie(first_int, first_char) = first;
cout << first_int << " " << first_char << "\n"; // prints : 10 A
// tuple_cat concatenates the elements of all the tuples in the same order.
/////////////////////
// Containers
/////////////////////
// Iterator
vector<Data_Type>::iterator it; // initialize the iteartor for vector
36
for(it=vector_name.begin(); it!=vector_name.end();++it)
// 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
// 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 initalize 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;
37
for (it=mymap.begin(); it!=mymap.end(); ++it)
std::cout << it->first << "->" << it->second << '\n';
// Output:
// A->1
// Z->26
// Output: 26
///////////////////////////////////
// Logical and Bitwise operators
//////////////////////////////////
// Logical operators
// C++ uses Short-circuit evaluation for boolean expressions, i.e, the second argument is executed or
// evaluated only if the first argument does not suffice to determine the value of the expression
// Bitwise operators
38
4 bitand 3 // Performs bitwise and
4 xor 3 // Performs bitwise xor
Further Reading:
An up-to-date language reference can be found at http://cppreference.com/w/cpp
Additional resources may be found at http://cplusplus.com
C
Ah, C. Still the language of modern high-performance computing.
C is the lowest-level language most programmers will ever use, but it more than makes up for it with raw
speed. Just be aware of its manual memory management and C will take you as far as you need to go.
// Single-line comments start with // - only available in C99 and later.
/*
Multi-line comments look like this. They work in C89 as well.
*/
/*
Multi-line comments don't nest /* Be careful */ // comment ends on this line...
*/ // ...not this one!
// (File names between <angle brackets> are headers from the C standard library.)
// For your own headers, use double quotes instead of angle brackets:
//#include "my_header.h"
// Must declare a 'function prototype' before main() when functions occur after
// your main() function.
int add_two_ints(int x1, int x2); // function prototype
// although `int add_two_ints(int, int);` is also valid (no need to name the args),
// it is recommended to name arguments in the prototype as well for easier inspection
39
// Your program's entry point is a function called
// main with an integer return type.
int main(void) {
// your program
}
// The command line arguments used to run your program are also passed to main
// argc being the number of arguments - your program's name counts as 1
// argv is an array of character arrays - containing the arguments themselves
// argv[0] = name of your program, argv[1] = first argument, etc.
int main (int argc, char** argv)
{
// print output using printf, for "print formatted"
// %d is an integer, \n is a newline
printf("%d\n", 0); // => Prints 0
///////////////////////////////////////
// Types
///////////////////////////////////////
// All variables MUST be declared at the top of the current block scope
// we declare them dynamically along the code for the sake of the tutorial
40
// sizeof(T) gives you the size of a variable with type T in bytes
// sizeof(obj) yields the size of the expression (variable, literal, etc.).
printf("%zu\n", sizeof(int)); // => 4 (on most machines with 4-byte words)
// Example:
// > Enter the array size: 10
// > sizeof array = 40
41
// It's of type `int`, and *not* `char` (for historical reasons).
int cha = 'a'; // fine
char chb = 'a'; // fine too (implicit conversion from int to char)
// Multi-dimensional arrays:
int multi_array[2][5] = {
{1, 2, 3, 4, 5},
{6, 7, 8, 9, 0}
};
// access elements:
int array_int = multi_array[0][2]; // => 3
///////////////////////////////////////
// Operators
///////////////////////////////////////
int b, c;
b = c = 0;
// Arithmetic is straightforward
i1 + i2; // => 3
i2 - i1; // => 1
i2 * i1; // => 2
i1 / i2; // => 0 (0.5, but truncated towards 0)
// You need to cast at least one integer to float to get a floating-point result
(float)i1 / i2; // => 0.5f
i1 / (double)i2; // => 0.5 // Same with double
f1 / f2; // => 0.5, plus or minus epsilon
// Floating-point numbers and calculations are not exact
42
int between_0_and_2 = 0 < a < 2;
// Instead use:
int between_0_and_2 = 0 < a && a < 2;
// Bitwise operators!
~0x0F; // => 0xFFFFFFF0 (bitwise negation, "1's complement", example result for 32-bit int)
0x0F & 0xF0; // => 0x00 (bitwise AND)
0x0F | 0xF0; // => 0xFF (bitwise OR)
0x04 ^ 0x0F; // => 0x0B (bitwise XOR)
0x01 << 1; // => 0x02 (bitwise left shift (by 1))
0x02 >> 1; // => 0x01 (bitwise right shift (by 1))
///////////////////////////////////////
// Control Structures
///////////////////////////////////////
if (0) {
printf("I am never run\n");
} else if (0) {
printf("I am also never run\n");
} else {
printf("I print\n");
}
43
while (ii < 10) { //ANY value not zero is true.
printf("%d, ", ii++); // ii++ increments ii AFTER using its current value.
} // => prints "0, 1, 2, 3, 4, 5, 6, 7, 8, 9, "
printf("\n");
int kk = 0;
do {
printf("%d, ", kk);
} while (++kk < 10); // ++kk increments kk BEFORE using its current value.
// => prints "0, 1, 2, 3, 4, 5, 6, 7, 8, 9, "
printf("\n");
printf("\n");
// *****NOTES*****:
// Loops and Functions MUST have a body. If no body is needed:
int i;
for (i = 0; i <= 5; i++) {
; // use semicolon to act as the body (null statement)
}
// Or
for (i = 0; i <= 5; i++);
44
typedef enum { false, true } bool;
// for C don't have bool as data type :(
bool disaster = false;
int i, j;
for(i=0;i<100;++i)
for(j=0;j<100;++j)
{
if((i + j) >= 150)
disaster = true;
if(disaster)
goto error;
}
error :
printf("Error occured at i = %d & j = %d.\n", i, j);
/*
https://ideone.com/GuPhd6
this will print out "Error occured at i = 52 & j = 99."
*/
///////////////////////////////////////
// Typecasting
///////////////////////////////////////
// Every value in C has a type, but you can cast one value into another type
// if you want (with some constraints).
int x_hex = 0x01; // You can assign vars with hex literals
// For determining the max value of a `char`, a `signed char` and an `unsigned char`,
// respectively, use the CHAR_MAX, SCHAR_MAX and UCHAR_MAX macros from <limits.h>
///////////////////////////////////////
// Pointers
///////////////////////////////////////
int x = 0;
printf("%p\n", (void *)&x); // Use & to retrieve the address of a variable
45
// (%p formats an object pointer of type void *)
// => Prints some address in memory;
// You can also change the value the pointer is pointing to.
// We'll have to wrap the dereference in parenthesis because
// ++ has a higher precedence than *.
(*px)++; // Increment the value px is pointing to by 1
printf("%d\n", *px); // => Prints 1
printf("%d\n", x); // => Prints 1
// You can also dynamically allocate contiguous blocks of memory with the
46
// standard library function malloc, which takes one argument of type size_t
// representing the number of bytes to allocate (usually from the heap, although this
// may not be true on e.g. embedded systems - the C standard says nothing about it).
int *my_ptr = malloc(sizeof(*my_ptr) * 20);
for (xx = 0; xx < 20; xx++) {
*(my_ptr + xx) = 20 - xx; // my_ptr[xx] = 20-xx
} // Initialize memory to 20, 19, 18, 17... 2, 1 (as ints)
// When you're done with a malloc'd block of memory, you need to free it,
// or else no one else can use it until your program terminates
// (this is called a "memory leak"):
free(my_ptr);
function_1();
} // end main function
///////////////////////////////////////
// Functions
///////////////////////////////////////
47
}
/*
Functions are call by value. When a function is called, the arguments passed to
the function are copies of the original arguments (except arrays). Anything you
do to the arguments in the function do not change the value of the original
argument where the function was called.
/*
char c[] = "This is a test.";
str_reverse(c);
printf("%s\n", c); // => ".tset a si sihT"
*/
/*
as we can return only one variable
to change values of more than one variables we use call by reference
*/
void swapTwoNumbers(int *a, int *b)
{
int temp = *a;
*a = *b;
*b = temp;
}
/*
int first = 10;
int second = 20;
printf("first: %d\nsecond: %d\n", first, second);
swapTwoNumbers(&first, &second);
printf("first: %d\nsecond: %d\n", first, second);
// values will be swapped
*/
/*
With regards to arrays, they will always be passed to functions
as pointers. Even if you statically allocate an array like `arr[10]`,
it still gets passed as a pointer to the first element in any function calls.
48
Again, there is no standard way to get the size of a dynamically allocated
array in C.
*/
// Size must be passed!
// Otherwise, this function has no way of knowing how big the array is.
void printIntArray(int *arr, int size) {
int i;
for (i = 0; i < size; i++) {
printf("arr[%d] is: %d\n", i, arr[i]);
}
}
/*
int my_arr[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
int size = 10;
printIntArray(my_arr, size);
// will print "arr[0] is: 1" etc
*/
///////////////////////////////////////
// User-defined types and structs
///////////////////////////////////////
// Structs are just collections of data, the members are allocated sequentially,
// in the order they are written:
struct rectangle {
int width;
int height;
};
void function_1()
{
struct rectangle my_rec;
49
// Access struct members with .
my_rec.width = 10;
my_rec.height = 20;
// ... or even better: prefer the -> shorthand for the sake of readability
my_rec_ptr->height = 10; // Same as (*my_rec_ptr).height = 10;
}
int area(rect r)
{
return r.width * r.height;
}
// if you have large structs, you can pass them "by pointer" to avoid copying
// the whole struct:
int areaptr(const rect *r)
{
return r->width * r->height;
}
///////////////////////////////////////
// Function pointers
///////////////////////////////////////
/*
At run time, functions are located at known memory addresses. Function pointers are
much like any other pointer (they just store a memory address), but can be used
to invoke functions directly, and to pass handlers (or callback functions) around.
However, definition syntax may be initially confusing.
/*
As long as function signatures match, you can assign any function to the same pointer.
Function pointers are usually typedef'd for simplicity and readability, as follows:
*/
50
typedef void (*my_fnp_type)(char *);
//Special characters:
/*
'\a'; // alert (bell) character
'\n'; // newline character
'\t'; // tab character (left justifies text)
'\v'; // vertical tab
'\f'; // new page (form feed)
'\r'; // carriage return
'\b'; // backspace character
'\0'; // NULL character. Usually put at end of strings in C.
// hello\n\0. \0 used by convention to mark end of string.
'\\'; // backslash
'\?'; // question mark
'\''; // single quote
'\"'; // double quote
'\xhh'; // hexadecimal number. Example: '\xb' = vertical tab character
'\0oo'; // octal number. Example: '\013' = vertical tab character
//print formatting:
"%d"; // integer
"%3d"; // integer with minimum of length 3 digits (right justifies text)
"%s"; // string
"%f"; // float
"%ld"; // long
"%3.2f"; // minimum 3 digits left and 2 digits right decimal float
"%7.4s"; // (can do with strings too)
"%c"; // char
"%p"; // pointer
"%x"; // hexadecimal
"%o"; // octal
"%%"; // prints %
*/
///////////////////////////////////////
// Order of Evaluation
///////////////////////////////////////
//---------------------------------------------------//
// Operators | Associativity //
//---------------------------------------------------//
// () [] -> . | left to right //
// ! ~ ++ -- + = *(type)sizeof | right to left //
// * / % | left to right //
// + - | left to right //
// << >> | left to right //
// < <= > >= | left to right //
// == != | left to right //
51
// & | left to right //
// ^ | left to right //
// | | left to right //
// && | left to right //
// || | left to right //
// ?: | right to left //
// = += -= *= /= %= &= ^= |= <<= >>= | right to left //
// , | left to right //
//---------------------------------------------------//
Header files are an important part of c as they allow for the connection of c
source files and can simplify code and definitions by separating them into
separate files.
Header files are syntactically similar to c source files but reside in ".h"
files. They can be included in your c source file by using the precompiler
command #include "example.h", given that example.h exists in the same directory
as the c file.
*/
/* A safe guard to prevent the header from being defined too many times. This */
/* happens in the case of circle dependency, the contents of the header is */
/* already defined. */
#ifndef EXAMPLE_H /* if EXAMPLE_H is not yet defined. */
#define EXAMPLE_H /* Define the macro EXAMPLE_H. */
/* Like c source files macros can be defined in headers and used in files */
/* that include this header file. */
#define EXAMPLE_NAME "Dennis Ritchie"
/* Function macros can also be defined. */
#define ADD(a, b) (a + b)
/* So can enumerations. */
enum traffic_light_state {GREEN, YELLOW, RED};
/* Function prototypes can also be defined here for use in multiple files, */
/* but it is bad practice to define the function in the header. Definitions */
/* should instead be put in a c file. */
Node createLinkedList(int *vals, int len);
52
/* file. Excessive includes or definitions should, also not be contained in */
/* a header file but instead put into separate headers or a c file. */
Further Reading
Best to find yourself a copy of K&R, aka “The C Programming Language” It is the book about C, written
by Dennis Ritchie, the creator of C, and Brian Kernighan. Be careful, though - it’s ancient and it contains
some inaccuracies (well, ideas that are not considered good anymore) or now-changed practices.
Another good resource is Learn C The Hard Way.
If you have a question, read the compl.lang.c Frequently Asked Questions.
It’s very important to use proper spacing, indentation and to be consistent with your coding style in general.
Readable code is better than clever code and fast code. For a good, sane coding style to adopt, see the Linux
kernel coding style.
Other than that, Google is your friend.
1 http://stackoverflow.com/questions/119123/why-isnt-sizeof-for-a-struct-equal-to-the-sum-of-sizeof-of-each-
member
Chapel
You can read all about Chapel at Cray’s official Chapel website. In short, Chapel is an open-source, high-
productivity, parallel-programming language in development at Cray Inc., and is designed to run on multi-
core PCs as well as multi-kilocore supercomputers.
More information and support can be found at the bottom of this document.
// Comments are C-family style
// one line comment
/*
multi-line comment
*/
// Basic printing
write( "Hello, " );
writeln( "World!" );
// write and writeln can take a list of things to print.
// each thing is printed right next to each other, so include your spacing!
writeln( "There are ", 3, " commas (\",\") in this line of code" );
// Different output channels
stdout.writeln( "This goes to standard output, just like plain writeln() does");
stderr.writeln( "This goes to standard error" );
53
var myThirdVar: real;
var myFourthVar: real = -1.234;
myThirdVar = myFourthVar;
// Typecasting
var intFromReal = myReal : int;
var intFromReal2: int = myReal : int;
// Math operators
var a: int, thisInt = 1234, thatInt = 5678;
a = thisInt + thatInt; // Addition
a = thisInt * thatInt; // Multiplication
54
a = thisInt - thatInt; // Subtraction
a = thisInt / thatInt; // Division
a = thisInt ** thatInt; // Exponentiation
a = thisInt % thatInt; // Remainder (modulo)
// Logical Operators
var b: bool, thisBool = false, thatBool = true;
b = thisBool && thatBool; // Logical and
b = thisBool || thatBool; // Logical or
b = !thisBool; // Logical negation
// Relational Operators
b = thisInt > thatInt; // Greater-than
b = thisInt >= thatInt; // Greater-than-or-equal-to
b = thisInt < a && a <= thatInt; // Less-than, and, less-than-or-equal-to
b = thisInt != thatInt; // Not-equal-to
b = thisInt == thatInt; // Equal-to
// Bitwise operations
a = thisInt << 10; // Left-bit-shift by 10 bits;
a = thatInt >> 5; // Right-bit-shift by 5 bits;
a = ~thisInt; // Bitwise-negation
a = thisInt ^ thatInt; // Bitwise exclusive-or
// Swap operator
var old_this = thisInt;
var old_that = thatInt;
thisInt <=> thatInt; // Swap the values of thisInt and thatInt
writeln( (old_this == thatInt) && (old_that == thisInt) );
55
// Tuples can also be written into.
diffTup[1] = -1;
// Type aliasing
type chroma = int; // Type of a single hue
type RGBColor = 3*chroma; // Type representing a full color
var black: RGBColor = ( 0,0,0 );
var white: RGBColor = ( 255, 255, 255 );
if -1 < 1 then
writeln( "Continuing to believe reality" );
else
writeln( "Send mathematician, something's wrong" );
if ( 10 > 100 ) {
writeln( "Universe broken. Please reboot universe." );
}
if ( a % 2 == 0 ) {
writeln( a, " is even." );
} else {
writeln( a, " is odd." );
}
if ( a % 3 == 0 ) {
writeln( a, " is even divisible by 3." );
} else if ( a % 3 == 1 ){
writeln( a, " is divided by 3 with a remainder of 1." );
} else {
writeln( b, " is divided by 3 with a remainder of 2." );
}
56
}
otherwise {
writeln( "Any other Input" );
writeln( "the otherwise case doesn't need a do if the body is one line" );
}
}
// While and Do-While loops are basically the same in every language.
var j: int = 1;
var jSum: int = 0;
while( j <= 1000 ){
jSum += j;
j += 1;
}
writeln( jSum );
// Do-While loop
do{
jSum += j;
j += 1;
}while( j <= 10000 );
writeln( jSum );
// For loops are much like those in python in that they iterate over a range.
// Ranges themselves are types, and can be stuffed into variables
// (more about that later)
for i in 1..10 do write( i , ", ") ;
writeln( );
for x in 1..10 {
for y in 1..10 {
write( (x,y), "\t" );
}
writeln( );
}
57
// Ranges can be unbounded
var range1toInf: range(boundedType=BoundedRangeType.boundedLow) = 1.. ;
// 1, 2, 3, 4, 5, ...
// Note: the range(boundedType= ... ) is only
// necessary if we explicitly type the variable
// The end point of a range can be determined using the count (#) operator
var rangeCount: range = -5..#12; // range from -5 to 6
for i in rangeCountBy{
write( i, if i == rangeCountBy.last then "\n" else ", " );
}
58
stringSet += "b";
stringSet += "c";
stringSet += "a"; // Redundant add "a"
stringSet -= "c"; // Remove "c"
writeln( stringSet );
// Both ranges and domains can be sliced to produce a range or domain with the
// intersection of indices
var rangeA = 1.. ; // range from 1 to infinity
var rangeB = ..5; // range from negative infinity to 5
var rangeC = rangeA[rangeB]; // resulting range is 1..5
writeln( (rangeA, rangeB, rangeC ) );
for i in 1..5 {
for j in realDomain.dim(2) { // Only use the 2nd dimension of the domain
realArray[i,j] = -1.61803 * i + 0.5 * j; // Access using index list
var idx: 2*int = (i,j); // Note: 'index' is a keyword
realArray[idx] = - realArray[(i,j)]; // Index using tuples
}
}
writeln( realArray );
59
rSum += value; // Read a value
value = rSum; // Write a value
}
writeln( rSum, "\n", realArray );
// Assign a slice one array to a slice (of the same size) of the other.
thatArray[{4..5}] = thisArray[{1..2}];
writeln( (thisArray, thatArray) );
writeln( arrayFromLoop );
60
proc fibonacci( n : int ) : int {
if ( n <= 1 ) then return n;
return fibonacci( n-1 ) + fibonacci( n-2 );
}
// Return type can be inferred (as long as the compiler can figure it out)
proc addThree( n ) {
return n + 3;
}
writeln( defaultsProc( 10 ) );
writeln( defaultsProc( x=11 ) );
writeln( defaultsProc( x=12, y=5.432 ) );
writeln( defaultsProc( y=9.876, x=13 ) );
61
// inout: copy arg in, copy arg out
// ref: pass arg by reference
proc intentsProc( in inarg, out outarg, inout inoutarg, ref refarg ){
writeln( "Inside Before: ", (inarg, outarg, inoutarg, refarg) );
inarg = inarg + 100;
outarg = outarg + 100;
inoutarg = inoutarg + 100;
refarg = refarg + 100;
writeln( "Inside After: ", (inarg, outarg, inoutarg, refarg) );
}
genericProc( 1, 2 );
genericProc( 1.2, 2.3 );
genericProc( 1.0+2.0i, 3.0+4.0i );
62
// The param modifier on the arg is used to enforce this constraint.
proc whereProc( param N : int ): void
where ( N > 0 ) {
writeln( "N is greater than 0" );
}
whereProc( 10 );
whereProc( -1 );
// whereProc( 0 ) would result in a compiler error because there
// are no functions that satisfy the where clause's condition.
// We could have defined a whereProc without a where clause that would then have
// served as a catch all for all the other cases (of which there is only one).
// Define a * operator on any two types that returns a tuple of those types
proc *( left : ?ltype, right : ?rtype): ( ltype, rtype ){
return (left, right );
}
/*
Note: You could break everything if you get careless with your overloads.
This here will break everything. Don't do it.
proc +( left: int, right: int ): int{
return left - right;
}
*/
63
// iterators yield many values to a loop.
// This is useful when a complicated set or order of iterations is needed but
// allows the code defining the iterations to be separate from the loop body.
iter oddsThenEvens( N: int ): int {
for i in 1..N by 2 do
yield i; // yield values instead of returning.
for i in 2..N by 2 do
yield i;
}
// Iterators can also yield conditionally, the result of which can be nothing
iter absolutelyNothing( N ): int {
for i in 1..N {
if ( N < i ) { // Always false
yield i; // Yield statement never happens
}
}
}
for i in absolutelyNothing( 10 ){
writeln( "Woa there! absolutelyNothing yielded ", i );
}
// We can zipper together two or more iterators (who have the same number
// of iterations) using zip() to create a single zipped iterator, where each
// iteration of the zipped iterator yields a tuple of one value yielded
// from each iterator.
// Ranges have implicit iterators
for (positive, negative) in zip( 1..5, -5..-1) do
writeln( (positive, negative) );
// The operation
toThisArray = fromThatArray;
// is produced through
for (i,j) in zip( toThisArray.domain, fromThatArray.domain) {
toThisArray[ i ] = fromThatArray[ j ];
}
toThisArray = [ j in -100..#5 ] j;
writeln( toThisArray );
// is produced through
for (i, j) in zip( toThisArray.domain, -100..#5 ){
toThisArray[i] = j;
}
writeln( toThisArray );
64
// This is all very important in understanding why the statement
// var iterArray : [1..10] int = [ i in 1..10 ] if ( i % 2 == 1 ) then j;
// exhibits a runtime error.
// Even though the domain of the array and the loop-expression are
// the same size, the body of the expression can be thought of as an iterator.
// Because iterators can yield nothing, that iterator yields a different number
// of things than the domain of the array or loop, which is not allowed.
// Classes have default constructors that don't need to be coded (see below)
// Our explicitly defined constructor
proc MyClass( val : real ){
this.memberInt = ceil( val ): int;
}
// Class methods
proc setMemberInt( val: int ){
this.memberInt = val;
}
65
// Construct using written constructor
var myOtherObject = new MyClass( 1.95 );
myOtherObject = new MyClass( val = 1.95 ); // Equivalent
writeln( myOtherObject.getMemberInt( ) );
// Destruction
delete myObject;
delete myDiffObject;
delete myOtherObject;
delete plusObject;
// Generic Classes
class GenericClass {
type classType;
var classDomain: domain(1);
var classArray: [classDomain] classType;
// Explicit constructor
proc GenericClass( type classType, elements : int ){
this.classDomain = {1..#elements};
}
// Copy constructor
// Note: We still have to put the type as an argument, but we can
// default to the type of the other object using the query (?) operator
// Further, we can take advantage of this to allow our copy constructor
// to copy classes of different types and cast on the fly
proc GenericClass( other : GenericClass(?otherType),
type classType = otherType ) {
this.classDomain = other.classDomain;
// Copy and cast
for idx in this.classDomain do this[ idx ] = other[ idx ] : classType;
}
66
return this.classArray[ i ];
}
// Make a copy of realList and change the type, also using the copy constructor
var copyNewTypeList = new GenericClass( realList, int );
for value in copyNewTypeList do write( value, ", " );
writeln( );
module OurModule {
// We can use modules inside of other modules.
use Time; // Time is one of the standard modules.
// Submodules of OurModule
// It is possible to create arbitrarily deep module nests.
module ChildModule {
proc foo(){
writeln( "ChildModule.foo()");
67
}
}
module SiblingModule {
proc foo(){
writeln( "SiblingModule.foo()" );
}
}
} // end OurModule
use ChildModule;
foo(); // Less explicit call on ChildModule.foo()
// Parallelism
// In other languages, parallelism is typically done with
// complicated libraries and strange class structure hierarchies.
// Chapel has it baked right into the language.
// A cobegin statement will spin each statement of the body into one new task
cobegin {
68
printFibb( 20 ); // new task
printFibb( 10 ); // new task
printFibb( 5 ); // new task
{
// This is a nested statement body and thus is a single statement
// to the parent statement and is executed by a single task
writeln( "this gets" );
writeln( "executed as" );
writeln( "a whole" );
}
}
// Notice here that the prints from each statement may happen in any order.
// forall loops are another parallel loop, but only create a smaller number
// of tasks, specifically --dataParTasksPerLocale=number of task
forall i in 1..100 {
write( i, ", ");
}
writeln( );
// Here we see that there are sections that are in order, followed by
// a section that would not follow ( e.g. 1, 2, 3, 7, 8, 9, 4, 5, 6, ).
// This is because each task is taking on a chunk of the range 1..10
// (1..3, 4..6, or 7..9) doing that chunk serially, but each task happens
// in parallel.
// Your results may depend on your machine and configuration
// For both the forall and coforall loops, the execution of the
// parent task will not continue until all the children sync up.
// forall loops are particularly useful for parallel iteration over arrays.
// Lets run an experiment to see how much faster a parallel loop is
use Time; // Import the Time module to use Timer objects
var timer: Timer;
var myBigArray: [{1..4000,1..4000}] real; // Large array we will write into
// Serial Experiment
timer.start( ); // Start timer
for (x,y) in myBigArray.domain { // Serial iteration
myBigArray[x,y] = (x:real) / (y:real);
}
timer.stop( ); // Stop timer
writeln( "Serial: ", timer.elapsed( ) ); // Print elapsed time
timer.clear( ); // Clear timer for parallel loop
// Parallel Experiment
69
timer.start( ); // start timer
forall (x,y) in myBigArray.domain { // Parallel iteration
myBigArray[x,y] = (x:real) / (y:real);
}
timer.stop( ); // Stop timer
writeln( "Parallel: ", timer.elapsed( ) ); // Print elapsed time
timer.clear( );
// You may have noticed that (depending on how many cores you have)
// that the parallel loop went faster than the serial loop
// operations are described as functions, you could define your own operators.
uranium.sub( 3 ); // atomically subtract a variable
writeln( uranium.read() );
sync {
begin { // Reader task
writeln( "Reader: waiting for uranium to be ", isEqualTo );
uranium.waitFor( isEqualTo );
writeln( "Reader: uranium was set (by someone) to ", isEqualTo );
}
70
// If you read an empty variable or write a full variable, you are waited
// until the variable is full or empty again
var someSyncVar$: sync int; // varName$ is a convention not a law.
sync {
begin { // Reader task
writeln( "Reader: waiting to read." );
var read_sync = someSyncVar$;
writeln( "Reader: value is ", read_sync );
}
// single vars can only be written once. A read on an unwritten single results
// in a wait, but when the variable has a value it can be read indefinitely
var someSingleVar$: single int; // varName$ is a convention not a law.
sync {
begin { // Reader task
writeln( "Reader: waiting to read." );
for i in 1..5 {
var read_single = someSingleVar$;
writeln( "Reader: iteration ", i,", and the value is ", read_single );
}
}
71
lock$.writeXF( true ); // Set lock$ to full (signal)
// Actual 'work'
writeln( "Task #", task, " doing work." );
sleep( 2 );
// we can define the operations + * & | ^ && || min max minloc maxloc
// over an entire array using scans and reductions
// Reductions apply the operation over the entire array and
// result in a single value
var listOfValues: [1..10] int = [15,57,354,36,45,15,456,8,678,2];
var sumOfValues = + reduce listOfValues;
var maxValue = max reduce listOfValues; // 'max' give just max value
72
Your input, questions, and discoveries are important to the developers!
The Chapel language is still in-development (version 1.12.0), so there are occasional hiccups with performance
and language features. The more information you give the Chapel development team about issues you
encounter or features you would like to see, the better the language becomes. Feel free to email the team
and other developers through the sourceforge email lists.
If you’re really interested in the development of the compiler or contributing to the project, check out the
master GitHub repository. It is under the Apache 2.0 License.
Compiling Code
Builds like other compilers:
chpl myFile.chpl -o myExe
Notable arguments:
• --fast: enables a number of optimizations and disables array bounds checks. Should only enable when
application is stable.
• --set <Symbol Name>=<Value>: set config param <Symbol Name> to <Value> at compile-time.
• --main-module <Module Name>: use the main() procedure found in the module <Module Name> as
the executable’s main.
• --module-dir <Directory>: includes <Directory> in the module search path.
Clojure-Macros
As with all Lisps, Clojure’s inherent homoiconicity gives you access to the full extent of the language to
write code-generation routines called “macros”. Macros provide a powerful way to tailor the language to
your needs.
Be careful though. It’s considered bad form to write a macro when a function will do. Use a macro only
when you need control over when or if the arguments to a form will be evaluated.
You’ll want to be familiar with Clojure. Make sure you understand everything in Clojure in Y Minutes.
;; Define a macro using defmacro. Your macro should output a list that can
;; be evaluated as clojure code.
;;
73
;; This macro is the same as if you wrote (reverse "Hello World")
(defmacro my-first-macro []
(list reverse "Hello World"))
;; You can make things easier on yourself by using the more succinct quote syntax
;; to create lists in your macros:
(defmacro my-first-quoted-macro []
'(reverse "Hello World"))
(macroexpand '(my-first-quoted-macro))
;; -> (reverse "Hello World")
;; Notice that reverse is no longer function object, but a symbol.
(inc2 2) ; -> 4
;; But, if you try to do this with a quoted list, you'll get an error, because
;; the argument will be quoted too. To get around this, clojure provides a
;; way of quoting macros: `. Inside `, you can use ~ to get at the outer scope
(defmacro inc2-quoted [arg]
`(+ 2 ~arg))
(inc2-quoted 2)
;; You can use the usual destructuring args. Expand list variables using ~@
(defmacro unless [arg & body]
`(if (not ~arg)
(do ~@body))) ; Remember the do!
;; (unless) evaluates and returns its body if the first argument is false.
;; Otherwise, it returns nil
74
;; Used without care, macros can do great evil by clobbering your vars
(defmacro define-x []
'(do
(def x 2)
(list x)))
(def x 4)
(define-x) ; -> (2)
(list x) ; -> (2)
(defmacro define-x-safely []
(let [sym (gensym 'x)]
`(do
(def ~sym 2)
(list ~sym))))
(def x 4)
(define-x-safely) ; -> (2)
(list x) ; -> (4)
;; You can use # within ` to produce a gensym for each symbol automatically
(defmacro define-x-hygenically []
`(do
(def x# 2)
(list x#)))
(def x 4)
(define-x-hygenically) ; -> (2)
(list x) ; -> (4)
;; It's typical to use helper functions with macros. Let's create a few to
;; help us support a (dumb) inline arithmetic syntax
(declare inline-2-helper)
(defn clean-arg [arg]
(if (seq? arg)
(inline-2-helper arg)
arg))
(defn apply-arg
"Given args [x (+ y)], return (+ x y)"
[val [op arg]]
(list op val (clean-arg arg)))
(defn inline-2-helper
[[arg1 & ops-and-args]]
(let [ops (partition 2 ops-and-args)]
(reduce apply-arg (clean-arg arg1) ops)))
75
; However, we'll need to make it a macro if we want it to be run at compile time
(defmacro inline-2 [form]
(inline-2-helper form)))
(inline-2 (1 + (3 / 2) - (1 / 2) + 1))
; -> 3 (actually, 3N, since the number got cast to a rational fraction with /)
Further Reading
Writing Macros from Clojure for the Brave and True http://www.braveclojure.com/writing-macros/
Official docs http://clojure.org/macros
When to use macros? http://dunsmor.com/lisp/onlisp/onlisp_12.html
Clojure
Clojure is a Lisp family language developed for the Java Virtual Machine. It has a much stronger emphasis
on pure functional programming than Common Lisp, but includes several STM utilities to handle state as
it comes up.
This combination allows it to handle concurrent processing very simply, and often automatically.
(You need a version of Clojure 1.2 or newer)
; Comments start with semicolons.
; Math is straightforward
(+ 1 1) ; => 2
(- 2 1) ; => 1
(* 1 2) ; => 2
(/ 2 1) ; => 2
; Equality is =
(= 1 1) ; => true
(= 2 1) ; => false
76
; You need not for logic, too
(not true) ; => false
; Types
;;;;;;;;;;;;;
; Clojure uses Java's object types for booleans, strings and numbers.
; Use `class` to inspect them.
(class 1) ; Integer literals are java.lang.Long by default
(class 1.); Float literals are java.lang.Double
(class ""); Strings always double-quoted, and are java.lang.String
(class false) ; Booleans are java.lang.Boolean
(class nil); The "null" value is called nil
; If you want to create a literal list of data, use ' to stop it from
; being evaluated
'(+ 1 2) ; => (+ 1 2)
; (shorthand for (quote (+ 1 2)))
77
(cons 4 [1 2 3]) ; => (4 1 2 3)
(cons 4 '(1 2 3)) ; => (4 1 2 3)
; Functions
;;;;;;;;;;;;;;;;;;;;;
78
; You can have multi-variadic functions, too
(defn hello3
([] "Hello World")
([name] (str "Hello " name)))
(hello3 "Jake") ; => "Hello Jake"
(hello3) ; => "Hello World"
; Maps
;;;;;;;;;;
; Hash maps and array maps share an interface. Hash maps have faster lookups
; but don't retain key order.
(class {:a 1 :b 2 :c 3}) ; => clojure.lang.PersistentArrayMap
(class (hash-map :a 1 :b 2 :c 3)) ; => clojure.lang.PersistentHashMap
; Maps can use any hashable type as a key, but usually keywords are best
; Keywords are like strings with some efficiency bonuses
(class :a) ; => clojure.lang.Keyword
79
; Retrieving a non-present key returns nil
(stringmap "d") ; => nil
; Sets
;;;;;;
; Useful forms
;;;;;;;;;;;;;;;;;
80
; So does let
(let [name "Urkel"]
(print "Saying hello to " name)
(str "Hello " name)) ; => "Hello Urkel" (prints "Saying hello to Urkel")
; The "Thread-first" macro (->) inserts into each form the result of
; the previous, as the first argument (second item)
(->
{:a 1 :b 2}
(assoc :c 3) ;=> (assoc {:a 1 :b 2} :c 3)
(dissoc :b)) ;=> (dissoc (assoc {:a 1 :b 2} :c 3) :b)
; The double arrow does the same thing, but inserts the result of
; each line at the *end* of the form. This is useful for collection
; operations in particular:
(->>
(range 10)
(map inc) ;=> (map inc (range 10)
(filter odd?) ;=> (filter odd? (map inc (range 10))
(into [])) ;=> (into [] (filter odd? (map inc (range 10)))
; Result: [1 3 5 7 9]
; Modules
;;;;;;;;;;;;;;;
81
; You can use require (and use, but don't) from a namespace using :require.
; You don't need to quote your modules if you do it this way.
(ns test
(:require
[clojure.string :as str]
[clojure.set :as set]))
; Java
;;;;;;;;;;;;;;;;;
; Use the class name with a "." at the end to make a new instance
(Date.) ; <a date object>
; STM
;;;;;;;;;;;;;;;;;
82
my-atom ;=> Atom<#...> (Returns the Atom object)
@my-atom ; => {:a 1 :b 2}
(inc-counter)
(inc-counter)
(inc-counter)
(inc-counter)
(inc-counter)
@counter ; => 5
Further Reading
This is far from exhaustive, but hopefully it’s enough to get you on your feet.
Clojure.org has lots of articles: http://clojure.org/
Clojuredocs.org has documentation with examples for most core functions: http://clojuredocs.org/quickref/
Clojure%20Core
4Clojure is a great way to build your clojure/FP skills: http://www.4clojure.com/
Clojure-doc.org (yes, really) has a number of getting started articles: http://clojure-doc.org/
Cmake
CMake is a cross-platform, open-source build system. This tool will allow you to test, compile and create
packages of your source code.
The problem that CMake tries to solve is the problem of Makefiles and Autoconfigure on cross-platforms
(different make interpreters have different command) and the ease-of-use on linking 3rd party libraries.
CMake is an extensible, open-source system that manages the build process in an operating system and
compiler-independent manner. Unlike many cross-platform systems, CMake is designed to be used in
conjunction with the native build environment. Simple configuration files placed in each source direc-
tory (called CMakeLists.txt files) are used to generate standard build files (e.g., makefiles on Unix and
projects/workspaces in Windows MSVC) which are used in the usual way.
# In CMake, this is a comment
83
# Makefile. Finally, run the native Make command.
#------------------------------------------------------------------------------
# Basic
#------------------------------------------------------------------------------
#
# The CMake file MUST be named as "CMakeLists.txt".
# We setup the name for our project. After we do that, this will change some
# directories naming convention genearted by CMake. We can send the LANG of
# code as second param
project (learncmake C)
# It's useful to setup the current version of our code in the build system
# using a `semver` style
set (LEARN_CMAKE_VERSION_MAJOR 1)
set (LEARN_CMAKE_VERSION_MINOR 0)
set (LEARN_CMAKE_VERSION_PATCH 0)
# Include Directories
# In GCC, this will invoke the "-I" command
include_directories( include )
# Conditions
if ( CONDITION )
# Output!
# Incidental information
message(STATUS "My message")
84
message(AUTHOR_WARNING "My message")
if( CONDITION )
elseif( CONDITION )
else( CONDITION )
endif( CONDITION )
# Loops
foreach(loop_var arg1 arg2 ...)
COMMAND1(ARGS ...)
COMMAND2(ARGS ...)
...
endforeach(loop_var)
while(condition)
COMMAND1(ARGS ...)
COMMAND2(ARGS ...)
...
endwhile(condition)
# Logic Operations
if(FALSE AND (FALSE OR TRUE))
message("Don't display!")
endif()
# Lists
# Setup the list of source files
85
set( LEARN_CMAKE_SOURCES
src/main.c
src/imagem.c
src/pather.c
)
# Check for OS
if( UNIX )
set( LEARN_CMAKE_DEFINITIONS
"${LEARN_CMAKE_DEFINITIONS} -Wall -Wextra -Werror -Wno-deprecated-declarations -Wno-unused-param
endif()
More Resources
• cmake tutorial
• cmake documentation
• mastering cmake
Coffeescript
CoffeeScript is a little language that compiles one-to-one into the equivalent JavaScript, and there is no
interpretation at runtime. As one of the successors to JavaScript, CoffeeScript tries its best to output
readable, pretty-printed and smooth-running JavaScript code, which works well in every JavaScript runtime.
See also the CoffeeScript website, which has a complete tutorial on CoffeeScript.
# CoffeeScript is a hipster language.
# It goes with the trends of many modern languages.
# So comments are like Ruby and Python, they use number symbols.
###
Block comments are like these, and they translate directly to '/ *'s and '* /'s
for the resulting JavaScript code.
86
before continuing.
###
# Assignment:
number = 42 #=> var number = 42;
opposite = true #=> var opposite = true;
# Conditions:
number = -42 if opposite #=> if(opposite) { number = -42; }
# Functions:
square = (x) -> x * x #=> var square = function(x) { return x * x; }
# Ranges:
list = [1..5] #=> var list = [1, 2, 3, 4, 5];
# Objects:
math =
root: Math.sqrt
square: square
cube: (x) -> x * square x
#=> var math = {
# "root": Math.sqrt,
# "square": square,
# "cube": function(x) { return x * square(x); }
# };
# Splats:
race = (winner, runners...) ->
print winner, runners
#=>race = function() {
# var runners, winner;
# winner = arguments[0], runners = 2 <= arguments.length ? __slice.call(arguments, 1) : [];
# return print(winner, runners);
# };
# Existence:
alert "I knew it!" if elvis?
#=> if(typeof elvis !== "undefined" && elvis !== null) { alert("I knew it!"); }
# Array comprehensions:
cubes = (math.cube num for num in list)
#=>cubes = (function() {
87
# var _i, _len, _results;
# _results = [];
# for (_i = 0, _len = list.length; _i < _len; _i++) {
# num = list[_i];
# _results.push(math.cube(num));
# }
# return _results;
# })();
Additional resources
• Smooth CoffeeScript
• CoffeeScript Ristretto
Coldfusion
ColdFusion is a scripting language for web development. Read more here.
CFML
<!--- Comments start with "<!---" and end with "--->" --->
<!---
Comments can
also
span
multiple lines
--->
88
<!--- Displaying simple data --->
<!--- Use <cfoutput> for simple values such as strings, numbers, and expressions --->
<p>Display <b>myVariable</b>: <cfoutput>#myVariable#</cfoutput></p><!--- myValue --->
<p>Display <b>myNumber</b>: <cfoutput>#myNumber#</cfoutput></p><!--- 3.14 --->
<hr />
<h1>Complex Variables</h1>
<!--- Declaring complex variables --->
<!--- Declaring an array of 1 dimension: literal or bracket notation --->
<p>Set <b>myArray1</b> to an array of 1 dimension using literal or bracket notation</p>
<cfset myArray1 = [] />
<!--- Declaring an array of 1 dimension: function notation --->
<p>Set <b>myArray2</b> to an array of 1 dimension using function notation</p>
<cfset myArray2 = ArrayNew(1) />
<hr />
<h3>Alternative Notation</h3>
<p>Is 1 == 1? <cfoutput>#1 eq 1#</cfoutput></p>
<p>Is 15 != 1? <cfoutput>#15 neq 1#</cfoutput></p>
<p>Is 10 > 8? <cfoutput>#10 gt 8#</cfoutput></p>
<p>Is 1 < 2? <cfoutput>#1 lt 2#</cfoutput></p>
<p>Is 10 >= 5? <cfoutput>#10 gte 5#</cfoutput></p>
<p>Is 1 <= 5? <cfoutput>#1 lte 5#</cfoutput></p>
<hr />
89
<!--- Control Structures --->
<h1>Control Structures</h1>
<hr />
<h2>Switch Statement</h2>
90
<cfcase value="99">
<p><cfoutput>#i#</cfoutput> is ninety-nine.</p>
</cfcase>
<cfdefaultcase>
<p><cfoutput>#i#</cfoutput> is not 5, 15, 45, or 99.</p>
</cfdefaultcase>
</cfswitch>
</cfloop>
<hr />
<h1>Converting types</h1>
<style>
table.table th, table.table td {
border: 1px solid #000000;
padding: 2px;
}
table.table th {
background-color: #CCCCCC;
}
</style>
91
<td>"Yes"</td>
</tr>
<tr>
<th>FALSE</th>
<td>FALSE</td>
<td>0</td>
<td>Error</td>
<td>"No"</td>
</tr>
<tr>
<th>Number</th>
<td>True if Number is not 0; False otherwise.</td>
<td>Number</td>
<td>See "Date-time values" earlier in this chapter.</td>
<td>String representation of the number (for example, "8").</td>
</tr>
<tr>
<th>String</th>
<td>If "Yes", True <br>If "No", False <br>If it can be converted to 0, False <br>If it can b
<td>If it represents a number (for example, "1,000" or "12.36E-12"), it is c
<td>If it represents a date-time (see next column), it is converted to the numeric value of
<td>String</td>
</tr>
<tr>
<th>Date</th>
<td>Error</td>
<td>The numeric value of the date-time object.</td>
<td>Date</td>
<td>An ODBC timestamp.</td>
</tr>
</tbody>
</table>
<hr />
<h1>Components</h1>
<cfcomponent>
<cfset this.hello = "Hello" />
<cfset this.world = "world" />
<cffunction name="sayHello">
<cfreturn this.hello & ", " & this.world & "!" />
</cffunction>
<cffunction name="setHello">
<cfargument name="newHello" type="string" required="true" />
92
<cffunction name="setWorld">
<cfargument name="newWorld" type="string" required="true" />
<cffunction name="getHello">
<cfreturn this.hello />
</cffunction>
<cffunction name="getWorld">
<cfreturn this.world />
</cffunction>
</cfcomponent>
<cffunction name="sayHello">
<cfreturn this.hello & ", " & this.world & "!" />
</cffunction>
<cffunction name="setHello">
<cfargument name="newHello" type="string" required="true" />
<cffunction name="setWorld">
<cfargument name="newWorld" type="string" required="true" />
<cffunction name="getHello">
<cfreturn this.hello />
</cffunction>
<cffunction name="getWorld">
<cfreturn this.world />
</cffunction>
<b>sayHello()</b>
<cfoutput><p>#sayHello()#</p></cfoutput>
<b>getHello()</b>
<cfoutput><p>#getHello()#</p></cfoutput>
93
<b>getWorld()</b>
<cfoutput><p>#getWorld()#</p></cfoutput>
<b>setHello("Hola")</b>
<cfoutput><p>#setHello("Hola")#</p></cfoutput>
<b>setWorld("mundo")</b>
<cfoutput><p>#setWorld("mundo")#</p></cfoutput>
<b>sayHello()</b>
<cfoutput><p>#sayHello()#</p></cfoutput>
<b>getHello()</b>
<cfoutput><p>#getHello()#</p></cfoutput>
<b>getWorld()</b>
<cfoutput><p>#getWorld()#</p></cfoutput>
CFScript
ColdFusion Script
In recent years, the ColdFusion language has added script syntax to mirror tag functionality. When using
an up-to-date CF server, almost all functionality is available using scrypt syntax.
Further Reading
The links provided here below are just to get an understanding of the topic, feel free to Google and find
specific examples.
1. Coldfusion Reference From Adobe
2. Open Source Documentation
Common-Lisp
ANSI Common Lisp is a general purpose, multi-paradigm programming language suited for a wide variety
of industry applications. It is frequently referred to as a programmable programming language.
The classic starting point is Practical Common Lisp and freely available.
Another popular and recent book is Land of Lisp.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; 0. Syntax
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Lisp has two fundamental pieces of syntax: the ATOM and the
;; S-expression. Typically, grouped S-expressions are called `forms`.
(+ 1 2 3 4) ; an s-expression
94
'(4 :foo t) ;another one
;;; Comments
;; Single line comments start with a semicolon; use two for normal
;; comments, three for section comments, and four for file-level
;; comments.
#| Block comments
can span multiple lines and...
#|
they can be nested!
|#
|#
;;; Environment.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; 1. Primitive Datatypes and Operators
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; Symbols
;;; Numbers
9999999999999999999999 ; integers
#b111 ; binary => 7
#o111 ; octal => 73
#x111 ; hexadecimal => 273
3.14159s0 ; single
3.14159d0 ; double
1/2 ; ratios
#C(1 2) ; complex numbers
95
;; Function application is written (f x y z ...)
;; where f is a function and x, y, z, ... are operands
;; If you want to create a literal list of data, use ' to stop it from
;; being evaluated - literally, "quote" the data.
'(+ 1 2) ; => (+ 1 2)
;; You can also call a function manually:
(funcall #'+ 1 2 3) ; => 6
;; Some arithmetic operations
(+ 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)
;;; Booleans
t ; for true (any not-nil value is true)
nil ; for false - and the empty list
(not nil) ; => t
(and 0 t) ; => t
(or 0 nil) ; => 0
;;; Characters
#\A ; => #\A
#\� ; => #\GREEK_SMALL_LETTER_LAMDA
#\u03BB ; => #\GREEK_SMALL_LETTER_LAMDA
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; 2. Variables
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; You can create a global (dynamically scoped) using defparameter
;; a variable name can use any character except: ()",'`;#|\
96
(defparameter *some-var* 5)
*some-var* ; => 5
;; Local binding: `me` is bound to "dance with you" only within the
;; (let ...). Let always returns the value of the last `form` in the
;; let form.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; 3. Structs and Collections
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Structs
(defstruct dog name breed age)
(defparameter *rover*
(make-dog :name "rover"
:breed "collie"
:age 5))
*rover* ; => #S(DOG :NAME "rover" :BREED "collie" :AGE 5)
;;; Pairs
;; `cons' constructs pairs, `car' and `cdr' extract the first
;; and second elements
(cons 'SUBJECT 'VERB) ; => '(SUBJECT . VERB)
(car (cons 'SUBJECT 'VERB)) ; => SUBJECT
(cdr (cons 'SUBJECT 'VERB)) ; => VERB
;;; Lists
;; Lists are linked-list data structures, made of `cons' pairs and end
;; with a `nil' (or '()) to mark the end of the list
(cons 1 (cons 2 (cons 3 nil))) ; => '(1 2 3)
;; `list' is a convenience variadic constructor for lists
(list 1 2 3) ; => '(1 2 3)
;; and a quote can also be used for a literal list value
'(1 2 3) ; => '(1 2 3)
97
;; Can still use `cons' to add an item to the beginning of a list
(cons 4 '(1 2 3)) ; => '(4 1 2 3)
;; Or use concatenate -
;; Lists are a very central type, so there is a wide variety of functionality for
;; them, a few examples:
(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)
;;; Vectors
;;; Arrays
;; 2D arrays
98
; => 0
;; But you'll want to use a better data structure than a linked list
;; for performant work!
;; set a value
(setf (gethash 'a *m*) 1)
;; Retrieve a value
(gethash 'a *m*) ; => 1, t
(multiple-value-bind
(a b)
99
(gethash 'd *m*)
(list a b))
; => (NIL NIL)
(multiple-value-bind
(a b)
(gethash 'a *m*)
(list a b))
; => (1 T)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; 3. Functions
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Or Apply
(apply (lambda () "Hello World") nil) ; => "Hello World"
(hello "Steve")
; => Hello, Steve, from The world
100
; => Hello, Steve, from the alpacas
(generalized-greeter "Jim" :from "the alpacas you met last summer" :honorific "Mr")
; => Hello, Mr Jim, from the alpacas you met last summer
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; 4. Equality
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Common Lisp has a sophisticated equality system. A couple are covered here.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; 5. Control Flow
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; Conditionals
101
(t 'ok)) ; => 'OK
; => :int
;;; Iteration
; => 1234
; => (0 1 2 3 4 5 6 7 8 9)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; 6. Mutation
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; 7. Classes and Objects
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
102
;; Conveyances.
(defclass human-powered-conveyance ()
((velocity
:accessor velocity
:initarg :velocity)
(average-efficiency
:accessor average-efficiency
:initarg :average-efficiency))
(:documentation "A human powered conveyance"))
(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
103
; 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)
;; Let's suppose we find out that the efficiency value of the number
;; of rowers in a canoe is roughly logarithmic. This should probably be set
;; in the constructor/initializer.
;; Here's how to initialize your instance after Common Lisp gets done
;; constructing it:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; 8. Macros
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Common Lisp doesn't come with a WHILE loop- let's add one.
;; If we obey our assembler instincts, we wind up with:
104
,block-name
(unless ,condition
(go ,done))
(progn
,@body)
(go ,block-name)
,done)))
Further Reading
• Keep moving on to the Practical Common Lisp book.
• A Gentle Introduction to…
Extra Info
• CLiki
• common-lisp.net
• Awesome Common Lisp
Credits.
Lots of thanks to the Scheme people for rolling up a great starting point which could be easily moved to
Common Lisp.
• Paul Khuong for some great reviewing.
105
Compojure
(defroutes myapp
(GET "/" [] "Hello World"))
(defn -main []
(run-server myapp {:port 5000}))
Step 1: Create a project with Leiningen:
lein new myapp
Step 2: Put the above code in src/myapp/core.clj
Step 3: Add some dependencies to project.clj:
[compojure "1.1.8"]
[http-kit "2.1.16"]
Step 4: Run:
lein run -m myapp.core
View at: http://localhost:5000/
Compojure apps will run on any ring-compatible server, but we recommend http-kit for its performance and
massive concurrency.
Routes
In compojure, each route is an HTTP method paired with a URL-matching pattern, an argument list, and
a body.
(defroutes myapp
(GET "/" [] "Show something")
(POST "/" [] "Create something")
(PUT "/" [] "Replace something")
(PATCH "/" [] "Modify Something")
(DELETE "/" [] "Annihilate something")
(OPTIONS "/" [] "Appease something")
(HEAD "/" [] "Preview something"))
Compojure route definitions are just functions which accept request maps and return response maps:
(myapp {:uri "/" :request-method :post})
; => {:status 200
; :headers {"Content-Type" "text/html; charset=utf-8}
; :body "Create Something"}
The body may be a function, which must accept the request as a parameter:
(defroutes myapp
(GET "/" [] (fn [req] "Do something with req")))
106
Or, you can just use the request directly:
(defroutes myapp
(GET "/" req "Do something with req"))
Route patterns may include named parameters:
(defroutes myapp
(GET "/hello/:name" [name] (str "Hello " name)))
You can adjust what each parameter matches by supplying a regex:
(defroutes myapp
(GET ["/file/:name.:ext" :name #".*", :ext #".*"] [name ext]
(str "File: " name ext)))
Middleware
Clojure uses Ring for routing. Handlers are just functions that accept a request map and return a response
map (Compojure will turn strings into 200 responses for you).
You can easily write middleware that wraps all or part of your application to modify requests or responses:
(defroutes myapp
(GET "/" req (str "Hello World v" (:app-version req))))
(defn -main []
(run-server (wrap-version myapp) {:port 5000}))
Ring-Defaults provides some handy middlewares for sites and apis, so add it to your dependencies:
[ring/ring-defaults "0.1.1"]
Then, you can import it in your ns:
(ns myapp.core
(:require [compojure.core :refer :all]
[ring.middleware.defaults :refer :all]
[org.httpkit.server :refer [run-server]]))
And use wrap-defaults to add the site-defaults middleware to your app:
(defn -main []
(run-server (wrap-defaults myapp site-defaults) {:port 5000}))
Now, your handlers may utilize query parameters:
(defroutes myapp
(GET "/posts" req
(let [title (get (:params req) :title)
author (get (:params req) :author)]
(str "Title: " title ", Author: " author))))
Or, for POST and PUT requests, form parameters as well
(defroutes myapp
(POST "/posts" req
(let [title (get (:params req) :title)
107
author (get (:params req) :author)]
(str "Title: " title ", Author: " author))))
Return values
The return value of a route block determines the response body passed on to the HTTP client, or at least
the next middleware in the ring stack. Most commonly, this is a string, as in the above examples. But, you
may also return a response map:
(defroutes myapp
(GET "/" []
{:status 200 :body "Hello World"})
(GET "/is-403" []
{:status 403 :body ""})
(GET "/is-json" []
{:status 200 :headers {"Content-Type" "application/json"} :body "{}"}))
Static Files
To serve up static files, use compojure.route.resources. Resources will be served from your project’s
resources/ folder.
(require '[compojure.route :as route])
(defroutes myapp
(GET "/")
(route/resources "/")) ; Serve static resources at the root path
Views / Templates
To use templating with Compojure, you’ll need a template library. Here are a few:
Stencil
Stencil is a Mustache template library:
(require '[stencil.core :refer [render-string]])
(defroutes myapp
(GET "/hello/:name" [name]
(render-string "Hello {{name}}" {:name name})))
You can easily read in templates from your resources directory. Here’s a helper function
(require 'clojure.java.io)
(defroutes myapp
(GET "/hello/:name" [name]
(render-string (read-template "templates/hello.html") {:name name})))
108
Selmer
Selmer is a Django and Jinja2-inspired templating language:
(require '[selmer.parser :refer [render-file]])
(defroutes myapp
(GET "/hello/:name" [name]
(render-file "templates/hello.html" {:name name})))
Hiccup
Hiccup is a library for representing HTML as Clojure code
(require '[hiccup.core :as hiccup])
(defroutes myapp
(GET "/hello/:name" [name]
(hiccup/html
[:html
[:body
[:h1 {:class "title"}
(str "Hello " name)]]])))
Markdown
Markdown-clj is a Markdown implementation.
(require '[markdown.core :refer [md-to-html-string]])
(defroutes myapp
(GET "/hello/:name" [name]
(md-to-html-string "## Hello, world")))
Further reading:
• Official Compojure Documentation
• Clojure for the Brave and True
Csharp
C# is an elegant and type-safe object-oriented language that enables developers to build a variety of secure
and robust applications that run on the .NET Framework.
Read more here.
// Single-line comments start with //
/*
Multi-line comments look like this
*/
/// <summary>
/// This is an XML documentation comment which can be used to generate external
/// documentation or provide context help within an IDE
/// </summary>
/// <param name="firstParam">This is some parameter documentation for firstParam</param>
/// <returns>Information on the returned value of a function</returns>
//public void MethodOrClassOrOtherWithParsableHelp(string firstParam) {}
109
// Specify the namespaces this source code will be using
// The namespaces below are all part of the standard .NET Framework Class Library
using System;
using System.Collections.Generic;
using System.Dynamic;
using System.Linq;
using System.Net;
using System.Threading.Tasks;
using System.IO;
///////////////////////////////////////////////////
// Types & Variables
//
// Declare a variable using <type> <name>
///////////////////////////////////////////////////
110
// Unsigned - (0 <= ushort <= 65,535)
short fooShort = 10000;
ushort fooUshort = 10000;
// Decimal - a 128-bits data type, with more precision than other floating-point types,
// suited for financial and monetary calculations
decimal fooDecimal = 150.3m;
// Strings -- unlike the previous base types which are all value types,
// a string is a reference type. That is, you can set it to null
string fooString = "\"escape\" quotes and add \n (new lines) and \t (tabs)";
Console.WriteLine(fooString);
// You can split a string over two lines with the @ symbol. To escape " use ""
string bazString = @"Here's some stuff
on a new line! ""Wow!"", the masses cried";
111
// Use const or read-only to make a variable immutable
// const values are calculated at compile time
const int HoursWorkPerWeek = 9001;
///////////////////////////////////////////////////
// Data Structures
///////////////////////////////////////////////////
// Lists
// Lists are used more frequently than arrays as they are more flexible
// The format for declaring a list is follows:
// List<datatype> <var name> = new List<datatype>();
List<int> intList = new List<int>();
List<string> stringList = new List<string>();
List<int> z = new List<int> { 9000, 1000, 1337 }; // initialize
// The <> are for generics - Check out the cool stuff section
///////////////////////////////////////
// Operators
///////////////////////////////////////
Console.WriteLine("\n->Operators");
// Arithmetic is straightforward
Console.WriteLine(i1 + i2 - i1 * 3 / 7); // => 3
// Modulo
112
Console.WriteLine("11%3 = " + (11 % 3)); // => 2
// Comparison operators
Console.WriteLine("3 == 2? " + (3 == 2)); // => false
Console.WriteLine("3 != 2? " + (3 != 2)); // => true
Console.WriteLine("3 > 2? " + (3 > 2)); // => true
Console.WriteLine("3 < 2? " + (3 < 2)); // => false
Console.WriteLine("2 <= 2? " + (2 <= 2)); // => true
Console.WriteLine("2 >= 2? " + (2 >= 2)); // => true
// Bitwise operators!
/*
~ Unary bitwise complement
<< Signed left shift
>> Signed right shift
& Bitwise AND
^ Bitwise exclusive OR
| Bitwise inclusive OR
*/
// Incrementations
int i = 0;
Console.WriteLine("\n->Inc/Dec-rementation");
Console.WriteLine(i++); //Prints "0", i = 1. Post-Incrementation
Console.WriteLine(++i); //Prints "2", i = 2. Pre-Incrementation
Console.WriteLine(i--); //Prints "2", i = 1. Post-Decrementation
Console.WriteLine(--i); //Prints "0", i = 0. Pre-Decrementation
///////////////////////////////////////
// Control Structures
///////////////////////////////////////
Console.WriteLine("\n->Control Structures");
// Ternary operators
// A simple if/else can be written as follows
// <condition> ? <true> : <false>
int toCompare = 17;
string isTrue = toCompare == 17 ? "True" : "False";
113
// While loop
int fooWhile = 0;
while (fooWhile < 100)
{
//Iterated 100 times, fooWhile 0->99
fooWhile++;
}
// Do While Loop
int fooDoWhile = 0;
do
{
// Start iteration 100 times, fooDoWhile 0->99
if (false)
continue; // skip the current iteration
fooDoWhile++;
if (fooDoWhile == 50)
break; // breaks from the loop completely
// Switch Case
// A switch works with the byte, short, char, and int data types.
// It also works with enumerated types (discussed in Enum Types),
// the String class, and a few special classes that wrap
// primitive types: Character, Byte, Short, and Integer.
int month = 3;
string monthString;
switch (month)
{
case 1:
monthString = "January";
break;
case 2:
monthString = "February";
114
break;
case 3:
monthString = "March";
break;
// You can assign more than one case to an action
// But you can't add an action without a break before another case
// (if you want to do this, you would have to explicitly add a goto case x
case 6:
case 7:
case 8:
monthString = "Summer time!!";
break;
default:
monthString = "Some other month";
break;
}
///////////////////////////////////////
// Converting Data Types And Typecasting
///////////////////////////////////////
// Converting data
// Casting
// Cast decimal 15 to a int
// and then implicitly cast to long
long x = (int) 15M;
}
///////////////////////////////////////
// CLASSES - see definitions at end of file
///////////////////////////////////////
public static void Classes()
{
// See Declaration of objects at end of file
115
// Call object methods
trek.SpeedUp(3); // You should always use setter and getter methods
trek.Cadence = 100;
Console.Read();
} // End main method
// CONSOLE ENTRY A console application must have a main method as an entry point
public static void Main(string[] args)
{
OtherInterestingFeatures();
}
//
// INTERESTING FEATURES
//
public // Visibility
static // Allows for direct call on class without object
int // Return Type,
MethodSignatures(
int maxCount, // First variable, expects an int
int count = 0, // will default the value to 0 if not passed in
int another = 3,
params string[] otherParams // captures all other parameters passed to method
)
{
return -1;
}
// Methods can have the same name, as long as the signature is unique
// A method that differs only in return type is not unique
public static void MethodSignatures(
ref int maxCount, // Pass by reference
out int count)
{
//the argument passed in as 'count' will hold the value of 15 outside of this function
count = 15; // out param must be assigned before control leaves the method
}
// GENERICS
// The classes for TKey and TValue is specified by the user calling this function.
// This method emulates the SetDefault of Python
public static TValue SetDefault<TKey, TValue>(
116
IDictionary<TKey, TValue> dictionary,
TKey key,
TValue defaultItem)
{
TValue result;
if (!dictionary.TryGetValue(key, out result))
return dictionary[key] = defaultItem;
return result;
}
// YIELD
// Usage of the "yield" keyword indicates that the method it appears in is an Iterator
// (this means you can use it in a foreach loop)
public static IEnumerable<int> YieldCounter(int limit = 10)
{
for (var i = 0; i < limit; i++)
yield return i;
}
117
public static void OtherInterestingFeatures()
{
// OPTIONAL PARAMETERS
MethodSignatures(3, 1, 3, "Some", "Extra", "Strings");
MethodSignatures(3, another: 3); // explicitly set a parameter, skipping optional ones
// EXTENSION METHODS
int i = 3;
i.Print(); // Defined below
// IMPLICITLY TYPED VARIABLES - you can let the compiler work out what the type is:
var magic = "magic is a string, at compile time, so you still get type safety";
// magic = 9; will not work as magic is a string, not an int
// GENERICS
//
var phonebook = new Dictionary<string, string>() {
{"Sarah", "212 555 5555"} // Add some entries to the phone book
};
118
// will no longer execute because CreateWithGears throws an exception
string some = "";
if (true) some = null;
some.ToLower(); // throws a NullReferenceException
}
catch (NotSupportedException)
{
Console.WriteLine("Not so much fun now!");
}
catch (Exception ex) // catch all other exceptions
{
throw new ApplicationException("It hit the fan", ex);
// throw; // A rethrow that preserves the callstack
}
// catch { } // catch-all without capturing the Exception
finally
{
// executes after try or catch
}
// PARALLEL FRAMEWORK
// http://blogs.msdn.com/b/csharpfaq/archive/2010/06/01/parallel-programming-in-net-framewor
var websites = new string[] {
"http://www.google.com", "http://www.reddit.com",
"http://www.shaunmccarthy.com"
};
var responses = new Dictionary<string, string>();
// Will spin up separate threads for each request, and join on them
// before going to the next step!
Parallel.ForEach(websites,
new ParallelOptions() {MaxDegreeOfParallelism = 3}, // max of 3 threads
website =>
{
// Do something that takes a long time on the file
using (var r = WebRequest.Create(new Uri(website)).GetResponse())
{
responses[website] = r.ContentType;
}
});
// This won't happen till after all requests have been completed
foreach (var key in responses.Keys)
119
Console.WriteLine("{0}:{1}", key, responses[key]);
// You can even add methods (returns a string, and takes in a string)
student.Introduce = new Func<string, string>(
(introduceTo) => string.Format("Hey {0}, this is {1}", student.FirstName, introduceTo));
Console.WriteLine(student.Introduce("Beth"));
// IQUERYABLE<T> - almost all collections implement this, which gives you a lot of
// very useful Map / Filter / Reduce style methods
var bikes = new List<Bicycle>();
bikes.Sort(); // Sorts the array
bikes.Sort((b1, b2) => b1.Wheels.CompareTo(b2.Wheels)); // Sorts based on wheels
var result = bikes
.Where(b => b.Wheels > 3) // Filters - chainable (returns IQueryable of previous type)
.Where(b => b.IsBroken && b.HasTassles)
.Select(b => b.ToString()); // Map - we only this selects, so result is a IQueryable<str
var sum = bikes.Sum(b => b.Wheels); // Reduce - sums all the wheels in the collection
// ASPARALLEL
// And this is where things get wicked - combines linq and parallel operations
var threeWheelers = bikes.AsParallel().Where(b => b.Wheels == 3).Select(b => b.Name);
// this will happen in parallel! Threads will automagically be spun up and the
// results divvied amongst them! Amazing for large datasets when you have lots of
// cores
// Now the query runs, but opens a reader, so only populates are you iterate through
foreach (string bike in query)
Console.WriteLine(result);
120
}
protected virtual int Gear // Protected: Accessible from the class and subclasses
{
get; // creates an auto property so you don't need a member field
set;
}
int _speed; // Everything is private by default: Only accessible from within this class.
// can also use keyword private
121
public string Name { get; set; }
public BikeBrand Brand; // After declaring an enum type, we can declare the field of this type
// Decorate an enum with the FlagsAttribute to indicate that multiple values can be switched on
// Any class derived from Attribute can be used to decorate types, methods, parameters etc
// Bitwise operators & and | can be used to perform and/or operations
[Flags]
public enum BikeAccessories
{
None = 0,
Bell = 1,
MudGuards = 2, // need to set the values manually!
Racks = 4,
Lights = 8,
FullPackage = Bell | MudGuards | Racks | Lights
}
// Usage: aBike.Accessories.HasFlag(Bicycle.BikeAccessories.Bell)
// Before .NET 4: (aBike.Accessories & Bicycle.BikeAccessories.Bell) == Bicycle.BikeAccessories.
public BikeAccessories Accessories { get; set; }
// Static members belong to the type itself rather then specific object.
// You can access them without a reference to any object:
// Console.WriteLine("Bicycles created: " + Bicycle.bicyclesCreated);
public static int BicyclesCreated { get; set; }
122
Brand = BikeBrand.AIST;
BicyclesCreated++;
}
// Function Syntax:
// <public/private/protected> <return type> <function name>(<args>)
123
// to restrict its access:
public bool IsBroken { get; private set; }
set {
passengers[i] = value;
}
}
124
// (Penny Farthings are those bicycles with the big front wheel.
// They have no gears.)
interface IBreakable
{
bool Broken { get; } // interfaces can contain properties as well as methods & events
}
// Classes can inherit only one other class, but can implement any amount of interfaces,
// however the base class name must be the first in the list and all interfaces follow
class MountainBike : Bicycle, IJumpable, IBreakable
{
int damage = 0;
125
{
damage += meters;
}
/// <summary>
/// Used to connect to DB for LinqToSql example.
/// EntityFramework Code First is awesome (similar to Ruby's ActiveRecord, but bidirectional)
/// http://msdn.microsoft.com/en-us/data/jj193542.aspx
/// </summary>
public class BikeRepository : DbContext
{
public BikeRepository()
: base()
{
}
// A2.cs
public partial class A
{
public static void A2()
{
Console.WriteLine("Method A2 in class A");
}
}
126
}
}
class Program
{
static void Main(string[] args)
{
Rectangle rect = new Rectangle { Length = 5, Width = 3 };
Console.WriteLine($"The length is {rect.Length} and the width is {rect.Width}");
}
}
} // End Namespace
Further Reading
• DotNetPerls
• C# in Depth
• Programming C#
• LINQ
• MSDN Library
• ASP.NET MVC Tutorials
• ASP.NET Web Matrix Tutorials
• ASP.NET Web Forms Tutorials
• Windows Forms Programming in C#
• C# Coding Conventions
Css
Web pages are built with HTML, which specifies the content of a page. CSS (Cascading Style Sheets) is a
separate language which specifies a page’s appearance.
127
CSS code is made of static rules. Each rule takes one or more selectors and gives specific values to a number
of visual properties. Those properties are then applied to the page elements indicated by the selectors.
This guide has been written with CSS 2 in mind, which is extended by the new features of CSS 3.
NOTE: Because CSS produces visual results, in order to learn it, you need to try everything in a CSS
playground like dabblet. The main focus of this article is on the syntax and some general tips.
Syntax
/* comments appear inside slash-asterisk, just like this line!
there are no "one-line comments"; this is the only comment style */
/* ####################
## SELECTORS
#################### */
/*
Here is an example element:
/* or both classes! */
.class1.class2 { }
/* or its name */
div { }
/* or its id */
#anID { }
128
/* or contains a value in a dash-separated list, e.g., "-" (U+002D) */
[otherAttr|='en'] { font-size:smaller; }
/* You can combine different selectors to create a more focused selector. Don't
put spaces between them. */
div.some-class[attr$='ue'] { }
/* There are some selectors called pseudo classes that can be used to select an
element only when it is in a particular state */
/* or an element is in focus */
selected:focus { }
/* Just like pseudo classes, pseudo elements allow you to style certain parts of
a document */
129
selector::after {}
/* ####################
## PROPERTIES
#################### */
selector {
/* Relative units */
width: 50%; /* percentage of parent element width */
font-size: 2em; /* multiples of element's original font-size */
font-size: 2rem; /* or the root element's font-size */
font-size: 2vw; /* multiples of 1% of the viewport's width (CSS 3) */
font-size: 2vh; /* or its height */
font-size: 2vmin; /* whichever of a vh or a vw is smaller */
font-size: 2vmax; /* or greater */
/* Absolute units */
width: 200px; /* pixels */
font-size: 20pt; /* points */
width: 5cm; /* centimeters */
min-width: 50mm; /* millimeters */
max-width: 5in; /* inches */
/* Colors */
color: #F6E; /* short hex format */
color: #FF66EE; /* long hex format */
color: tomato; /* a named color */
color: rgb(255, 255, 255); /* as rgb values */
color: rgb(10%, 20%, 50%); /* as rgb percentages */
color: rgba(255, 0, 0, 0.3); /* as rgba values (CSS 3) Note: 0 <= a <= 1 */
color: transparent; /* equivalent to setting the alpha to 0 */
color: hsl(0, 100%, 50%); /* as hsl percentages (CSS 3) */
color: hsla(0, 100%, 50%, 0.3); /* as hsl percentages with alpha */
/* Borders */
border-width:5px;
border-style:solid;
border-color:red; /* similar to how background-color is set */
border: 5px solid red; /* this is a short hand approach for the same */
border-radius:20px; /* this is a CSS3 property */
/* Fonts */
130
font-family: Arial;
/* if the font family name has a space, it must be quoted */
font-family: "Courier New";
/* if the first one is not found, the browser uses the next, and so on */
font-family: "Courier New", Trebuchet, Arial, sans-serif;
}
Usage
Save a CSS stylesheet with the extension .css.
<!-- You need to include the css file in your page's <head>. This is the
recommended method. Refer to http://stackoverflow.com/questions/8284365 -->
<link rel='stylesheet' type='text/css' href='path/to/style.css' />
<!-- You can also include some CSS inline in your markup. -->
<style>
a { color: purple; }
</style>
Precedence or Cascade
An element may be targeted by multiple selectors and may have a property set on it in more than once. In
these cases, one of the rules takes precedence over others. Rules with a more specific selector take precedence
over a less specific one, and a rule occurring later in the stylesheet overwrites a previous one (which also
means that if two different linked stylesheets contain rules for an element and if the rules are of the same
specificity, then order of linking would take precedence and the sheet linked latest would govern styling) .
This process is called cascading, hence the name Cascading Style Sheets.
Given the following CSS:
/* A */
p.class1[attr='value']
/* B */
p.class1 { }
/* C */
p.class2 { }
/* D */
p { }
/* E */
p { property: value !important; }
and the following markup:
<p style='/*F*/ property:value;' class='class1 class2' attr='value' />
The precedence of style is as follows. Remember, the precedence is for each property, not for the entire
block.
131
• E has the highest precedence because of the keyword !important. It is recommended that you avoid
its usage.
• F is next, because it is an inline style.
• A is next, because it is more “specific” than anything else. It has 3 specifiers: The name of the element
p, its class class1, an attribute attr='value'.
• C is next, even though it has the same specificity as B. This is because it appears after B.
• B is next.
• D is the last one.
Compatibility
Most of the features in CSS 2 (and many in CSS 3) are available across all browsers and devices. But it’s
always good practice to check before using a new feature.
Resources
• CanIUse (Detailed compatibility info)
• Dabblet (CSS playground)
• Mozilla Developer Network’s CSS documentation (Tutorials and reference)
• Codrops’ CSS Reference (Reference)
Further Reading
• Understanding Style Precedence in CSS: Specificity, Inheritance, and the Cascade
• Selecting elements using attributes
• QuirksMode CSS
• Z-Index - The stacking context
• SASS and LESS for CSS pre-processing
• CSS-Tricks
D
// You know what's coming...
module hello;
import std.stdio;
// args is optional
void main(string[] args) {
writeln("Hello, World!");
}
If you’re like me and spend way too much time on the internet, odds are you’ve heard about D. The D
programming language is a modern, general-purpose, multi-paradigm language with support for everything
from low-level features to expressive high-level abstractions.
D is actively developed by a large group of super-smart people and is spearheaded by Walter Bright and
Andrei Alexandrescu. With all that out of the way, let’s look at some examples!
import std.stdio;
void main() {
132
// Conditionals and loops work as expected.
for(int i = 0; i < 10000; i++) {
writeln(i);
}
do {
n -= (n / 2);
} while(n > 0);
// For and while are nice, but in D-land we prefer 'foreach' loops.
// The '..' creates a continuous range, including the first value
// but excluding the last.
foreach(n; 1..1_000_000) {
if(n % 2 == 0)
writeln(n);
}
class BinTree(T) {
T data = null;
133
enum Day {
Sunday,
Monday,
Tuesday,
Wednesday,
Thursday,
Friday,
Saturday,
}
return a;
}
// Use the ref keyword to ensure pass by reference. That is, even if 'a' and 'b'
// are value types, they will always be passed by reference to 'swap()'.
void swap(T)(ref T a, ref T b) {
auto temp = a;
a = b;
b = temp;
}
auto mat = new Matrix!(3, 3); // We've defaulted type 'T' to 'int'.
Speaking of classes, let’s talk about properties for a second. A property is roughly a function that may act
like an lvalue, so we can have the syntax of POD structures (structure.x = 7) with the semantics of getter
and setter methods (object.setX(7))!
// Consider a class parameterized on types 'T' & 'U'.
class MyClass(T, U) {
T _data;
U _other;
}
134
// Constructors are always named 'this'.
this(T t, U u) {
// This will call the setter methods below.
data = t;
other = u;
}
// getters
@property T data() {
return _data;
}
@property U other() {
return _other;
}
// setters
@property void data(T t) {
_data = t;
}
// Import the 'stdio' module from the standard library for writing to
// console (imports can be local to a scope).
import std.stdio;
135
import std.algorithm : map, filter, reduce;
import std.range : iota; // builds an end-exclusive range
void main() {
// We want to print the sum of a list of squares of even ints
// from 1 to 100. Easy!
writeln(num);
}
Notice how we got to build a nice Haskellian pipeline to compute num? That’s thanks to a D innovation
know as Uniform Function Call Syntax (UFCS). With UFCS, we can choose whether to write a function call
as a method or free function call! Walter wrote a nice article on this here. In short, you can call functions
whose first parameter is of some type A on any expression of type A as a method.
I like parallelism. Anyone else like parallelism? Sure you do. Let’s do some!
// Let's say we want to populate a large array with the square root of all
// consecutive integers starting from 1 (up until the size of the array), and we
// want to do this concurrently taking advantage of as many cores as we have
// available.
import std.stdio;
import std.parallelism : parallel;
import std.math : sqrt;
void main() {
// Create your large array
auto arr = new double[1_000_000];
Dart
Dart is a newcomer into the realm of programming languages. It borrows a lot from other mainstream
languages, having as a goal not to deviate too much from its JavaScript sibling. Like JavaScript, Dart aims
for great browser integration.
Dart’s most controversial feature must be its Optional Typing.
import "dart:collection";
import "dart:math" as DM;
136
// This is an executable tutorial. You can run it with Dart or on
// the Try Dart! site if you copy/paste it there. http://try.dartlang.org/
// Class declaration with a sayIt method, which also has closure access
// to the outer variable as though it were a function as seen before.
var example5method = "Example5 sayIt";
class Example5Class {
sayIt() {
print(example5method);
}
137
}
example5() {
// Create an anonymous instance of the Example5Class and call the sayIt
// method on it.
new Example5Class().sayIt();
}
// Literals are great, but there's a restriction for what literals can be
// outside of function/method bodies. Literals on the outer scope of class
// 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"};
example8() {
print(example8A[0]);
print(example8M["someKey"]);
}
138
}
var i = 0;
while (i < example9A.length) {
print("Example9 while loop '${example9A[i]}'");
i++;
}
for (var e in example9A) {
print("Example9 for-in loop '${e}'");
}
example9A.forEach((e) => print("Example9 forEach loop '${e}'"));
}
139
example14() {
var v = true;
if (v) {
print("Example14 value is true");
}
v = null;
try {
if (v) {
// Never runs
} else {
// Never runs
}
} catch (e) {
print("Example14 null value causes an exception: '${e}'");
}
}
140
// actual difference between the two. The given flexibility can be good
// to avoid the need to escape content that matches the delimiter being
// used. For example, double-quotes of HTML attributes if the string
// contains HTML content.
example18() {
print('Example18 <a href="etc">'
"Don't can't I'm Etc"
'</a>');
}
// Optional types allow for the annotation of APIs and come to the aid of
// IDEs so the IDEs can better refactor, auto-complete and check for
// errors. So far we haven't declared any types and the programs have
// worked just fine. In fact, types are disregarded during runtime.
// Types can even be wrong and the program will still be given the
// benefit of the doubt and be run as though the types didn't matter.
// There's a runtime parameter that checks for type errors which is
// the checked mode, which is said to be useful during development time,
// but which is also slower because of the extra checking and is thus
// avoided during deployment runtime.
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");
141
print("Example21 names '${o.names}' and length '${o.length}'");
o.names = ["d", "e"];
print("Example21 names '${o.names}' and length '${o.length}'");
}
// Class inheritance takes the form of class name extends AnotherClassName {}.
class Example22A {
var _name = "Some Name!";
get name => _name;
}
class Example22B extends Example22A {}
example22() {
var o = new Example22B();
print("Example22 class inheritance '${o.name}'");
}
// The Class constructor method uses the same name of the class and
// takes the form of SomeClass() : super() {}, where the ": super()"
// part is optional and it's used to delegate constant parameters to the
// super-parent's constructor.
class Example24A {
var _value;
Example24A({value: "someValue"}) {
_value = value;
}
get value => _value;
}
class Example24B extends Example24A {
Example24B({value: "someOtherValue"}) : super(value: value);
142
}
example24() {
var o1 = new Example24B(),
o2 = new Example24B(value: "evenMore");
print("Example24 calling super during constructor '${o1.value}'");
print("Example24 calling super during constructor '${o2.value}'");
}
143
print("Example27 color is '${color}'");
print("Example27 color is '${o.color1}' and '${o.color2}'");
}
144
}
// Parse int, convert double to int, or just keep int when dividing numbers
// by using the ~/ operation. Let's play a guess game too.
example30() {
var gn, tooHigh = false,
n, n2 = (2.0).toInt(), top = int.parse("123") ~/ n2, bottom = 0;
top = top ~/ 6;
gn = new DM.Random().nextInt(top + 1); // +1 because nextInt top is exclusive
print("Example30 Guess a number between 0 and ${top}");
guessNumber(i) {
if (n == gn) {
print("Example30 Guessed right! The number is ${gn}");
} else {
tooHigh = n > gn;
print("Example30 Number ${n} is too "
"${tooHigh ? 'high' : 'low'}. Try again");
}
return n == gn;
}
n = (top - bottom) ~/ 2;
while (!guessNumber(n)) {
if (tooHigh) {
top = n - 1;
} else {
bottom = n + 1;
}
n = bottom + ((top - bottom) ~/ 2);
}
}
Further Reading
Dart has a comprehensive web-site. It covers API reference, tutorials, articles and more, including a useful
Try Dart online. http://www.dartlang.org/ http://try.dartlang.org/
145
Dynamic-Programming
Dynamic Programming
Introduction
Dynamic Programming is a powerful technique used for solving a particular class of problems as we will
see.The idea is very simple, If you have solved a problem with the given input, then save the result for future
reference, so as to avoid solving the same problem again.
Always remember!! “Those who can’t remember the past are condemned to repeat it”
References
• EDN spec
• Implementations
• Tagged Elements
Elisp
;; This gives an introduction to Emacs Lisp in 15 minutes (v0.2d)
;;
;; Author: Bastien / @bzg2 / http://bzg.fr
;;
;; First make sure you read this text by Peter Norvig:
;; http://norvig.com/21-days.html
;;
;; Then install GNU Emacs 24.3:
;;
146
;; Debian: apt-get install emacs (or see your distro instructions)
;; OSX: http://emacsformacosx.com/emacs-builds/Emacs-24.3-universal-10.6.8.dmg
;; Windows: http://ftp.gnu.org/gnu/windows/emacs/emacs-24.3-bin-i386.zip
;;
;; More general information can be found at:
;; http://www.gnu.org/software/emacs/#Obtaining
;; Important warning:
;;
;; Going through this tutorial won't damage your computer unless
;; you get so angry that you throw it on the floor. In that case,
;; I hereby decline any responsibility. Have fun!
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; Fire up Emacs.
;;
;; Hit the `q' key to dismiss the welcome message.
;;
;; Now look at the gray line at the bottom of the window:
;;
;; "*scratch*" is the name of the editing space you are now in.
;; This editing space is called a "buffer".
;;
;; The scratch buffer is the default buffer when opening Emacs.
;; You are never editing files: you are editing buffers that you
;; can save to a file.
;;
;; "Lisp interaction" refers to a set of commands available here.
;;
;; Emacs has a built-in set of commands available in every buffer,
;; and several subsets of commands available when you activate a
;; specific mode. Here we use the `lisp-interaction-mode', which
;; comes with commands to evaluate and navigate within Elisp code.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; Semi-colons start comments anywhere on a line.
;;
;; Elisp programs are made of symbolic expressions ("sexps"):
(+ 2 2)
147
(+ 3 (+ 1 2))
;; ^ cursor here
;; `C-j' => 6
;; Now let's call the function with the string "you" as the value
;; for its unique argument:
(hello "you")
;; `C-xC-e' => "Hello you"
;; Yeah!
;; Take a breath.
148
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; Now switch to a new buffer named "*test*" in another window:
(switch-to-buffer-other-window "*test*")
;; `C-xC-e'
;; => [screen has two windows and cursor is in the *test* buffer]
;; Mouse over the top window and left-click to go back. Or you can
;; use `C-xo' (i.e. hold down control-x and hit o) to go to the other
;; window interactively.
;; Now if you don't mind, I'll stop asking you to hit `C-xC-e': do it
;; for every sexp that follows.
149
(defun hello (name)
(insert (format "Hello %s!\n" name)))
(hello "you")
(greeting "Bastien")
;; Take a breath.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; Let's store a list of names:
(setq list-of-names '("Sarah" "Chloe" "Mathilde"))
150
;; Add an element to the beginning of a list with `push':
(push "Stephanie" list-of-names)
;; NOTE: `car' and `cdr' don't modify the list, but `push' does.
;; This is an important difference: some functions don't have any
;; side-effects (like `car') while others have (like `push').
(greeting)
(defun replace-hello-by-bonjour ()
(switch-to-buffer-other-window "*test*")
(goto-char (point-min))
(while (search-forward "Hello")
(replace-match "Bonjour"))
(other-window 1))
(replace-hello-by-bonjour)
151
;; We use this sexp in the function below, which doesn't throw an error:
(defun hello-to-bonjour ()
(switch-to-buffer-other-window "*test*")
(erase-buffer)
;; Say hello to names in `list-of-names'
(mapcar 'hello list-of-names)
(goto-char (point-min))
;; Replace "Hello" by "Bonjour"
(while (search-forward "Hello" nil 't)
(replace-match "Bonjour"))
(other-window 1))
(hello-to-bonjour)
(defun boldify-names ()
(switch-to-buffer-other-window "*test*")
(goto-char (point-min))
(while (re-search-forward "Bonjour \\(.+\\)!" nil 't)
(add-text-properties (match-beginning 1)
(match-end 1)
(list 'face 'bold)))
(other-window 1))
(boldify-names)
152
;; To read an online introduction to Emacs Lisp:
;; https://www.gnu.org/software/emacs/manual/html_node/eintr/index.html
Elixir
Elixir is a modern functional language built on top of the Erlang VM. It’s fully compatible with Erlang, but
features a more standard syntax and many more features.
## ---------------------------
## -- Basic types
## ---------------------------
# Atoms, that are literals, a constant with name. They start with `:`.
:hello # atom
153
# In elixir, just like in Erlang, the `=` denotes pattern matching and
# not an assignment.
#
# This means that the left-hand side (pattern) is matched against a
# right-hand side.
#
# This is how the above example of accessing the head and tail of a list works.
# A pattern match will error when the sides don't match, in this example
# the tuples have different sizes.
# {a, b, c} = {1, 2} #=> ** (MatchError) no match of right hand side value: {1,2}
# Multi-line strings
"""
I'm a multi-line
string.
"""
#=> "I'm a multi-line\nstring.\n"
# Strings are really just binaries, and char lists are just lists.
<<?a, ?b, ?c>> #=> "abc"
[?a, ?b, ?c] #=> 'abc'
# `?a` in elixir returns the ASCII integer for the letter `a`
?a #=> 97
154
genders = %{david: "male", gillian: "female"}
genders.gillian #=> "female"
## ---------------------------
## -- Operators
## ---------------------------
# Some math
1 + 1 #=> 2
10 - 5 #=> 5
5 * 2 #=> 10
10 / 2 #=> 5.0
# Elixir also provides `||`, `&&` and `!` which accept arguments of any type.
# All values except `false` and `nil` will evaluate to true.
1 || true #=> 1
false && 1 #=> false
nil && 20 #=> nil
!true #=> false
# For comparisons we have: `==`, `!=`, `===`, `!==`, `<=`, `>=`, `<` and `>`
1 == 1 #=> true
1 != 1 #=> false
1 < 2 #=> true
# `===` and `!==` are more strict when comparing integers and floats:
1 == 1.0 #=> true
1 === 1.0 #=> false
## ---------------------------
## -- Control Flow
155
## ---------------------------
# `if` expression
if false do
"This will never be seen"
else
"This will"
end
# It is common to set the last condition equal to `true`, which will always match.
cond do
1 + 1 == 3 ->
"I will never be seen"
2 * 5 == 12 ->
"Me neither"
156
true ->
"But I will (this is essentially an else)"
end
## ---------------------------
## -- Modules and Functions
## ---------------------------
f.(1, 3) #=> 4
f.(-1, 3) #=> -3
# You can group several functions into a module. Inside a module use `def`
# to define your functions.
defmodule Math do
def sum(a, b) do
a + b
end
def square(x) do
x * x
end
end
Math.sum(1, 2) #=> 3
157
Math.square(3) #=> 9
# To compile our simple Math module save it as `math.ex` and use `elixirc`
# in your terminal: elixirc math.ex
# Inside a module we can define functions with `def` and private functions with `defp`.
# A function defined with `def` is available to be invoked from other modules,
# a private function can only be invoked locally.
defmodule PrivateMath do
def sum(a, b) do
do_sum(a, b)
end
defp do_sum(a, b) do
a + b
end
end
PrivateMath.sum(1, 2) #=> 3
# PrivateMath.do_sum(1, 2) #=> ** (UndefinedFunctionError)
Recursion.sum_list([1,2,3], 0) #=> 6
# Elixir modules support attributes, there are built-in attributes and you
# may also add custom ones.
defmodule MyMod do
@moduledoc """
158
This is a built-in attribute on a example module.
"""
## ---------------------------
## -- Structs and Exceptions
## ---------------------------
# The `try` block with the `rescue` keyword is used to handle exceptions
try do
raise "some error"
rescue
RuntimeError -> "rescued a runtime error"
_error -> "this will rescue any error"
end
#=> "rescued a runtime error"
## ---------------------------
## -- Concurrency
## ---------------------------
# Elixir relies on the actor model for concurrency. All we need to write
# concurrent programs in elixir are three primitives: spawning processes,
# sending messages and receiving messages.
# To start a new process we use the `spawn` function, which takes a function
159
# as argument.
f = fn -> 2 * 2 end #=> #Function<erl_eval.20.80484245>
spawn(f) #=> #PID<0.40.0>
# `spawn` returns a pid (process identifier), you can use this pid to send
# messages to the process. To do message passing we use the `send` operator.
# For all of this to be useful we need to be able to receive messages. This is
# achieved with the `receive` mechanism:
# The `receive do` block is used to listen for messages and process
# them when they are received. A `receive do` block will only
# process one received message. In order to process multiple
# messages, a function with a `receive do` block must recursively
# call itself to get into the `receive do` block again.
defmodule Geometry do
def area_loop do
receive do
{:rectangle, w, h} ->
IO.puts("Area = #{w * h}")
area_loop()
{:circle, r} ->
IO.puts("Area = #{3.14 * r * r}")
area_loop()
end
end
end
# Compile the module and create a process that evaluates `area_loop` in the shell
pid = spawn(fn -> Geometry.area_loop() end) #=> #PID<0.40.0>
# Alternatively
pid = spawn(Geometry, :area_loop, [])
# Send a message to `pid` that will match a pattern in the receive statement
send pid, {:rectangle, 2, 3}
#=> Area = 6
# {:rectangle,2,3}
# The shell is also a process, you can use `self` to get the current pid
self() #=> #PID<0.27.0>
## ---------------------------
## -- Agents
## ---------------------------
160
# `Agent.get` takes an agent name and a `fn` that gets passed the current state
# Whatever that `fn` returns is what you'll get back
Agent.get(my_agent, fn colors -> colors end) #=> ["red, "green"]
References
• Getting started guide from the Elixir website
• Elixir Documentation
• “Programming Elixir” by Dave Thomas
• Elixir Cheat Sheet
• “Learn You Some Erlang for Great Good!” by Fred Hebert
• “Programming Erlang: Software for a Concurrent World” by Joe Armstrong
Elm
Elm is a functional reactive programming language that compiles to (client-side) JavaScript. Elm is statically
typed, meaning that the compiler catches most errors immediately and provides a clear and understandable
error message. Elm is great for designing user interfaces and games for the web.
-- Single line comments start with two dashes.
{- Multiline comments can be enclosed in a block like this.
{- They can be nested. -}
-}
-- Arithmetic
1 + 1 -- 2
8 - 1 -- 7
10 * 2 -- 20
-- Every number literal without a decimal point can be either an Int or a Float.
33 / 2 -- 16.5 with floating point division
33 // 2 -- 16 with integer division
-- Exponents
5 ^ 2 -- 25
-- Booleans
not True -- False
not False -- True
1 == 1 -- True
1 /= 1 -- False
1 < 10 -- True
161
-- Strings can be appended.
"Hello " ++ "world!" -- "Hello world!"
-- The head and tail of a list are returned as a Maybe. Instead of checking
-- every value to see if it's null, you deal with missing values explicitly.
List.head [1..5] -- Just 1
List.tail [1..5] -- Just [2, 3, 4, 5]
List.head [] -- Nothing
-- List.functionName means the function lives in the List module.
-- Access the elements of a pair with the first and second functions.
-- (This is a shortcut; we'll come to the "real way" in a bit.)
fst ("elm", 42) -- "elm"
snd ("elm", 42) -- 42
-- Records are like tuples but the fields have names. The order of fields
-- doesn't matter. Notice that record values use equals signs, not colons.
{ x = 3, y = 7 }
-- Or with an accessor function, which is a dot and the field name on its own.
.y { x = 3, y = 7 } -- 7
-- Update the fields of a record. (It must have the fields already.)
{ person |
name = "George" }
162
position = particle.position + particle.velocity,
velocity = particle.velocity + particle.acceleration }
-- If statements always have an else, and the branches must be the same type.
if powerLevel > 9000 then
"WHOA!"
else
"meh"
-- Define a function with its name, arguments, an equals sign, and the body.
multiply a b =
a * b
163
-- Pass functions as arguments to other functions.
List.map double [1..4] -- [2, 4, 6, 8]
-- You can pattern match in function definitions when there's only one case.
-- This function takes one tuple rather than two arguments.
-- This is the way you'll usually unpack/extract values from tuples.
area (width, height) =
width * height
area (6, 7) -- 42
-- Function calls happen before any infix operator. Parens indicate precedence.
cos (degrees 30) ^ 2 + sin (degrees 30) ^ 2 -- 1
-- First degrees is applied to 30, then the result is passed to the trig
-- functions, which is then squared, and the addition happens last.
-- The compiler will infer the type of every value in your program.
-- Types are always uppercase. Read x : T as "x has type T".
-- Some common types, which you might see in Elm's REPL.
5 : Int
6.7 : Float
"hello" : String
True : Bool
164
-- Functions have types too. Read -> as "goes to". Think of the rightmost type
-- as the type of the return value, and the others as arguments.
not : Bool -> Bool
round : Float -> Int
-- When you define a value, it's good practice to write its type above it.
-- The annotation is a form of documentation, which is verified by the compiler.
double : Int -> Int
double x = x * 2
-- There are three special lowercase types: number, comparable, and appendable.
-- Numbers allow you to use arithmetic on Ints and Floats.
-- Comparable allows you to order numbers and strings, like a < b.
-- Appendable things can be combined with a ++ b.
-- You can give existing types a nice name with a type alias.
type alias Point3D =
{ x : Float, y : Float, z : Float }
-- If you alias a record, you can use the name as a constructor function.
otherOrigin : Point3D
otherOrigin =
Point3D 0 0 0
-- But it's still the same type, so you can equate them.
origin == otherOrigin -- True
-- By contrast, defining a union type creates a type that didn't exist before.
-- A union type is so called because it can be one of many possibilities.
-- Each of the possibilities is represented as a "tag".
type Direction =
North | South | East | West
-- Tags can carry other values of known type. This can work recursively.
type IntTree =
Leaf | Node Int IntTree IntTree
-- "Leaf" and "Node" are the tags. Everything following a tag is a type.
165
root =
Node 7 Leaf Leaf
-- Pattern match union tags. The uppercase tags will be matched exactly. The
-- lowercase variables will match anything. Underscore also matches anything,
-- but signifies that you aren't using it.
leftmostElement : Tree a -> Maybe a
leftmostElement tree =
case tree of
Leaf -> Nothing
Node x Leaf _ -> Just x
Node _ subtree _ -> leftmostElement subtree
-- That's pretty much it for the language itself. Now let's see how to organize
-- and run your code.
-- The core libraries are organized into modules, as are any third-party
-- libraries you may use. For large projects, you can define your own modules.
-- One common pattern is to export a union type but not its tags. This is known
-- as an "opaque type", and is frequently used in libraries.
-- Imports the Dict module and the Dict type, so your annotations don't have to
-- say Dict.Dict. You can still use Dict.insert.
import Dict exposing (Dict)
-- Rename an import.
import Graphics.Collage as C
-- A port indicates that you will be communicating with the outside world.
-- Ports are only allowed in the Main module.
166
-- An outgoing port has a definition.
port clientOrders : List String
port clientOrders = ["Books", "Groceries", "Furniture"]
-- We won't go into the details, but you set up callbacks in JavaScript to send
-- on incoming ports and receive on outgoing ports.
-- Compile a file.
$ elm make MyFile.elm
-- The first time you do this, Elm will install the core libraries and create
-- elm-package.json, where information about your project is kept.
167
Go out and write some Elm!
Erlang
% Percent sign starts a one-line comment.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% 1. Variables and pattern matching.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Floating-point number.
Pi = 3.14159.
% Atoms with non alphanumeric values can be written by enclosing the atoms
% with apostrophes.
AtomWithSpace = 'some atom with space'.
168
% If we want to extract some values from a tuple, we use the pattern-matching
% operator `=`.
{point, X, Y} = Point. % X = 10, Y = 45
% We can use `_` as a placeholder for variables that we’re not interested in.
% The symbol `_` is called an anonymous variable. Unlike regular variables,
% several occurrences of `_` in the same pattern don’t have to bind to the
% same value.
Person = {person, {name, {first, joe}, {last, armstrong}}, {footsize, 42}}.
{_, {_, {_, Who}, _}, _} = Person. % Who = joe
% If `T` is a list, then `[H|T]` is also a list, with head `H` and tail `T`.
% The vertical bar (`|`) separates the head of a list from its tail.
% `[]` is the empty list.
% We can extract elements from a list with a pattern-matching operation. If we
% have a nonempty list `L`, then the expression `[X|Y] = L`, where `X` and `Y`
% are unbound variables, will extract the head of the list into `X` and the tail
% of the list into `Y`.
[FirstThing|OtherThingsToBuy] = ThingsToBuy.
% FirstThing = {apples, 10}
% OtherThingsToBuy = [{pears, 6}, {milk, 3}]
% There are no strings in Erlang. Strings are really just lists of integers.
% Strings are enclosed in double quotation marks (`"`).
Name = "Hello".
[72, 101, 108, 108, 111] = "Hello".
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% 2. Sequential programming.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Modules are the basic unit of code in Erlang. All the functions we write are
% stored in modules. Modules are stored in files with `.erl` extensions.
% Modules must be compiled before the code can be run. A compiled module has the
% extension `.beam`.
-module(geometry).
-export([area/1]). % the list of functions exported from the module.
% The function `area` consists of two clauses. The clauses are separated by a
% semicolon, and the final clause is terminated by dot-whitespace.
% Each clause has a head and a body; the head consists of a function name
% followed by a pattern (in parentheses), and the body consists of a sequence of
% expressions, which are evaluated if the pattern in the head is successfully
% matched against the calling arguments. The patterns are matched in the order
% they appear in the function definition.
169
area({rectangle, Width, Ht}) -> Width * Ht;
area({circle, R}) -> 3.14159 * R * R.
% We need to include the module name together with the function name in order to
% identify exactly which function we want to call.
geometry:area({rectangle, 10, 5}). % 50
geometry:area({circle, 1.4}). % 6.15752
% In Erlang, two functions with the same name and different arity (number of
% arguments) in the same module represent entirely different functions.
-module(lib_misc).
-export([sum/1]). % export function `sum` of arity 1
% accepting one argument: list of integers.
sum(L) -> sum(L, 0).
sum([], N) -> N;
sum([H|T], N) -> sum(T, H+N).
% Funs are "anonymous" functions. They are called this way because they have
% no name. However, they can be assigned to variables.
Double = fun(X) -> 2 * X end. % `Double` points to an anonymous function
% with handle: #Fun<erl_eval.6.17052888>
Double(2). % 4
% List comprehensions are expressions that create lists without having to use
% funs, maps, or filters.
% The notation `[F(X) || X <- L]` means "the list of `F(X)` where `X` is taken
% from the list `L`."
L = [1,2,3,4,5].
[2 * X || X <- L]. % [2,4,6,8,10]
% A list comprehension can have generators and filters, which select subset of
% the generated values.
EvenNumbers = [N || N <- [1, 2, 3, 4], N rem 2 == 0]. % [2, 4]
% Guards are constructs that we can use to increase the power of pattern
% matching. Using guards, we can perform simple tests and comparisons on the
% variables in a pattern.
% You can use guards in the heads of function definitions where they are
% introduced by the `when` keyword, or you can use them at any place in the
% language where an expression is allowed.
max(X, Y) when X > Y -> X;
max(X, Y) -> Y.
170
is_cat(A) -> false.
is_dog(A) when is_atom(A), A =:= dog -> true;
is_dog(A) -> false.
% We won't dwell on the `=:=` operator here; just be aware that it is used to
% check whether two Erlang expressions have the same value *and* the same type.
% Contrast this behaviour to that of the `==` operator:
1 + 2 =:= 3. % true
1 + 2 =:= 3.0. % false
1 + 2 == 3.0. % true
% Warning: not all valid Erlang expressions can be used as guard expressions;
% in particular, our `is_cat` and `is_dog` functions cannot be used within the
% guard sequence in `is_pet`'s definition. For a description of the
% expressions allowed in guard sequences, refer to this
% [section](http://erlang.org/doc/reference_manual/expressions.html#id81912)
% of the Erlang reference manual.
% We have to read the record definitions into the shell before we can define a
% record. We use the shell function `rr` (short for read records) to do this.
rr("records.hrl"). % [todo]
% `case` expressions.
% `filter` returns a list of all elements `X` in a list `L` for which `P(X)` is
% true.
filter(P, [H|T]) ->
case P(H) of
true -> [H|filter(P, T)];
false -> filter(P, T)
171
end;
filter(P, []) -> [].
filter(fun(X) -> X rem 2 == 0 end, [1, 2, 3, 4]). % [2, 4]
% `if` expressions.
max(X, Y) ->
if
X > Y -> X;
X < Y -> Y;
true -> nil
end.
% Warning: at least one of the guards in the `if` expression must evaluate to
% `true`; otherwise, an exception will be raised.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% 3. Exceptions.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Exceptions are raised by the system when internal errors are encountered or
% explicitly in code by calling `throw(Exception)`, `exit(Exception)`, or
% `erlang:error(Exception)`.
generate_exception(1) -> a;
generate_exception(2) -> throw(a);
generate_exception(3) -> exit(a);
generate_exception(4) -> {'EXIT', a};
generate_exception(5) -> erlang:error(a).
% Erlang has two methods of catching an exception. One is to enclose the call to
% the function that raises the exception within a `try...catch` expression.
catcher(N) ->
try generate_exception(N) of
Val -> {N, normal, Val}
catch
throw:X -> {N, caught, thrown, X};
exit:X -> {N, caught, exited, X};
error:X -> {N, caught, error, X}
end.
% The other is to enclose the call in a `catch` expression. When you catch an
% exception, it is converted into a tuple that describes the error.
catcher(N) -> catch generate_exception(N).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% 4. Concurrency
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Erlang relies on the actor model for concurrency. All we need to write
% concurrent programs in Erlang are three primitives: spawning processes,
% sending messages and receiving messages.
% To start a new process, we use the `spawn` function, which takes a function
172
% as argument.
% `spawn` returns a pid (process identifier); you can use this pid to send
% messages to the process. To do message passing, we use the `!` operator.
% For all of this to be useful, we need to be able to receive messages. This is
% achieved with the `receive` mechanism:
-module(calculateGeometry).
-compile(export_all).
calculateArea() ->
receive
{rectangle, W, H} ->
W * H;
{circle, R} ->
3.14 * R * R;
_ ->
io:format("We can only calculate area of rectangles or circles.")
end.
% Compile the module and create a process that evaluates `calculateArea` in the
% shell.
c(calculateGeometry).
CalculateArea = spawn(calculateGeometry, calculateArea, []).
CalculateArea ! {circle, 2}. % 12.56000000000000049738
% The shell is also a process; you can use `self` to get the current pid.
self(). % <0.41.0>
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% 5. Testing with EUnit
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Unit tests can be written using EUnits's test generators and assert macros
-module(fib).
-export([fib/1]).
-include_lib("eunit/include/eunit.hrl").
fib(0) -> 1;
fib(1) -> 1;
fib(N) when N > 1 -> fib(N-1) + fib(N-2).
fib_test_() ->
[?_assert(fib(0) =:= 1),
?_assert(fib(1) =:= 1),
?_assert(fib(2) =:= 2),
?_assert(fib(3) =:= 3),
?_assert(fib(4) =:= 5),
?_assert(fib(5) =:= 8),
?_assertException(error, function_clause, fib(-1)),
?_assert(fib(31) =:= 2178309)
].
173
% EUnit will automatically export to a test() function to allow running the tests
% in the erlang shell
fib:test()
% The popular erlang build tool Rebar is also compatible with EUnit
% ```
% rebar eunit
% ```
References
• “Learn You Some Erlang for great good!”
• “Programming Erlang: Software for a Concurrent World” by Joe Armstrong
• Erlang/OTP Reference Documentation
• Erlang - Programming Rules and Conventions
Factor
Factor is a modern stack-based language, based on Forth, created by Slava Pestov.
Code in this file can be typed into Factor, but not directly imported because the vocabulary and import
header would make the beginning thoroughly confusing.
! This is a comment
! `.` pops the top result from the stack and prints it.
. ! 9
99 neg . ! -99
-99 abs . ! 99
52 23 max . ! 52
52 23 min . ! 23
! A number of words are provided to manipulate the stack, collectively known as shuffle words.
174
3 dup - ! duplicate the top item (1st now equals 2nd): 3 - 3
2 5 swap / ! swap the top with the second element: 5 / 2
4 0 drop 2 / ! remove the top item (don't print to screen): 4 / 2
1 2 3 nip .s ! remove the second item (similar to drop): 1 3
1 2 clear .s ! wipe out the entire stack
1 2 3 4 over .s ! duplicate the second item to the top: 1 2 3 4 3
1 2 3 4 2 pick .s ! duplicate the third item to the top: 1 2 3 4 2 3
! Creating Words
! The `:` word sets Factor into compile mode until it sees the `;` word.
: square ( n -- n ) dup * ; ! No output
5 square . ! 25
! After the name of the word to create, the declaration between brackets gives the stack effect.
! We can use whatever names we like inside the declaration:
: weirdsquare ( camel -- llama ) dup * ;
! Conditionals
! Any value is true except the built-in value f.
! A built-in value t does exist, but its use isn't essential.
! Conditionals are higher order words as with the combinators above.
! By default the conditionals consume the value under test, but starred variants
! leave it alone if it's true:
175
5 [ . ] when* ! 5
f [ . ] when* ! No output, empty stack, f is consumed because it's false
! Loops
! You've guessed it.. these are higher order words too.
5 [ . ] each-integer ! 0 1 2 3 4
4 3 2 1 0 5 [ + . ] each-integer ! 0 2 4 6 8
5 [ "Hello" . ] times ! Hello Hello Hello Hello Hello
! Here's a list:
{ 2 4 6 8 } ! Goes on the stack as one item
! Variables
! Usually Factor programs are expected to keep all data on the stack.
! Using named variables makes refactoring harder (and it's called Factor for a reason)
! Global variables, if you must:
! Or in a word..
:: lword ( -- ) ! Note double colon to invoke lexical variable extension
2 :> c ! Declares immutable variable c to hold 2
c . ; ! Print it out
! In a word declared this way, the input side of the stack declaration
! becomes meaningful and gives the variable names stack values are captured into
:: double ( a -- result ) a 2 * ;
176
:: mword2 ( a! -- x y ) ! Capture top of stack in mutable variable a
a ! Push a
a 2 * a! ! Multiply a by 2 and store result back in a
a ; ! Push new value of a
5 mword2 ! Stack: 5 10
! And if you want to get meta, quotations are sequences and can be dismantled..
0 [ 2 + ] nth ! 2
1 [ 2 + ] nth ! +
[ 2 + ] \ - suffix ! Quotation [ 2 + - ]
Forth
Forth was created by Charles H. Moore in the 70s. It is an imperative, stack-based language and programming
environment, being used in projects such as Open Firmware. It’s also used by NASA.
Note: This article focuses predominantly on the Gforth implementation of Forth, but most of what is written
here should work elsewhere.
\ This is a comment
( This is also a comment but it's only used when defining words )
177
\ ------------------------------ Basic Arithmetic ------------------------------
\ Arithmetic (in fact most words requiring data) works by manipulating data on
\ the stack.
5 4 + \ ok
99 negate . \ -99 ok
-99 abs . \ 99 ok
52 23 max . \ 52 ok
52 23 min . \ 23 ok
\ Naturally, as we work with the stack, we'll want some useful methods:
\ The `:` word sets Forth into compile mode until it sees the `;` word.
: square ( n -- n ) dup * ; \ ok
5 square . \ 25 ok
178
12 53 = \ 0 ok
\ Else:
: ?>64 ( n -- n ) dup 64 > if ." Greater than 64!" else ." Less than 64!" then ;
100 ?>64 \ Greater than 64! ok
20 ?>64 \ Less than 64! ok
\ `do` expects two numbers on the stack: the end number and the start number.
\ `?do` works similarly, except it will skip the loop if the end and start
\ numbers are equal.
: squares ( n -- ) 0 ?do i square . loop ; \ ok
10 squares \ 0 1 4 9 16 25 36 49 64 81 ok
\ Finally we can print our variable using the "read" word `@`, which adds the
\ value to the stack, or use `?` that reads and prints it in one go.
age @ . \ 21 ok
age ? \ 21 ok
\ Constants are quite similar, except we don't bother with memory addresses:
179
100 constant WATER-BOILING-POINT \ ok
WATER-BOILING-POINT . \ 100 ok
\ You can use `2 cells allot` to create an array that's 3 cells long:
variable mynumbers 2 cells allot \ ok
\ or we can just skip all the above and initialize with specific values:
create mynumbers 64 , 9001 , 1337 , \ ok (the last `,` is important!)
\ The return stack is used to the hold pointers to things when words are
\ executing other words, e.g. loops.
\ We've already seen one use of it: `i`, which duplicates the top of the return
\ stack. `i` is equivalent to `r@`.
: myloop ( -- ) 5 0 do r@ . loop ; \ ok
\ As well as reading, we can add to the return stack and remove from it:
5 6 4 >r swap r> .s \ 6 5 4 ok
\ NOTE: Because Forth uses the return stack for word pointers, `>r` should
\ always be followed by `r>`.
180
\ ------------------------- Floating Point Operations --------------------------
\ Usually we simply prepend words with 'f' when dealing with floats:
variable myfloatingvar \ ok
4.4e myfloatingvar f! \ ok
myfloatingvar f@ f. \ 4.4 ok
\ Typing a non-existent word will empty the stack. However, there's also a word
\ specifically for that:
clearstack
\ You can list every word that's in Forth's dictionary (but it's a huge list!):
\ words
\ Exiting Gforth:
\ bye
Fortran95
Fortran is one of the oldest computer languages. It was developed in the 1950s by IBM for numeric cal-
culations (Fortran is an abreviation of “Formula Translation”). Despite its age, it is still used for high-
performance computing such as weather prediction. However, the language has changed considerably over
the years, although mostly maintaining backwards compatibility; well known versions are FORTRAN 77,
Fortran 90, Fortran 95, Fortran 2003, Fortran 2008 and Fortran 2015.
This overview will discuss the features of Fortran 95 since it is the most widely implemented of the more
recent specifications and the later versions are largely similar (by comparison FORTRAN 77 is a very different
language).
! This is a comment.
181
! Using indentation is not required but it is recommended.
! Declaring Variables
! ===================
! The '::' separators are not always necessary but are recommended.
! Strings
! =======
182
! Assignment & Arithmetic
! =======================
! Single-line if statement
if (z == a) b = 4 !condition always need surrounding parentheses.
i = 20
select case (i)
case (0) !case i == 0
j=0
case (1:10) !cases i is 1 to 10 inclusive.
j=1
case (11:) !all cases where i>=11
j=2
case default
j=3
end select
month = 'jan'
! Condition can be integer, logical or character type.
! Select constructions can also be named.
monthly: select case (month)
case ("jan")
j = 0
183
case default
j = -1
end select monthly
! Arrays
! ======
array = (/1,2,3,4,5,6/)
array = [1,2,3,4,5,6] !using Fortran 2003 notation.
arrayb = [10.2,3e3,0.41,4e-5]
array2d = reshape([1.0,2.0,3.0,4.0,5.0,6.0], [3,2])
184
! Conditionally execute element-wise assignments.
array = [1,2,3,4,5,6]
where (array > 3)
array = array + 1
elsewhere (array == 2)
array = 1
elsewhere
array = 0
end where
! Input/Output
! ============
! The letter indicates the expected type and the number afterwards gives
! the number of characters to use for printing the value.
! Letters can be I (integer), F (real), E (engineering format),
! L (logical), A (characters) ...
print "(I3)", 3200 !print '***' since the number doesn't fit.
! To read a file.
open(unit=11, file="records.txt", status="old")
! The file is referred to by a 'unit number', an integer that you pick in
! the range 9:99. Status can be one of {'old','replace','new'}.
read(unit=11, fmt="(3F10.2)") a, b, c
close(11)
! To write a file.
open(unit=12, file="records.txt", status="replace")
write(12, "(F10.2,F10.2,F10.2)") c, b, a
close(12)
185
! There are more features available than discussed here and alternative
! variants due to backwards compatability with older Fortran versions.
! Built-in Functions
! ==================
! A subroutine runs some code on some input values and can cause
! side-effects or modify the input values.
186
function func2(a,b,c) result(f) !return variable declared to be 'f'.
implicit none
integer, intent(in) :: a,b !can declare and enforce that variables
!are not modified by the function.
integer, intent(inout) :: c
integer :: f !function return type declared inside the function.
integer :: cnt = 0 !GOTCHA - initialisation implies variable is
!saved between function calls.
f = a + b - c
c = 4 !altering the value of an input variable.
cnt = cnt + 1 !count number of function calls.
end function func2
subroutine routine(d,e,f)
implicit none
real, intent(inout) :: f
real, intent(in) :: d,e
f = 2*d + 3*e + f
end subroutine routine
! Modules
! =======
module fruit
187
real :: apple
real :: pear
real :: orange
end module fruit
module fruity
! Declarations must be in the order: modules, interfaces, variables.
! (can declare modules and interfaces in programs too).
use fruit, only: apple, pear ! use apple and pear from fruit module.
implicit none !comes after module imports.
! Interfaces
! ==========
! Explicitly declare an external function/procedure within the module
! (better in general to put functions/procedures in the 'contains' section).
interface
elemental real function func4(a) result(res)
real, intent(in) :: a
end function func4
end interface
contains
subroutine create_mycar(mycar)
188
! Demonstrates usage of a derived data type.
implicit none
type(car),intent(out) :: mycar
end subroutine
More Resources
Fsharp
F# is a general purpose functional/OO programming language. It’s free and open source, and runs on Linux,
Mac, Windows and more.
It has a powerful type system that traps many errors at compile time, but it uses type inference so that it
reads more like a dynamic language.
189
The syntax of F# is different from C-style languages:
• Curly braces are not used to delimit blocks of code. Instead, indentation is used (like Python).
• Whitespace is used to separate parameters rather than commas.
If you want to try out the code below, you can go to tryfsharp.org and paste it into an interactive REPL.
// ================================================
// Basic Syntax
// ================================================
190
// You can pipe the output of one operation to the next using "|>"
// Piping data around is very common in F#, similar to UNIX pipes.
// you can define lambdas (anonymous functions) using the "fun" keyword
let sumOfSquaresTo100withFun =
[1..100] |> List.map (fun x -> x * x) |> List.sum
optionPatternMatch validValue
optionPatternMatch invalidValue
// ================================================
// More on functions
// ================================================
191
// constructs
// ================================================
// Lists and collection
// ================================================
module ListExamples =
192
// A prime number generator
// - this is using a short notation for the pattern matching syntax
// - (p::xs) is 'first :: tail' of the list, could also be written as p :: xs
// this means this matches 'p' (the first item in the list), and xs is the rest of the list
// this is called the 'cons pattern'
// - uses 'rec' keyword, which is necessary when using recursion
let rec sieve = function
| (p::xs) -> p :: sieve [ for x in xs do if x % p > 0 then yield x ]
| [] -> []
let primes = sieve [2..50]
printfn "%A" primes
listMatcher [1; 2; 3; 4]
listMatcher [1; 2]
listMatcher [1]
listMatcher []
// -----------------------------------------
// Standard library functions
// -----------------------------------------
// map
let add3 x = x + 3
[1..10] |> List.map add3
// filter
let even x = x % 2 = 0
[1..10] |> List.filter even
module ArrayExamples =
193
let arrayMatcher aList =
match aList with
| [| |] -> printfn "the array is empty"
| [| first |] -> printfn "the array has one element %A " first
| [| first; second |] -> printfn "array is %A and %A" first second
| _ -> printfn "the array has more than two elements"
arrayMatcher [| 1; 2; 3; 4 |]
[| 1..10 |]
|> Array.map (fun i -> i + 3)
|> Array.filter (fun i -> i % 2 = 0)
|> Array.iter (printfn "value is %i. ")
module SequenceExamples =
// test
let fib10 = fib |> Seq.take 10 |> Seq.toList
printf "first 10 fibs are %A" fib10
// ================================================
// Data Types
// ================================================
module DataTypeExamples =
194
// Tuples are quick 'n easy anonymous types
// -- Use a comma to create a tuple
let twoTuple = 1, 2
let threeTuple = "a", 2, true
// ------------------------------------
// Record types have named fields
// ------------------------------------
// ------------------------------------
// Union types (aka variants) have a set of choices
// Only case can be valid at a time.
// ------------------------------------
printTemp temp1
printTemp temp2
// ------------------------------------
// Recursive types
// ------------------------------------
195
let jdoe = {First="John"; Last="Doe"}
let worker = Worker jdoe
// ------------------------------------
// Modeling with types
// ------------------------------------
// Union types are great for modeling state without using flags
type EmailAddress =
| ValidEmailAddress of string
| InvalidEmailAddress of string
type ShoppingCart =
| EmptyCart // no data
| ActiveCart of ActiveCartData
| PaidCart of PaidCartData
// ------------------------------------
// Built in behavior for types
// ------------------------------------
196
// sorting
List.sort hand |> printfn "sorted hand is (low to high) %A"
List.max hand |> printfn "high card is %A"
List.min hand |> printfn "low card is %A"
// ================================================
// Active patterns
// ================================================
module ActivePatternExamples =
// print a list
['a'; 'b'; '1'; ' '; '-'; 'c'] |> List.iter printChar
// -----------------------------------
// FizzBuzz using active patterns
// -----------------------------------
// test
197
[1..20] |> List.iter fizzBuzz
// ================================================
// Conciseness
// ================================================
module AlgorithmExamples =
// test
sumOfSquares 100 |> printfn "Sum of squares = %A"
// test
sort [1; 5; 23; 18; 9; 1; 3] |> printfn "Sorted = %A"
// ================================================
// Asynchronous Code
// ================================================
module AsyncExample =
open System.Net
198
open System
open System.IO
open Microsoft.FSharp.Control.CommonExtensions
// do it
sites
|> List.map fetchUrlAsync // make a list of async tasks
|> Async.Parallel // set up the tasks to run in parallel
|> Async.RunSynchronously // start them off
// ================================================
// .NET compatibility
// ================================================
module NetCompatibilityExamples =
let useAndDisposeResources =
199
use r1 = makeResource "first resource"
printfn "using first resource"
for i in [1..3] do
let resourceName = sprintf "\tinner resource %d" i
use temp = makeResource resourceName
printfn "\tdo something with %s" resourceName
use r2 = makeResource "second resource"
printfn "using second resource"
printfn "done."
// test
let r = Rectangle(2, 3)
printfn "The width is %i" r.Width
printfn "The area is %i" r.BoundingArea
r.Print()
// test
let s = "Alice"
printfn "'%s' starts with an 'A' = %A" s s.StartsWithA
200
// ------- events -------
type MyButton() =
let clickEvent = new Event<_>()
[<CLIEvent>]
member this.OnClick = clickEvent.Publish
member this.TestEvent(arg) =
clickEvent.Trigger(this, arg)
// test
let myButton = new MyButton()
myButton.OnClick.Add(fun (sender, arg) ->
printfn "Click event with arg=%O" arg)
myButton.TestEvent("Hello World!")
More Information
For more demonstrations of F#, go to the Try F# site, or my why use F# series.
Read more about F# at fsharp.org.
Git
Git is a distributed version control and source code management system.
It does this through a series of snapshots of your project, and it works with those snapshots to provide you
with functionality to version and manage your source code.
Versioning Concepts
What is version control?
201
• Branching is fast!
• Merging is easy!
• Git is fast.
• Git is flexible.
Git Architecture
Repository
A set of files, directories, historical records, commits, and heads. Imagine it as a source code data structure,
with the attribute that each source code “element” gives you access to its revision history, among other
things.
A git repository is comprised of the .git directory & working tree.
The .git directory contains all the configurations, logs, branches, HEAD, and more. Detailed List.
This is basically the directories and files in your repository. It is often referred to as your working directory.
The Index is the staging area in git. It’s basically a layer that separates your working tree from the Git
repository. This gives developers more power over what gets sent to the Git repository.
Commit
A git commit is a snapshot of a set of changes, or manipulations to your Working Tree. For example, if you
added 5 files, and removed 2 others, these changes will be contained in a commit (or snapshot). This commit
can then be pushed to other repositories, or not!
Branch
A branch is essentially a pointer to the last commit you made. As you go on committing, this pointer will
automatically update to point the latest commit.
Tag
A tag is a mark on specific point in history. Typically people use this functionality to mark release points
(v1.0, and so on)
HEAD is a pointer that points to the current branch. A repository only has 1 active HEAD.
head is a pointer that points to any commit. A repository can have any number of heads.
202
Stages of Git
• Modified - Changes have been made to a file but file has not been committed to Git Database yet
• Staged - Marks a modified file to go into your next commit snapshot
• Committed - Files have been committed to the Git Database
Conceptual Resources
Commands
init
Create an empty Git repository. The Git repository’s settings, stored information, and more is stored in a
directory (a folder) named “.git”.
$ git init
config
To configure settings. Whether it be for the repository, the system itself, or global configurations ( global
config file is ~/.gitconfig ).
# Print & Set Some Basic Config Variables (Global)
$ git config --global user.email "[email protected]"
$ git config --global user.name "My Name"
Learn More About git config.
help
To give you quick access to an extremely detailed guide of each command. Or to just give you a quick
reminder of some semantics.
# Quickly check available commands
$ git help
203
ignore files
To intentionally untrack file(s) & folder(s) from git. Typically meant for private & temp files which would
otherwise be shared in the repository.
$ echo "temp/" >> .gitignore
$ echo "private_key" >> .gitignore
status
To show differences between the index file (basically your working copy/repo) and the current HEAD commit.
# Will display the branch, untracked files, changes and other differences
$ git status
add
To add files to the staging area/index. If you do not git add new files to the staging area/index, they will
not be included in commits!
# add a file in your current working directory
$ git add HelloWorld.java
branch
Manage your branches. You can view, edit, create, delete branches using this command.
# list existing branches & remotes
$ git branch -a
# delete a branch
$ git branch -d myBranch
# rename a branch
# git branch -m <oldname> <newname>
$ git branch -m myBranchName myNewBranchName
204
tag
checkout
Updates all files in the working tree to match the version in the index, or specified tree.
# Checkout a repo - defaults to master branch
$ git checkout
clone
Clones, or copies, an existing repository into a new directory. It also adds remote-tracking branches for each
branch in the cloned repo, which allows you to push to a remote branch.
# Clone learnxinyminutes-docs
$ git clone https://github.com/adambard/learnxinyminutes-docs.git
205
commit
Stores the current contents of the index in a new “commit.” This commit contains the changes made and a
message created by the user.
# commit with a message
$ git commit -m "Added multiplyNumbers() function to HelloWorld.c"
# automatically stage modified or deleted files, except new files, and then commit
$ git commit -a -m "Modified foo.php and removed bar.php"
# change last commit (this deletes previous commit with a fresh commit)
$ git commit --amend -m "Correct message"
diff
Shows differences between a file in the working directory, index and commits.
# Show difference between your working dir and the index
$ git diff
# Show differences between the index and the most recent commit.
$ git diff --cached
# Show differences between your working dir and the most recent commit
$ git diff HEAD
grep
log
206
$ git log --oneline
merge
mv
# Moving a file
$ git mv HelloWorld.c ./new/path/HelloWorld.c
pull
push
207
# Push and merge changes from a local repo to a
# remote named "origin" and "master" branch.
# git push <remote> <branch>
$ git push origin master
stash
Stashing takes the dirty state of your working directory and saves it on a stack of unfinished changes that
you can reapply at any time.
Let’s say you’ve been doing some work in your git repo, but you want to pull from the remote. Since you
have dirty (uncommited) changes to some files, you are not able to run git pull. Instead, you can run git
stash to save your changes onto a stack!
$ git stash
Saved working directory and index state \
"WIP on master: 049d078 added the index file"
HEAD is now at 049d078 added the index file
(To restore them type "git stash apply")
Now you can pull!
git pull
...changes apply...
Now check that everything is OK
$ git status
# On branch master
nothing to commit, working directory clean
You can see what “hunks” you’ve stashed so far using git stash list. Since the “hunks” are stored in a
Last-In-First-Out stack, our most recent change will be at top.
$ git stash list
stash@{0}: WIP on master: 049d078 added the index file
stash@{1}: WIP on master: c264051 Revert "added file_size"
stash@{2}: WIP on master: 21d80a5 added number to log
Now let’s apply our dirty changes back by popping them off the stack.
$ git stash pop
# On branch master
# Changes not staged for commit:
# (use "git add <file>..." to update what will be committed)
#
# modified: index.html
# modified: lib/simplegit.rb
#
208
git stash apply does the same thing
Now you’re ready to get back to work on your stuff!
Additional Reading.
rebase (caution)
Take all changes that were committed on one branch, and replay them onto another branch. Do not rebase
commits that you have pushed to a public repo.
# Rebase experimentBranch onto master
# git rebase <basebranch> <topicbranch>
$ git rebase master experimentBranch
Additional Reading.
reset (caution)
Reset the current HEAD to the specified state. This allows you to undo merges, pulls, commits, adds, and
more. It’s a great command but also dangerous if you don’t know what you are doing.
# Reset the staging area, to match the latest commit (leaves dir unchanged)
$ git reset
# Reset the staging area, to match the latest commit, and overwrite working dir
$ git reset --hard
# Moves the current branch tip to the specified commit (leaves dir unchanged)
# all changes still exist in the directory.
$ git reset 31f2bb1
reflog (caution)
Reflog will list most of the git commands you have done for a given time period, default 90 days.
This give you the a change to reverse any git commands that have gone wrong for instance if a rebase is has
broken your application.
You can do this:
1. git reflog to list all of the git commands for the rebase
38b323f HEAD@{0}: rebase -i (finish): returning to refs/heads/feature/add_git_reflog
38b323f HEAD@{1}: rebase -i (pick): Clarify inc/dec operators
4fff859 HEAD@{2}: rebase -i (pick): Update java.html.markdown
34ed963 HEAD@{3}: rebase -i (pick): [yaml/en] Add more resources (#1666)
ed8ddf2 HEAD@{4}: rebase -i (pick): pythonstatcomp spanish translation (#1748)
2e6c386 HEAD@{5}: rebase -i (start): checkout 02fb96d
2. Select where to reset to, in our case its 2e6c386, or HEAD@{5}
3. ‘git reset –hard HEAD@{5}’ this will reset your repo to that head
209
4. You can start the rebase again or leave it alone.
Additional Reading.
revert
Revert can be used to undo a commit. It should not be confused with reset which restores the state of a
project to a previous point. Revert will add a new commit which is the inverse of the specified commit, thus
reverting it.
# Revert a specified commit
$ git revert <commit>
rm
The opposite of git add, git rm removes files from the current working tree.
# remove HelloWorld.c
$ git rm HelloWorld.c
Further Information
• tryGit - A fun interactive way to learn Git.
• Udemy Git Tutorial: A Comprehensive Guide
• Git Immersion - A Guided tour that walks through the fundamentals of git
• git-scm - Video Tutorials
• git-scm - Documentation
• Atlassian Git - Tutorials & Workflows
• SalesForce Cheat Sheet
• GitGuys
• Git - the simple guide
• Pro Git
• An introduction to Git and GitHub for Beginners (Tutorial)
Go
Go was created out of the need to get work done. It’s not the latest trend in computer science, but it is the
newest fastest way to solve real-world problems.
It has familiar concepts of imperative languages with static typing. It’s fast to compile and fast to execute,
it adds easy-to-understand concurrency to leverage today’s multi-core CPUs, and has features to help with
large-scale programming.
Go comes with a great standard library and an enthusiastic community.
210
// Single line comment
/* Multi-
line comment */
211
s2 := `A "raw" string literal
can include line breaks.` // Same string type.
// Slices have dynamic size. Arrays and slices each have advantages
// but use cases for slices are much more common.
s3 := []int{4, 5, 9} // Compare to a3. No ellipsis here.
s4 := make([]int, 4) // Allocates slice of 4 ints, initialized to all 0.
var d2 [][]float64 // Declaration only, nothing allocated here.
bs := []byte("a slice") // Type conversion syntax.
212
// Output of course counts as using a variable.
fmt.Println(s, c, a4, s3, d2, m)
func learnFlowControl() {
// If statements require brace brackets, and do not require parentheses.
if true {
fmt.Println("told ya")
}
// Formatting is standardized by the command line command "go fmt."
if false {
// Pout.
} else {
// Gloat.
}
// Use switch in preference to chained if statements.
x := 42.0
switch x {
case 0:
case 1:
case 42:
// Cases don't "fall through".
/*
There is a `fallthrough` keyword however, see:
https://github.com/golang/go/wiki/Switch#fall-through
*/
213
case 43:
// Unreached.
default:
// Default case is optional.
}
// Like if, for doesn't use parens either.
// Variables declared in for and if are local to their scope.
for x := 0; x < 3; x++ { // ++ is a statement.
fmt.Println("iteration", x)
}
// x == 42 here.
// For is the only loop statement in Go, but it has alternate forms.
for { // Infinite loop.
break // Just kidding.
continue // Unreached.
}
// You can use range to iterate over an array, a slice, a string, a map, or a channel.
// range returns one (channel) or two values (array, slice, string and map).
for key, value := range map[string]int{"one": 1, "two": 2, "three": 3} {
// for each pair in the map, print key and value
fmt.Printf("key=%s, value=%d\n", key, value)
}
214
learnDefer() // A quick detour to an important keyword.
learnInterfaces() // Good stuff coming up!
}
func learnFunctionFactory() {
// Next two are equivalent, with second being more practical
fmt.Println(sentenceFactory("summer")("A beautiful", "day!"))
d := sentenceFactory("summer")
fmt.Println(d("A beautiful", "day!"))
fmt.Println(d("A lazy", "afternoon!"))
}
func learnInterfaces() {
// Brace syntax is a "struct literal". It evaluates to an initialized
// struct. The := syntax declares and initializes p to this struct.
p := pair{3, 4}
fmt.Println(p.String()) // Call String method of p, of type pair.
var i Stringer // Declare i of interface type Stringer.
i = p // Valid because pair implements Stringer
215
// Call String method of i, of type Stringer. Output same as above.
fmt.Println(i.String())
// Functions in the fmt package call the String method to ask an object
// for a printable representation of itself.
fmt.Println(p) // Output same as above. Println calls String method.
fmt.Println(i) // Output same as above.
learnErrorHandling()
}
func learnErrorHandling() {
// ", ok" idiom used to tell if something worked or not.
m := map[int]string{3: "three", 4: "four"}
if x, ok := m[1]; !ok { // ok will be false because 1 is not in the map.
fmt.Println("no one there")
} else {
fmt.Print(x) // x would be the value, if it were in the map.
}
// An error value communicates not just "ok" but more about the problem.
if _, err := strconv.Atoi("non-int"); err != nil { // _ discards value
// prints 'strconv.ParseInt: parsing "non-int": invalid syntax'
fmt.Println(err)
}
// We'll revisit interfaces a little later. Meanwhile,
learnConcurrency()
}
216
// properly configured. All three send to the same channel.
go inc(0, c) // go is a statement that starts a new goroutine.
go inc(10, c)
go inc(-805, c)
// Read three results from the channel and print them out.
// There is no telling in what order the results will arrive!
fmt.Println(<-c, <-c, <-c) // channel on right, <- is "receive" operator.
requestServer()
}
func requestServer() {
resp, err := http.Get("http://localhost:8080")
fmt.Println(err)
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
fmt.Printf("\nWebserver said: `%s`", string(body))
217
}
Further Reading
The root of all things Go is the official Go web site. There you can follow the tutorial, play interactively,
and read lots. Aside from a tour, the docs contain information on how to write clean and effective Go code,
package and command docs, and release history.
The language definition itself is highly recommended. It’s easy to read and amazingly short (as language
definitions go these days.)
You can play around with the code on Go playground. Try to change it and run it from your browser! Note
that you can use https://play.golang.org as a REPL to test things and code in your browser, without even
installing Go.
On the reading list for students of Go is the source code to the standard library. Comprehensively docu-
mented, it demonstrates the best of readable and understandable Go, Go style, and Go idioms. Or you can
click on a function name in the documentation and the source code comes up!
Another great resource to learn Go is Go by example.
Go Mobile adds support for mobile platforms (Android and iOS). You can write all-Go native mobile apps
or write a library that contains bindings from a Go package, which can be invoked via Java (Android) and
Objective-C (iOS). Check out the Go Mobile page for more information.
Groovy
Groovy - A dynamic language for the Java platform Read more here.
/*
Set yourself up:
*/
// Hello World
println "Hello world!"
/*
Variables:
def x = 1
println x
218
x = new java.util.Date()
println x
x = -3.1499392
println x
x = false
println x
x = "Groovy!"
println x
/*
Collections and maps
*/
// As with Java
technologies.add("Grails")
// As with Java
technologies.remove("Griffon")
// Or
contained = 'Groovy' in technologies
219
technologies.containsAll(['Groovy','Grails'])
//Shuffle a list
Collections.shuffle(technologies, new Random())
//Clear a list
technologies.clear()
//Add values
devMap = ['name':'Roberto', 'framework':'Grails', 'language':'Groovy']
devMap.put('lastName','Perez')
/*
Groovy Beans
220
* A name declared with no access modifier generates a private field with
public getter and setter (i.e. a property).
* You can declare a property and also declare your own getter or setter.
* You can declare a property and a field of the same name, the property will
use that field then.
* If you want a private or protected property you have to provide your own
getter and setter which must be declared private or protected.
* If you access a property from within the class the property is defined in
at compile time with implicit or explicit this (for example this.foo, or
simply foo), Groovy will access the field directly instead of going though
the getter and setter.
* If you access a property that does not exist using the explicit or
implicit foo, then Groovy will access the property through the meta class,
which may fail at runtime.
*/
class Foo {
// read only property
final String name = "Roberto"
/*
Logical Branching and Looping
*/
if(x==1) {
println "One"
} else if(x==2) {
println "Two"
} else {
println "X greater than Two"
}
221
def x = (y > 1) ? "worked" : "failed"
assert x == "worked"
//For loop
//Iterate over a range
def x = 0
for (i in 0 .. 30) {
x += i
}
/*
Operators
Operator Overloading for a list of the common operators that Groovy supports:
http://www.groovy-lang.org/operators.html#Operator-Overloading
222
/*
Closures
A Groovy Closure is like a "code block" or a method pointer. It is a piece of
code that is defined and then executed at a later point.
// If you have a Closure that takes a single argument, you may omit the
// parameter definition of the Closure
def clos = { print it }
clos( "hi" )
/*
Groovy can memoize closure results [1][2][3]
*/
def cl = {a, b ->
sleep(3000) // simulate some time consuming processing
a + b
}
mem = cl.memoize()
def callClosure(a, b) {
def start = System.currentTimeMillis()
mem(a, b)
println "Inputs(a = $a, b = $b) - took ${System.currentTimeMillis() - start} msecs."
}
callClosure(1, 2)
callClosure(1, 2)
callClosure(2, 3)
callClosure(2, 3)
callClosure(3, 4)
callClosure(3, 4)
callClosure(1, 2)
callClosure(2, 3)
callClosure(3, 4)
223
/*
Expando
The Expando class is a dynamic bean so we can add properties and we can add
closures as methods to an instance of this class
http://mrhaki.blogspot.mx/2009/10/groovy-goodness-expando-as-dynamic-bean.html
*/
def user = new Expando(name:"Roberto")
assert 'Roberto' == user.name
user.lastName = 'Pérez'
assert 'Pérez' == user.lastName
/*
Metaprogramming (MOP)
*/
String x = "test"
x?.testAdd()
224
assertEquals "boo", f.boo
/*
TypeChecked and CompileStatic
Groovy, by nature, is and will always be a dynamic language but it supports
typechecked and compilestatic
void testMethod() {}
@TypeChecked
void test() {
testMeethod()
println naameee
//Another example:
import groovy.transform.TypeChecked
@TypeChecked
Integer test() {
Integer num = "1"
return "Test"
//CompileStatic example:
import groovy.transform.CompileStatic
@CompileStatic
int sum(int x, int y) {
x + y
}
assert sum(2,5) == 7
Further resources
Groovy documentation
225
Groovy web console
Join a Groovy user group
Books
• [Groovy Goodness] (https://leanpub.com/groovy-goodness-notebook)
• [Groovy in Action] (http://manning.com/koenig2/)
• [Programming Groovy 2: Dynamic Productivity for the Java Developer] (http://shop.oreilly.com/product/978193778530
1 http://roshandawrani.wordpress.com/2010/10/18/groovy-new-feature-closures-can-now-memorize-
their-results/ 2 http://www.solutionsiq.com/resources/agileiq-blog/bid/72880/Programming-with-
Groovy-Trampoline-and-Memoize 3 http://mrhaki.blogspot.mx/2011/05/groovy-goodness-cache-closure-
results.html
Hack
Hack is a superset of PHP that runs under a virtual machine called HHVM. Hack is almost completely
interoperable with existing PHP code and adds a bunch of useful features from statically typed languages.
Only Hack-specific features are covered here. Details about PHP’s syntax are available in the PHP article
on this site.
<?hh
// Hack syntax is only enabled for files starting with an <?hh marker
// <?hh markers cannot be interspersed with HTML the way <?php can be.
// Using the marker "<?hh //strict" puts the type checker in strict mode.
226
}
// Generics
class Box<T>
{
protected T $data;
// Shapes
//
// Hack adds the concept of shapes for defining struct-like arrays with a
// guaranteed, type-checked set of keys
type Point2D = shape('x' => int, 'y' => int);
227
}
distance(
shape('x' => -1, 'y' => 5),
shape('x' => 2, 'y' => 50)
);
// Type aliasing
//
// Hack adds a bunch of type aliasing features for making complex types readable
newtype VectorArray = array<int, Vector<int>>;
addPoints(
tuple(1, 2),
tuple(5, 6)
);
// First-class enums
enum RoadType : int
{
Road = 0;
Street = 1;
Avenue = 2;
Boulevard = 3;
}
228
class WithoutArgumentPromotion
{
public string $name;
// Co-operative multi-tasking
//
// Two new keywords "async" and "await" can be used to perform multi-tasking
// Note that this does not involve threads - it just allows transfer of control
async function cooperativePrint(int $start, int $end) : Awaitable<void>
{
for ($i = $start; $i <= $end; $i++) {
echo "$i ";
// Attributes
//
// Attributes are a form of metadata for functions. Hack provides some
// special built-in attributes that introduce useful behaviour.
229
// The __ConsistentConstruct special attribute signals the Hack type checker to
// ensure that the signature of __construct is the same for all subclasses.
<<__ConsistentConstruct>>
class ConsistentFoo
{
public function __construct(int $x, float $y)
{
// ...
}
// ...
}
230
// parent definition found or overridden parent is defined in non-<?hh code"
//
<<__Override>>
public function otherMethod()
{
// ...
}
}
// Traits can implement interfaces (standard PHP does not support this)
interface KittenInterface
{
public function play() : void;
}
class Samuel
{
use CatTrait;
}
More Information
Visit the Hack language reference for detailed explainations of the features Hack adds to PHP, or the official
Hack website for more general information.
Visit the official HHVM website for HHVM installation instructions.
Visit Hack’s unsupported PHP features article for details on the backwards incompatibility between Hack
and PHP.
Haml
Haml is a markup language predominantly used with Ruby that cleanly and simply describes the HTML
of any web document without the use of inline code. It is a popular alternative to using Rails templating
language (.erb) and allows you to embed Ruby code into your markup.
It aims to reduce repetition in your markup by closing tags for you based on the structure of the indents in
your code. The result is markup that is well-structured, DRY, logical, and easier to read.
You can also use Haml on a project independent of Ruby, by installing the Haml gem on your machine and
using the command line to convert it to html.
231
$ haml input_file.haml output_file.html
/ -------------------------------------------
/ Indenting
/ -------------------------------------------
/
Because of the importance indentation has on how your code is rendered, the
indents should be consistent throughout the document. Any differences in
indentation will throw an error. It's common-practice to use two spaces,
but it's really up to you, as long as they're constant.
/ -------------------------------------------
/ Comments
/ -------------------------------------------
/
To write a multi line comment, indent your commented code to be
wrapped by the forward slash
-# This is a silent comment, which means it wont be rendered into the doc at all
/ -------------------------------------------
/ Html elements
/ -------------------------------------------
/ To write your tags, use the percent sign followed by the name of the tag
%body
%header
%nav
/ The div tag is the default element, so they can be written simply like this
.foo
/ To add content to a tag, add the text directly after the declaration
%h1 Headline copy
232
You can escape html by using the ampersand and equals sign ( &= ). This
converts html-sensitive characters (&, /, :) into their html encoded
equivalents. For example
%p
&= "Yes & yes"
/ You can unescape html by using the bang and equals sign ( != )
%p
!= "This is how you write a paragraph tag <p></p>"
/ which would output 'This is how you write a paragraph tag <p></p>'
/ CSS classes can be added to your tags either by chaining .classnames to the tag
%div.foo.bar
/ To write data-attributes, use the :data key with its value as another hash
%div{:data => {:attribute => 'foo'}}
/ -------------------------------------------
/ Inserting Ruby
/ -------------------------------------------
/
To output a Ruby value as the contents of a tag, use an equals sign followed
by the Ruby code
%h1= book.name
%p
= book.author
= book.publisher
/ To run some Ruby code without rendering it to the html, use a hyphen instead
- books = ['book 1', 'book 2', 'book 3']
if book do
233
%p This is a book
/
Again, no need to add the closing tags to the block, even for the Ruby.
Indentation will take care of that for you.
/ -------------------------------------------
/ Inserting Table with bootstrap classes
/ -------------------------------------------
%table.table.table-hover
%thead
%tr
%th Header 1
%th Header 2
%tr
%td Value1
%td value2
%tfoot
%tr
%td
Foot value
/ -------------------------------------------
/ Inline Ruby / Ruby interpolation
/ -------------------------------------------
/ -------------------------------------------
/ Filters
/ -------------------------------------------
/
Use the colon to define Haml filters, one example of a filter you can
use is :javascript, which can be used for writing inline js
:javascript
console.log('This is inline <script>');
234
Additional resources
• What is HAML? - A good introduction that does a much better job of explaining the benefits of using
HAML.
• Official Docs - If you’d like to go a little deeper.
Haskell
Haskell was designed as a practical, purely functional programming language. It’s famous for its monads
and its type system, but I keep coming back to it because of its elegance. Haskell makes coding a real joy
for me.
-- Single line comments start with two dashes.
{- Multiline comments can be enclosed
in a block like this.
-}
----------------------------------------------------
-- 1. Primitive Datatypes and Operators
----------------------------------------------------
-- integer division
35 `div` 4 -- 8
-- Boolean operations
not True -- False
not False -- True
1 == 1 -- True
1 /= 1 -- False
1 < 10 -- True
235
-- Strings and characters
"This is a string."
'a' -- character
'You cant use single quotes for strings.' -- error!
----------------------------------------------------
-- Lists and Tuples
----------------------------------------------------
-- Infinite lists work because Haskell has "lazy evaluation". This means
-- that Haskell only evaluates things when it needs to. So you can ask for
-- the 1000th element of your list and Haskell will give it to you:
-- And now Haskell has evaluated elements 1 - 1000 of this list...but the
-- rest of the elements of this "infinite" list don't exist yet! Haskell won't
-- actually evaluate them until it needs to.
236
tail [1..5] -- [2, 3, 4, 5]
init [1..5] -- [1, 2, 3, 4]
last [1..5] -- 5
-- list comprehensions
[x*2 | x <- [1..5]] -- [2, 4, 6, 8, 10]
-- with a conditional
[x*2 | x <- [1..5], x*2 > 4] -- [6, 8, 10]
----------------------------------------------------
-- 3. Functions
----------------------------------------------------
-- A simple function that takes two variables
add a b = a + b
-- You can also put the function name between the two arguments
-- with backticks:
1 `add` 2 -- 3
-- You can also define functions that have no letters! This lets
-- you define your own operators! Here's an operator that does
-- integer division
(//) a b = a `div` b
35 // 4 -- 8
237
-- Pattern matching on tuples:
foo (x, y) = (x + 1, y + 2)
----------------------------------------------------
-- 4. More functions
----------------------------------------------------
add a b = a + b
foo = add 10 -- foo is now a function that takes a number and adds 10 to it
foo 5 -- 15
-- function composition
-- the operator `.` chains functions together.
-- For example, here foo is a function that takes a value. It adds 10 to it,
-- multiplies the result of that by 4, and then returns the final value.
foo = (4*) . (10+)
-- 4*(10 + 5) = 60
foo 5 -- 60
-- fixing precedence
-- Haskell has another operator called `$`. This operator applies a function
-- to a given parameter. In contrast to standard function application, which
-- has highest possible priority of 10 and is left-associative, the `$` operator
-- has priority of 0 and is right-associative. Such a low priority means that
-- the expression on its right is applied as the parameter to the function on its left.
-- before
even (fib 7) -- false
-- equivalently
238
even $ fib 7 -- false
-- composing functions
even . fib $ 7 -- false
----------------------------------------------------
-- 5. Type signatures
----------------------------------------------------
-- Haskell has a very strong type system, and every valid expression has a type.
-- When you define a value, it's good practice to write its type above it:
double :: Integer -> Integer
double x = x * 2
----------------------------------------------------
-- 6. Control Flow and If Expressions
----------------------------------------------------
-- if expressions
haskell = if 1 == 1 then "awesome" else "awful" -- haskell = "awesome"
-- case expressions: Here's how you could parse command line arguments
case args of
"help" -> printHelp
"start" -> startProgram
_ -> putStrLn "bad args"
239
-- and then use it
for [0..5] $ \i -> show i
----------------------------------------------------
-- 7. Data Types
----------------------------------------------------
----------------------------------------------------
-- 8. Haskell IO
----------------------------------------------------
240
main :: IO ()
main = putStrLn $ "Hello, sky! " ++ (say Blue)
-- putStrLn has type String -> IO ()
sayHello :: IO ()
sayHello = do
putStrLn "What is your name?"
name <- getLine -- this gets a line and gives it the name "name"
putStrLn $ "Hello, " ++ name
action :: IO String
action = do
putStrLn "This is a line. Duh"
input1 <- getLine
input2 <- getLine
-- The type of the `do` statement is that of its last line.
-- `return` is not a keyword, but merely a function
return (input1 ++ "\n" ++ input2) -- return :: String -> IO String
241
main'' = do
putStrLn "I will echo two lines!"
result <- action
putStrLn result
putStrLn "This was all, folks!"
-- The type `IO` is an example of a "monad". The way Haskell uses a monad to
-- do IO allows it to be a purely functional language. Any function that
-- interacts with the outside world (i.e. does IO) gets marked as `IO` in its
-- type signature. This lets us reason about what functions are "pure" (don't
-- interact with the outside world or modify state) and what functions aren't.
----------------------------------------------------
-- 9. The Haskell REPL
----------------------------------------------------
let foo = 5
-- You can see the type of any value or expression with `:t`:
> :t foo
foo :: Integer
> :t (:)
(:) :: a -> [a] -> [a]
> :i (+)
class Num a where
(+) :: a -> a -> a
...
-- Defined in ‘GHC.Num’
infixl 6 +
> sayHello
What is your name?
Friend!
Hello, Friend!
242
There’s a lot more to Haskell, including typeclasses and monads. These are the big ideas that make Haskell
such fun to code in. I’ll leave you with one final Haskell example: an implementation of a quicksort variant
in Haskell:
qsort [] = []
qsort (p:xs) = qsort lesser ++ [p] ++ qsort greater
where lesser = filter (< p) xs
greater = filter (>= p) xs
There are two popular ways to install Haskell: The traditional Cabal-based installation, and the newer
Stack-based process.
You can find a much gentler introduction from the excellent Learn you a Haskell or Real World Haskell.
Haxe
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.
/*
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
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
by the compiler.
*/
/*
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).
/*
Packages are directories that contain modules. Each module is a .hx file
that contains types defined in a package. Package names (e.g. org.yourapp)
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,
243
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:
*/
import haxe.ds.ArraySort;
/*
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.
*/
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{
/*
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(){
/*
Trace is the default method of printing haxe expressions to the
screen. Different targets will have different methods of
accomplishing this. E.g., java, c++, c#, etc. will print to std
out. Javascript will print to console.log, and flash will print to
an embedded TextField. All traces come with a default newline.
Finally, It's possible to prevent traces from showing by using the
"--no-traces" argument on the compiler.
*/
trace("Hello World, with trace()!");
244
/*
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:
*/
trace('two expressions..'); trace('one line');
//////////////////////////////////////////////////////////////////
// Types & Variables
//////////////////////////////////////////////////////////////////
trace("***Types & Variables***");
/*
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
it. It's not necessary to declare the type in many cases. Here,
the haxe compiler is inferring that the type of another_integer
should be "Int".
*/
var another_integer = 2;
trace(another_integer + " is the value for another_integer");
// The $type() method prints the type that the compiler assigns:
$type(another_integer);
/*
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)
*/
/*
In addition to simple values like Integers, Floats, and Booleans,
Haxe provides standard library implementations for common data
245
structures like strings, arrays, lists, and maps:
*/
var a_string = "some" + 'string'; // strings can have double or single quotes
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 ${...}.
*/
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).
*/
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.
*/
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.
*/
var a = new Array<String>(); // an array that contains Strings
a[0] = 'foo';
trace(a.length + " is the value for a.length");
a[9] = 'bar';
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:
*/
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.
m.set('foo', 4);
246
// 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')");
trace(m['bar'] + " is the value for m['bar']");
/*
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
*/
//////////////////////////////////////////////////////////////////
// Operators
//////////////////////////////////////////////////////////////////
trace("***OPERATORS***");
// basic arithmetic
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)");
trace((12 % 4) + " is the value for (12 % 4)");
//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");
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");
247
*/
//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
//////////////////////////////////////////////////////////////////
// Control Structures
//////////////////////////////////////////////////////////////////
trace("***CONTROL STRUCTURES***");
// if statements
var j = 10;
if (j == 10){
trace("this is printed");
} else if (j > 10){
trace("not greater than 10, so not printed");
} else {
trace("also not printed.");
}
/*
Finally, there is another form of control structures that operates
at compile time: conditional compilation.
*/
#if neko
trace('hello from neko');
#elseif js
trace('hello from js');
#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.
*/
// while loop
var k = 0;
while(k < 100){
// trace(counter); // will print out numbers 0-99
k++;
}
248
// do-while loop
var l = 0;
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){
trace(val + " is the value for val in the m array");
}
trace("Array Comprehensions");
//////////////////////////////////////////////////////////////////
// Switch Statements (Value Type)
//////////////////////////////////////////////////////////////////
trace("***SWITCH STATEMENTS (VALUE TYPES)***");
/*
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:
*/
var my_dog_name = "fido";
var favorite_thing = "";
switch(my_dog_name){
case "fido" : favorite_thing = "bone";
249
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
}
// The "_" case above is a "wildcard" value
// that will match anything.
//////////////////////////////////////////////////////////////////
// Expression Statements
//////////////////////////////////////////////////////////////////
trace("***EXPRESSION STATEMENTS***");
/*
Haxe control statements are very powerful because every statement
is also an expression, consider:
*/
// if statements
var k = if (true) 10 else 20;
//////////////////////////////////////////////////////////////////
// Converting Value Types
//////////////////////////////////////////////////////////////////
trace("***CONVERTING VALUE TYPES***");
// string to integer
Std.parseInt("0"); // returns 0
Std.parseFloat("0.4"); // returns 0.4;
// integer to string
Std.string(0); // returns "0";
// concatenation with strings will auto-convert to string.
0 + ""; // returns "0";
true + ""; // returns "true";
250
// See documentation for parsing in Std for more details.
//////////////////////////////////////////////////////////////////
// Dealing with Types
//////////////////////////////////////////////////////////////////
/*
*HOWEVER*, there are times when you just wish the compiler would let
something slide, and not throw a type error in a given case.
/*
All that you know for certain with a Dynamic variable is that the
compiler will no longer worry about what type it is. It is like a
wildcard variable: You can pass it instead of any variable type,
and you can assign any variable type you want.
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
any type checks that might be otherwise required. This keyword should
be used very sparingly, such as in limited conditionally-compiled
situations where type checking is a hinderance.
//////////////////////////////////////////////////////////////////
// Basic Object Oriented Programming
//////////////////////////////////////////////////////////////////
trace("***BASIC OBJECT ORIENTED PROGRAMMING***");
251
/*
Create an instance of FooClass. The classes for this are at the
end of the file.
*/
var foo_instance = new FooClass(3);
/*
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.
*/
SimpleEnumTest.example();
ComplexEnumTest.example();
TypedefsAndStructuralTypes.example();
UsingExample.example();
/*
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
252
// a public constructor
public function new(arg:Int){
// call the constructor of the parent object, since we extended BarClass:
super();
this.public_any = 0;
this._private = arg;
/*
A simple class to extend
*/
class BarClass {
var base_variable:Int;
public function new(){
base_variable = 4;
}
public static function acceptBarInstance(b:BarClass){
}
}
/*
A simple interface to implement
*/
interface BarInterface{
public function baseFunction(x:Int):String;
}
//////////////////////////////////////////////////////////////////
253
// Enums and Switch Statements
//////////////////////////////////////////////////////////////////
/*
Enums in Haxe are very powerful. In their simplest form, enums
are a type with a limited number of states:
*/
enum SimpleEnum {
Foo;
Bar;
Baz;
}
class SimpleEnumTest{
public static function example(){
var e_explicit:SimpleEnum = SimpleEnum.Foo; // you can specify the "full" name
var e = Foo; // but inference will work as well.
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.
}
/*
This doesn't seem so different from simple value switches on strings.
However, if we don't include *all* of the states, the compiler will
complain. You can try it by commenting out a line above.
/*
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);
ComplexEnumEnum(c: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{
254
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){
case IntEnum(x) : trace('$x was the parameter passed to e1');
default: trace("Shouldn't be printed");
}
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.
*/
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":
*/
/*
The anon_obj variable doesn't have a type declared, and is an
anonymous object according to the compiler. However, remember back at
the top where we declared the FooObj typedef? Since anon_obj matches
255
that structure, we can use it anywhere that a "FooObject" type is
expected.
*/
var f = function(fo:FooObject){
trace('$fo was passed in to this function');
}
f(anon_obj); // call the FooObject signature function with anon_obj.
/*
Note that typedefs can have optional fields as well, marked with "?"
typedef OptionalFooObj = {
?optionalString: String,
requiredInt: Int
}
*/
/*
Typedefs work well with conditional compilation. For instance,
we could have included this at the top of the file:
#if( js )
typedef Surface = js.html.CanvasRenderingContext2D;
#elseif( nme )
typedef Surface = nme.display.Graphics;
#elseif( !flash9 )
typedef Surface = flash8.MovieClip;
#elseif( java )
typedef Surface = java.awt.geom.GeneralPath;
#end
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.
/*
With a "using" import, the first argument type is extended with the
method. What does that mean? Well, since "endsWith" has a first
argument type of "String", that means all String types now have the
256
"endsWith" method:
*/
trace("foobar".endsWith("bar") + " should be true!");
/*
This technique enables a good deal of expression for certain types,
while limiting the scope of modifications to a single file.
Note that the String instance is *not* modified in the run time.
The newly attached method is not really part of the attached
instance, and the compiler still generates code equivalent to a
static method.
*/
}
}
We’re still only scratching the surface here of what Haxe can do. For a formal overiew of all Haxe features,
checkout the online manual, the online api, and “haxelib”, the [haxe library repo] (http://lib.haxe.org/).
For more advanced topics, consider checking out:
• Abstract types
• Macros, and Compiler Macros
• Tips and Tricks
Finally, please join us on the mailing list, on IRC #haxe on freenode, or on Google+.
Hy
Hy is a lisp dialect built on top of python. This is achieved by converting hy code to python’s abstract
syntax tree (ast). This allows hy to call native python code or python to call native hy code as well
This tutorial works for hy � 0.9.12, with some corrections for hy 0.11.
;; this gives an gentle introduction to hy for a quick trial head to
;; http://try-hy.appspot.com
;;
; Semicolon comments, like other LISPS
;; s-expression basics
; lisp programs are made of symbolic expressions or sexps which
; resemble
(some-function args)
; now the quintessential hello world
(print "hello world")
257
(+ 4 1) ;=> 5
; the operator is applied to all arguments, like other lisps
(+ 4 1 2 3) ;=> 10
(- 2 1) ;=> 1
(* 4 2) ;=> 8
(/ 4 1) ;=> 4
(% 4 2) ;=> 0 the modulo operator
; power is represented by ** operator like python
(** 3 2) ;=> 9
; nesting forms will do the expected thing
(+ 2 (* 4 2)) ;=> 10
; also logical operators and or not and equal to etc. do as expected
(= 5 4) ;=> False
(not (= 5 4)) ;=> True
;; variables
; variables are set using setv, variable names can use utf-8 except
; for ()[]{}",'`;#|
(setv a 42)
(setv � 3.14159)
(def *foo* 42)
;; other container data types
; strings, lists, tuples & dicts
; these are exactly same as python's container types
"hello world" ;=> "hello world"
; string operations work similar to python
(+ "hello " "world") ;=> "hello world"
; lists are created using [], indexing starts at 0
(setv mylist [1 2 3 4])
; tuples are immutable data structures
(setv mytuple (, 1 2))
; dictionaries are key value pairs
(setv dict1 {"key1" 42 "key2" 21})
; :name can be used to define keywords in hy which can be used for keys
(setv dict2 {:key1 41 :key2 20})
; use `get' to get the element at an index/key
(get mylist 1) ;=> 2
(get dict1 "key1") ;=> 42
; Alternatively if keywords were used they can directly be called
(:key1 dict2) ;=> 41
(foolists 3) ;=> [3 2]
258
(foolists 10 3) ;=> [10 3]
;; Sequence operations
; hy has some builtin utils for sequence operations etc.
; retrieve the first element using `first' or `car'
(setv mylist [1 2 3 4])
(setv mydict {"a" 1 "b" 2})
(first mylist) ;=> 1
;; Python interop
;; import works just like in python
(import datetime)
(import [functools [partial reduce]]) ; imports fun1 and fun2 from module1
(import [matplotlib.pyplot :as plt]) ; doing an import foo as bar
; all builtin python methods etc. are accessible from hy
; a.foo(arg) is called as (.foo a arg)
(.split (.strip "hello world ")) ;=> ["hello" "world"]
259
(+ (* 4 3) 2)
; there is also a "threading tail macro", which instead passes the value as the
; second argument. compare:
(-> 4 (- 2) (+ 1)) ;=> 3
(+ (- 4 2) 1) ;=> 3
; to:
(->> 4 (- 2) (+ 1)) ;=> -1
(+ 1 (- 2 4)) ;=> -1
;; Conditionals
; (if condition (body-if-true) (body-if-false)
(if (= passcode "moria")
(print "welcome")
(print "Speak friend, and Enter!"))
;; classes
; classes are defined in the following way
(defclass Wizard [object]
[[--init-- (fn [self spell]
(setv self.spell spell) ; init the spell attr
None)]
[get-spell (fn [self]
self.spell)]])
; or, in hy 0.11:
(defclass Wizard [object]
(defn --init-- [self spell]
(setv self.spell spell))
260
self.spell))
;; do checkout hylang.org
Further Reading
Inform7
Inform 7 is a natural language based language created by Graham Nelson and Emily Short for writing text
adventures, but also potentially usable for other text based applications, especially data backed ones.
"LearnInform" by Hyphz
[This is a comment.]
261
To toggle (the block - a datablock):
if the block is broken: [Conditional.]
now the block is not broken; [Updating a property.]
else:
now the block is broken.
[Multiple parameters.]
To fix (the broken block - a datablock) using (the repair block - a datablock):
if the broken block is not broken, stop; [Comma for a non indented single command.]
if the repair block is broken, stop;
now the sequence number of the broken block is the sequence number of the repair block;
now the broken block is not broken.
[Because of its text adventure origins, Inform 7 doesn't generally allow objects
to be created dynamically, although there's a language extension that enables it.]
Block2 is a datablock.
Block2 is broken.
The sequence number of Block2 is 2.
The name of Block2 is "Block two."
[Lists.]
To show how to use list types:
let the list be a list of datablocks;
add Block1 to the list;
add Block2 to the list;
say the list; ["Block1 and Block2"]
[Membership.]
if Block1 is listed in the list:
say "Block1 is there.";
[Loop.]
repeat with the block running through the list:
dump the block; [1 Block One. 1 Block Two.]
[Remember block two's sequence number was changed above.]
let X be entry 2 of the list; [Counting starts at 1.]
dump X; ["1 Block two."]
remove X from the list;
say the list. [Block1]
To decide which number is the sum of all numbers up to (X - a number) (this is summing up):
let the total so far be a number;
repeat with the current number running from 1 to X:
now the total so far is the total so far + the current number;
decide on the total so far. [This is the return statement.]
262
say summing up applied to {1, 2, 3, 4}.
To decide which number is the result of applying (phrase - phrase A -> A) twice to (B - a value of kind A):
let b1 be phrase applied to B;
let b2 be phrase applied to b1;
decide on b2.
[ Rulebooks allow a number of functions which apply to the same type under different conditions to be stacked.
[ Objects can also have relations, which resemble those in a relational database. ]
A dog is a kind of thing.
Rover is a dog.
The kennel is a container. [This is a built in base class.]
Rover is in the kennel. [This creates an inbuilt relation called "containment".]
263
Helpfulness relates a person (called the helper) to a person (called the helpee) when the helpee is blind and
The verb to be helpful to means the helpfulness relation.
To demonstrate using a procedural relation:
repeat with the helper running through people that are helpful to Edward:
say the helper.
[ Interface to the text adventure harness to allow the above code to be run. ]
Tutorial room is a room.
"A rather strange room full of buttons. Push them to run the exercises, or turn on the robot to run them all."
A button is a kind of thing. A button is fixed in place.
Java
Java is a general-purpose, concurrent, class-based, object-oriented computer programming language. Read
more here.
// Single-line comments start with //
/*
Multi-line comments look like this.
264
*/
/**
* JavaDoc comments look like this. Used to describe the Class or various
* attributes of a Class.
* Main attributes:
*
* @author Name (and contact information such as email) of author(s).
* @version Current version of the program.
* @since When this part of the program was first added.
* @param For describing the different parameters for a method.
* @return For describing what the method returns.
* @deprecated For showing the code is outdated or shouldn't be used.
* @see Links to another part of documentation.
*/
// Each .java file contains one outer-level public class, with the same name
// as the file.
public class LearnJava {
///////////////////////////////////////
// Variables
///////////////////////////////////////
/*
* Variable Declaration
*/
// Declare a variable using <type> <name>
int fooInt;
// Declare multiple variables of the same
// type <type> <name1>, <name2>, <name3>
265
int fooInt1, fooInt2, fooInt3;
/*
* Variable Initialization
*/
/*
* Variable types
*/
// Byte - 8-bit signed two's complement integer
// (-128 <= byte <= 127)
byte fooByte = 100;
266
final int HOURS_I_WORK_PER_WEEK = 9001;
// but they can be initialized later.
final double E;
E = 2.71828;
// Strings
String fooString = "My String Is Here!";
// String Building
// #1 - with plus operator
// That's the basic way to do it (optimized under the hood)
String plusConcatenated = "Strings can " + "be concatenated " + "via + operator.";
System.out.println(plusConcatenated);
// Output: Strings can be concatenated via + operator.
// #2 - with StringBuilder
// This way doesn't create any intermediate strings. It just stores the string pieces, and ties
// when toString() is called.
// Hint: This class is not thread safe. A thread-safe alternative (with some impact on performan
267
StringBuilder builderConcatenated = new StringBuilder();
builderConcatenated.append("You ");
builderConcatenated.append("can use ");
builderConcatenated.append("the StringBuilder class.");
System.out.println(builderConcatenated.toString()); // only now is the string built
// Output: You can use the StringBuilder class.
// Arrays
// The array size must be decided upon instantiation
// The following formats work for declaring an array
// <datatype>[] <var name> = new <datatype>[<array size>];
// <datatype> <var name>[] = new <datatype>[<array size>];
int[] intArray = new int[10];
String[] stringArray = new String[1];
boolean boolArray[] = new boolean[100];
///////////////////////////////////////
268
// Operators
///////////////////////////////////////
System.out.println("\n->Operators");
// Arithmetic is straightforward
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 returns int)
System.out.println("1/2 = " + (i1 / (double)i2)); // => 0.5
// Modulo
System.out.println("11%3 = "+(11 % 3)); // => 2
// Comparison operators
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
// Boolean operators
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
// Bitwise operators!
/*
~ Unary bitwise complement
<< Signed left shift
>> Signed/Arithmetic right shift
>>> Unsigned/Logical right shift
& Bitwise AND
^ Bitwise exclusive OR
| Bitwise inclusive OR
*/
// Increment operators
int i = 0;
System.out.println("\n->Inc/Dec-rementation");
// The ++ and -- operators increment and decrement by 1 respectively.
// If they are placed before the variable, they increment then return;
// after the variable they return then increment.
System.out.println(i++); // i = 1, prints 0 (post-increment)
System.out.println(++i); // i = 2, prints 2 (pre-increment)
System.out.println(i--); // i = 1, prints 2 (post-decrement)
System.out.println(--i); // i = 0, prints 0 (pre-decrement)
///////////////////////////////////////
// Control Structures
///////////////////////////////////////
269
System.out.println("\n->Control Structures");
// While loop
int fooWhile = 0;
while(fooWhile < 100) {
System.out.println(fooWhile);
// Increment the counter
// Iterated 100 times, fooWhile 0,1,2...99
fooWhile++;
}
System.out.println("fooWhile Value: " + fooWhile);
// Do While Loop
int fooDoWhile = 0;
do {
System.out.println(fooDoWhile);
// Increment the counter
// Iterated 99 times, fooDoWhile 0->99
fooDoWhile++;
} while(fooDoWhile < 100);
System.out.println("fooDoWhile Value: " + fooDoWhile);
// For Loop
// for loop structure => for(<start_statement>; <conditional>; <step>)
for (int fooFor = 0; fooFor < 10; fooFor++) {
System.out.println(fooFor);
// Iterated 10 times, fooFor 0->9
}
System.out.println("fooFor Value: " + fooFor);
270
int[] fooList = {1, 2, 3, 4, 5, 6, 7, 8, 9};
// for each loop structure => for (<object> : <iterable>)
// reads as: for each element in the iterable
// note: the object type must match the element type of the iterable.
for (int bar : fooList) {
System.out.println(bar);
//Iterates 9 times and prints 1-9 on new lines
}
// Switch Case
// A switch works with the byte, short, char, and int data types.
// It also works with enumerated types (discussed in Enum Types), the
// String class, and a few special classes that wrap primitive types:
// Character, Byte, Short, and Integer.
int month = 3;
String monthString;
switch (month) {
case 1: monthString = "January";
break;
case 2: monthString = "February";
break;
case 3: monthString = "March";
break;
default: monthString = "Some other month";
break;
}
System.out.println("Switch Case Result: " + monthString);
// Conditional Shorthand
// You can use the '?' operator for quick assignments or logic forks.
// Reads as "If (statement) is true, use <first value>, otherwise, use
// <second value>"
int foo = 5;
String bar = (foo < 10) ? "A" : "B";
System.out.println(bar); // Prints A, because the statement is true
////////////////////////////////////////
271
// Converting Data Types And Typecasting
////////////////////////////////////////
// Converting data
// Typecasting
// You can also cast Java objects, there's a lot of details and deals
// with some more intermediate concepts. Feel free to check it out here:
// http://docs.oracle.com/javase/tutorial/java/IandI/subclasses.html
///////////////////////////////////////
// Classes And Functions
///////////////////////////////////////
272
add("SWEDEN");
add("FINLAND");
}}
class Bicycle {
// Bicycle's Fields/Variables
public int cadence; // Public: Can be accessed from anywhere
private int speed; // Private: Only accessible from within the class
protected int gear; // Protected: Accessible from the class and subclasses
String name; // default: Only accessible from within this package
static String className; // Static class variable
// Static block
// Java has no implementation of static constructors, but
// has a static block that can be used to initialize class variables
// (static variables).
// This block will be called when the class is loaded.
static {
className = "Bicycle";
}
273
this.cadence = startCadence;
this.speed = startSpeed;
this.name = name;
}
// Method Syntax:
// <public/private/protected> <return type> <function name>(<args>)
// Java classes often implement getters and setters for their fields
274
// You should mark a method you're overriding with an @annotation.
// To learn more about what annotations are and their purpose check this
// out: http://docs.oracle.com/javase/tutorial/java/annotations/
@Override
public void setGear(int gear) {
gear = 0;
}
}
// Interfaces
// Interface declaration syntax
// <access-level> interface <interface-name> extends <super-interfaces> {
// // Constants
// // Method declarations
// }
// Example - Food:
public interface Edible {
public void eat(); // Any class that implements this interface, must
// implement this method.
}
@Override
public void digest() {
// ...
}
}
// In Java, you can extend only one class, but you can implement many
// interfaces. For example:
public class ExampleClass extends ExampleClassParent implements InterfaceOne,
InterfaceTwo {
@Override
public void InterfaceOneMethod() {
}
@Override
public void InterfaceTwoMethod() {
}
// Abstract Classes
275
// Abstract Class declaration syntax
// <access-level> abstract <abstract-class-name> extends <super-abstract-classes> {
// // Constants and variables
// // Method declarations
// }
276
// NOTE: You will get an error if you used the
// @Override annotation here, since java doesn't allow
// overriding of static methods.
// What is happening here is called METHOD HIDING.
// Check out this SO post: http://stackoverflow.com/questions/16313649/
public static void main(String[] args)
{
Dog pluto = new Dog();
pluto.makeSound();
pluto.eat();
pluto.printAge();
}
}
// Final Classes
// Final classes are classes that cannot be inherited from and are therefore a
// final child. In a way, final classes are the opposite of abstract classes
// because abstract classes must be extended, but final classes cannot be
// extended.
public final class SaberToothedCat extends Animal
{
// Note still have to override the abstract methods in the
// abstract class.
@Override
public void makeSound()
{
System.out.println("Roar");
}
}
// Final Methods
public abstract class Mammal()
{
// Final Method Syntax:
// <access modifier> final <return type> <function name>(<args>)
// Enum Type
//
// An enum type is a special data type that enables for a variable to be a set
277
// of predefined constants. The variable must be equal to one of the values
// that have been predefined for it. Because they are constants, the names of
// an enum type's fields are in uppercase letters. In the Java programming
// language, you define an enum type by using the enum keyword. For example,
// you would specify a days-of-the-week enum type as:
public enum Day {
SUNDAY, MONDAY, TUESDAY, WEDNESDAY,
THURSDAY, FRIDAY, SATURDAY
}
Further Reading
The links provided here below are just to get an understanding of the topic, feel free to Google and find
specific examples.
278
Official Oracle Guides:
• Java Tutorial Trail from Sun / Oracle
• Java Access level modifiers
• Object-Oriented Programming Concepts:
– Inheritance
– Polymorphism
– Abstraction
• Exceptions
• Interfaces
• Generics
• Java Code Conventions
Online Practice and Tutorials
• Learneroo.com - Learn Java
• Codingbat.com
Books:
• Head First Java
• Thinking in Java
• Objects First with Java
• Java The Complete Reference
Javascript
JavaScript was created by Netscape’s Brendan Eich in 1995. It was originally intended as a simpler scripting
language for websites, complementing the use of Java for more complex web applications, but its tight
integration with Web pages and built-in support in browsers has caused it to become far more common than
Java in web frontends.
JavaScript isn’t just limited to web browsers, though: Node.js, a project that provides a standalone runtime
for Google Chrome’s V8 JavaScript engine, is becoming more and more popular.
JavaScript has a C-like syntax, so if you’ve used languages like C or Java, a lot of the basic syntax will
already be familiar. Despite this, and despite the similarity in name, JavaScript’s object model is significantly
different to Java’s.
// Single-line comments start with two slashes.
/* Multiline comments start with slash-star,
and end with star-slash */
// ... but they don't have to be, as semicolons are automatically inserted
// wherever there's a newline, except in certain cases.
doStuff()
// Because those cases can cause unexpected results, we'll keep on using
// semicolons in this guide.
279
///////////////////////////////////
// 1. Numbers, Strings and Operators
// JavaScript has one number type (which is a 64-bit IEEE 754 double).
// Doubles have a 52-bit mantissa, which is enough to store integers
// up to about 9�10¹5 precisely.
3; // = 3
1.5; // = 1.5
// Bitwise operations also work; when you perform a bitwise operation your float
// is converted to a signed int *up to* 32 bits.
1 << 2; // = 4
// Equality is ===
1 === 1; // = true
2 === 1; // = false
// Inequality is !==
1 !== 1; // = false
280
2 !== 1; // = true
// More comparisons
1 < 10; // = true
1 > 10; // = false
2 <= 2; // = true
2 >= 2; // = true
// false, null, undefined, NaN, 0 and "" are falsy; everything else is truthy.
// Note that 0 is falsy and "0" is truthy, even though 0 == "0".
///////////////////////////////////
// 2. Variables, Arrays and Objects
281
// If you leave the var keyword off, you won't get an error...
someOtherVar = 10;
// ...but your variable will be created in the global scope, not in the scope
// you defined it in.
// If you want to declare a couple of variables, then you could use a comma
// separator
var someFourthVar = 2, someFifthVar = 4;
// ... or using the dot syntax, provided the key is a valid identifier.
myObj.myKey; // = "myValue"
// Objects are mutable; values can be changed and new keys added.
myObj.myThirdKey = true;
// If you try to access a value that's not yet set, you'll get undefined.
282
myObj.myFourthKey; // = undefined
///////////////////////////////////
// 3. Logic and Control Structures
// As does `while`.
while (true){
// An infinite loop!
}
// Do-while loops are like while loops, except they always run at least once.
var input;
do {
input = getInput();
} while (!isValid(input))
// The for/in statement iterates over every property across the entire prototype chain.
var description = "";
var person = {fname:"Paul", lname:"Ken", age:18};
for (var x in person){
description += person[x] + " ";
}
// For/in should not be used to iterate over an Array where the index order
// is important, as there is no guarantee that for/in will return the indexes
// in any particular order.
283
if (house.size == "big" && house.colour == "blue"){
house.contains = "bear";
}
if (colour == "red" || colour == "blue"){
// colour is either red or blue
}
// && and || "short circuit", which is useful for setting default values.
var name = otherName || "default";
///////////////////////////////////
// 4. Functions, Scope and Closures
// Note that the value to be returned must start on the same line as the
// `return` keyword, otherwise you'll always return `undefined` due to
// automatic semicolon insertion. Watch out for this when using Allman style.
function myFunction(){
return // <- semicolon automatically inserted here
{thisIsAn: 'object literal'}
}
myFunction(); // = undefined
284
}
setTimeout(myFunction, 5000);
// Note: setTimeout isn't part of the JS language, but is provided by browsers
// and Node.js.
// Function objects don't even have to be declared with a name - you can write
// an anonymous function definition directly into the arguments of another.
setTimeout(function(){
// this code will be called in 5 seconds' time
}, 5000);
// JavaScript has function scope; functions get their own scope but other blocks
// do not.
if (true){
var i = 5;
}
i; // = 5 - not undefined as you'd expect in a block-scoped language
285
///////////////////////////////////
// 5. More about Objects; Constructors and Prototypes
// When functions attached to an object are called, they can access the object
// they're attached to using the `this` keyword.
myObj = {
myString: "Hello world!",
myFunc: function(){
return this.myString;
}
};
myObj.myFunc(); // = "Hello world!"
// What this is set to has to do with how the function is called, not where
// it's defined. So, our function doesn't work if it isn't called in the
// context of the object.
var myFunc = myObj.myFunc;
myFunc(); // = undefined
// The `apply` function is nearly identical, but takes an array for an argument
// list.
anotherFunc.apply(myObj, [" And Hello Sun!"]); // = "Hello World! And Hello Sun!"
Math.min(42, 6, 27); // = 6
Math.min([42, 6, 27]); // = NaN (uh-oh!)
286
Math.min.apply(Math, [42, 6, 27]); // = 6
// But, `call` and `apply` are only temporary. When we want it to stick, we can
// use `bind`.
// When you call a function with the `new` keyword, a new object is created, and
// made available to the function via the `this` keyword. Functions designed to be
// called like that are called constructors.
myObj.__proto__ = myPrototype;
myObj.meaningOfLife; // = 42
287
// There's no copying involved here; each object stores a reference to its
// prototype. This means we can alter the prototype and our changes will be
// reflected everywhere.
myPrototype.meaningOfLife = 43;
myObj.meaningOfLife; // = 43
// Built-in types like strings and numbers also have constructors that create
// equivalent wrapper objects.
var myNumber = 12;
var myNumberObj = new Number(12);
myNumber == myNumberObj; // = true
// However, the wrapper objects and the regular builtins share a prototype, so
// you can actually add functionality to a string, for instance.
String.prototype.firstCharacter = function(){
return this.charAt(0);
}
"abc".firstCharacter(); // = "a"
288
// This fact is often used in "polyfilling", which is implementing newer
// features of JavaScript in an older subset of JavaScript, so that they can be
// used in older environments such as outdated browsers.
Further Reading
The Mozilla Developer Network provides excellent documentation for JavaScript as it’s used in browsers.
Plus, it’s a wiki, so as you learn more you can help others out by sharing your own knowledge.
MDN’s A re-introduction to JavaScript covers much of the concepts covered here in more detail. This guide
has quite deliberately only covered the JavaScript language itself; if you want to learn more about how to
use JavaScript in web pages, start by learning about the Document Object Model.
Learn Javascript by Example and with Challenges is a variant of this reference with built-in challenges.
JavaScript Garden is an in-depth guide of all the counter-intuitive parts of the language.
JavaScript: The Definitive Guide is a classic guide and reference book.
Eloquent Javascript by Marijn Haverbeke is an excellent JS book/ebook with attached terminal
Eloquent Javascript - The Annotated Version by Gordon Zhu is also a great derivative of Eloquent Javascript
with extra explanations and clarifications for some of the more complicated examples.
Javascript: The Right Way is a guide intended to introduce new developers to JavaScript and help experi-
enced developers learn more about its best practices.
In addition to direct contributors to this article, some content is adapted from Louie Dinh’s Python tutorial
on this site, and the JS Tutorial on the Mozilla Developer Network.
Json
JSON is an extremely simple data-interchange format. As json.org says, it is easy for humans to read and
write and for machines to parse and generate.
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.
289
For the purposes of this tutorial, everything is going to be 100% valid JSON. Luckily, it kind of speaks for
itself.
Supported data types:
• Strings: "hello", "\"A quote.\"", "\u0abe", "Newline.\n"
• Numbers: 23, 0.11, 12e10, 3.141e-10, 1.23e+4
• Objects: { "key": "value" }
• Arrays: ["Values"]
• Miscellaneous: true, false, null
{
"key": "value",
"objects": {
"comment": "Most of your structure will come from objects.",
"another object": {
"comment": "These things can be nested, very useful."
}
},
"silliness": [
{
"sources of potassium": ["bananas"]
},
[
[1, 0, 0, 0],
[0, 1, 0, 0],
[0, 0, 1, "neo"],
[0, 0, 0, 1]
]
],
"alternative style": {
"comment": "check this out!"
, "comma position": "doesn't matter, if it's before the next key, it's valid"
, "another comment": "how nice"
},
290
"that was short": "And done. You now know everything JSON has to offer."
}
Further Reading
• JSON.org All of JSON beautifully explained using flowchart-like graphics.
Julia
Julia is a new homoiconic functional language focused on technical computing. While having the full power
of homoiconic macros, first-class functions, and low-level control, Julia is as easy to learn and use as Python.
This is based on Julia 0.4.
####################################################
## 1. Primitive Datatypes and Operators
####################################################
# Bitwise Operators
~2 # => -3 # bitwise not
3 & 5 # => 1 # bitwise and
2 | 4 # => 6 # bitwise or
2 $ 4 # => 6 # bitwise xor
2 >>> 1 # => 1 # logical shift right
291
2 >> 1 # => 1 # arithmetic shift right
2 << 1 # => 4 # logical/arithmetic shift left
# You can use the bits function to see the binary representation of a number.
bits(12345)
# => "0000000000000000000000000000000000000000000000000011000000111001"
bits(12345.0)
# => "0100000011001000000111001000000000000000000000000000000000000000"
# Boolean operators
!true # => false
!false # => true
1 == 1 # => true
2 == 1 # => false
1 != 1 # => false
2 != 1 # => true
1 < 10 # => true
1 > 10 # => false
2 <= 2 # => true
2 >= 2 # => true
# Comparisons can be chained
1 < 2 < 3 # => true
2 < 3 < 2 # => false
# Printing is easy
println("I'm Julia. Nice to meet you!")
292
"good" == "good" # => true
"1 + 2 = 3" == "1 + 2 = $(1+2)" # => true
####################################################
## 2. Variables and Collections
####################################################
293
b = Int8[4, 5, 6] # => 3-element Int8 Array: [4, 5, 6]
# Function names that end in exclamations points indicate that they modify
# their argument.
arr = [5,4,6] # => 3-element Int64 Array: [5,4,6]
sort(arr) # => [4,5,6]; arr is still [5,4,6]
sort!(arr) # => [4,5,6]; arr is now [4,5,6]
# Errors list the line and file they came from, even if it's in the standard
# library. If you built Julia from source, you can look in the folder base
# inside the julia folder to find these files.
294
# Concatenate lists with append!
b = [1,2,3]
append!(a,b) # Now a is [1, 2, 3, 4, 5, 1, 2, 3]
295
values(filled_dict)
# => ValueIterator{Dict{ASCIIString,Int64}}(["three"=>3,"one"=>1,"two"=>2])
# Note - Same as above regarding key ordering.
# Use the get method to avoid that error by providing a default value
# get(dictionary,key,default_value)
get(filled_dict,"one",4) # => 1
get(filled_dict,"four",4) # => 4
####################################################
## 3. Control Flow
####################################################
296
println("some_var is indeed 10.")
end
# => prints "some var is smaller than 10"
for a in Dict("dog"=>"mammal","cat"=>"mammal","mouse"=>"mammal")
println("$(a[1]) is a $(a[2])")
end
# prints:
# dog is a mammal
# cat is a mammal
# mouse is a mammal
297
try
error("help")
catch e
println("caught it $e")
end
# => caught it ErrorException("help")
####################################################
## 4. Functions
####################################################
298
function defaults(a,b,x=5,y=6)
return "$a $b and $x $y"
end
all_the_args(1, 3, keyword_arg=4)
# prints:
# normal arg: 1
# optional arg: 3
# keyword arg: 4
299
function adder(y)
x + y
end
adder
end
add_10 = create_adder(10)
add_10(3) # => 13
####################################################
## 5. Types
####################################################
# type Name
# field::OptionalType
# ...
# end
type Tiger
taillength::Float64
coatcolor # not including a type annotation is the same as `::Any`
end
# The type doubles as the constructor function for values of that type
sherekhan = typeof(tigger)(5.6,"fire") # => Tiger(5.6,"fire")
300
# These struct-style types are called concrete types
# They can be instantiated, but cannot have subtypes.
# The other kind of types is abstract types.
# abstract Name
abstract Cat # just a name and point in the type hierarchy
# Every type has a super type; use the `super` function to get it.
typeof(5) # => Int64
super(Int64) # => Signed
super(Signed) # => Integer
super(Integer) # => Real
super(Real) # => Number
super(Number) # => Any
super(super(Signed)) # => Real
super(Any) # => Any
# All of these type, except for Int64, are abstract.
typeof("fire") # => ASCIIString
super(ASCIIString) # => DirectIndexString
super(DirectIndexString) # => AbstractString
# Likewise here with ASCIIString
301
eye_color
Panther() = new("green")
# Panthers will only have this constructor, and no default constructor.
end
# Using inner constructors, like Panther does, gives you control
# over how values of the type can be created.
# When possible, you should use outer constructors rather than inner ones.
####################################################
## 6. Multiple-Dispatch
####################################################
function meow(animal::Panther)
"grrr"
end
function meow(animal::Tiger)
"rawwwr"
end
302
# this means that the method is picked based on the type of the first argument.
# In Julia, all of the argument types contribute to selecting the best method.
# Let's define a function with more arguments, so we can see the difference
function fight(t::Tiger,c::Cat)
println("The $(t.coatcolor) tiger wins!")
end
# => fight (generic function with 1 method)
# This warning is because it's unclear which fight will be called in:
fight(Lion("RAR"),Lion("brown","rarrr")) # => prints The victorious cat says rarrr
# The result may be different in other versions of Julia
square_area(5) #25
303
# What happens when we feed square_area an integer?
code_native(square_area, (Int32,))
# .section __TEXT,__text,regular,pure_instructions
# Filename: none
# Source line: 1 # Prologue
# push RBP
# mov RBP, RSP
# Source line: 1
# movsxd RAX, EDI # Fetch l from memory?
# imul RAX, RAX # Square l and store the result in RAX
# pop RBP # Restore old base pointer
# ret # Result will still be in RAX
code_native(square_area, (Float32,))
# .section __TEXT,__text,regular,pure_instructions
# Filename: none
# Source line: 1
# push RBP
# mov RBP, RSP
# Source line: 1
# vmulss XMM0, XMM0, XMM0 # Scalar single precision multiply (AVX)
# pop RBP
# ret
code_native(square_area, (Float64,))
# .section __TEXT,__text,regular,pure_instructions
# Filename: none
# Source line: 1
# push RBP
# mov RBP, RSP
# Source line: 1
# vmulsd XMM0, XMM0, XMM0 # Scalar double precision multiply (AVX)
# pop RBP
# ret
#
# Note that julia will use floating point instructions if any of the
# arguments are floats.
# Let's calculate the area of a circle
circle_area(r) = pi * r * r # circle_area (generic function with 1 method)
circle_area(5) # 78.53981633974483
code_native(circle_area, (Int32,))
# .section __TEXT,__text,regular,pure_instructions
# Filename: none
# Source line: 1
# push RBP
# mov RBP, RSP
# Source line: 1
# vcvtsi2sd XMM0, XMM0, EDI # Load integer (r) from memory
# movabs RAX, 4593140240 # Load pi
# vmulsd XMM1, XMM0, QWORD PTR [RAX] # pi * r
# vmulsd XMM0, XMM0, XMM1 # (pi * r) * r
# pop RBP
304
# ret
#
code_native(circle_area, (Float64,))
# .section __TEXT,__text,regular,pure_instructions
# Filename: none
# Source line: 1
# push RBP
# mov RBP, RSP
# movabs RAX, 4593140496
# Source line: 1
# vmulsd XMM1, XMM0, QWORD PTR [RAX]
# vmulsd XMM0, XMM1, XMM0
# pop RBP
# ret
#
Further Reading
You can get a lot more detail from The Julia Manual
The best place to get help with Julia is the (very friendly) mailing list.
Kotlin
Kotlin is a statically typed programming language for the JVM, Android and the browser. It is 100%
interoperable with Java. Read more here.
// Single-line comments start with //
/*
Multi-line comments look like this.
*/
/*
The entry point to a Kotlin program is a function named "main".
The function is passed an array containing any command line arguments.
*/
fun main(args: Array<String>) {
/*
Declaring values is done using either "var" or "val".
"val" declarations cannot be reassigned, whereas "vars" can.
*/
val fooVal = 10 // we cannot later reassign fooVal to something else
var fooVar = 10
fooVar = 20 // fooVar can be reassigned
/*
In most cases, Kotlin can determine what the type of a variable is,
so we don't have to explicitly specify it every time.
We can explicitly declare the type of a variable like so:
305
*/
val foo : Int = 7
/*
Strings can be represented in a similar way as in Java.
Escaping is done with a backslash.
*/
val fooString = "My String Is Here!";
val barString = "Printing on a new line?\nNo Problem!";
val bazString = "Do you want to add a tab?\tNo Problem!";
println(fooString);
println(barString);
println(bazString);
/*
A raw string is delimited by a triple quote (""").
Raw strings can contain newlines and any other characters.
*/
val fooRawString = """
fun helloWorld(val name : String) {
println("Hello, world!")
}
"""
println(fooRawString)
/*
Strings can contain template expressions.
A template expression starts with a dollar sign ($).
*/
val fooTemplateString = "$fooString has ${fooString.length} characters"
println(fooTemplateString)
/*
For a variable to hold null it must be explicitly specified as nullable.
A variable can be specified as nullable by appending a ? to its type.
We can access a nullable variable by using the ?. operator.
We can use the ?: operator to specify an alternative value to use
if a variable is null.
*/
var fooNullable: String? = "abc"
println(fooNullable?.length) // => 3
println(fooNullable?.length ?: -1) // => 3
fooNullable = null
println(fooNullable?.length) // => null
println(fooNullable?.length ?: -1) // => -1
/*
Functions can be declared using the "fun" keyword.
Function arguments are specified in brackets after the function name.
Function arguments can optionally have a default value.
The function return type, if required, is specified after the arguments.
*/
fun hello(name: String = "world") : String {
return "Hello, $name!"
306
}
println(hello("foo")) // => Hello, foo!
println(hello(name = "bar")) // => Hello, bar!
println(hello()) // => Hello, world!
/*
A function parameter may be marked with the "vararg" keyword
to allow a variable number of arguments to be passed to the function.
*/
fun varargExample(vararg names: Int) {
println("Argument has ${names.size} elements")
}
varargExample() // => Argument has 0 elements
varargExample(1) // => Argument has 1 elements
varargExample(1, 2, 3) // => Argument has 3 elements
/*
When a function consists of a single expression then the curly brackets can
be omitted. The body is specified after a = symbol.
*/
fun odd(x: Int): Boolean = x % 2 == 1
println(odd(6)) // => false
println(odd(7)) // => true
// If the return type can be inferred then we don't need to specify it.
fun even(x: Int) = x % 2 == 0
println(even(6)) // => true
println(even(7)) // => false
307
infix fun infixMemberFunction(y: Int) : Int {
return x * y
}
}
/*
To create a new instance we call the constructor.
Note that Kotlin does not have a "new" keyword.
*/
val fooExampleClass = ExampleClass(7)
// Member functions can be called using dot notation.
println(fooExampleClass.memberFunction(4)) // => 11
/*
If a function has been marked with the "infix" keyword then it can be
called using infix notation.
*/
println(fooExampleClass infixMemberFunction 4) // => 28
/*
Data classes are a concise way to create classes that just hold data.
The "hashCode"/"equals" and "toString" methods are automatically generated.
*/
data class DataClassExample (val x: Int, val y: Int, val z: Int)
val fooData = DataClassExample(1, 2, 4)
println(fooData) // => DataClassExample(x=1, y=2, z=4)
/*
We can create a list using the "listOf" function.
The list will be immutable - elements cannot be added or removed.
*/
val fooList = listOf("a", "b", "c")
println(fooList.size) // => 3
println(fooList.first()) // => a
println(fooList.last()) // => c
// Elements of a list can be accessed by their index.
println(fooList[1]) // => b
308
// A mutable list can be created using the "mutableListOf" function.
val fooMutableList = mutableListOf("a", "b", "c")
fooMutableList.add("d")
println(fooMutableList.last()) // => d
println(fooMutableList.size) // => 4
/*
Sequences represent lazily-evaluated collections.
We can create a sequence using the "generateSequence" function.
*/
val fooSequence = generateSequence(1, {it + 1})
val x = fooSequence.take(10).toList()
println(x) // => [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
return generateSequence(::next)
}
val y = fibonacciSequence().take(10).toList()
println(y) // => [1, 1, 2, 3, 5, 8, 13, 21, 34, 55]
309
var ctr = 0
while (ctr < 5) {
println(ctr)
ctr++
}
do {
println(ctr)
ctr++
} while (ctr < 10)
/*
We can check if an object is 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.
*/
fun smartCastExample(x: Any) : Boolean {
if (x is Boolean) {
// x is automatically cast to Boolean
return x
} else if (x is Int) {
// x is automatically cast to Int
return x > 0
} else if (x is String) {
// x is automatically cast to String
return x.isNotEmpty()
} else {
return false
}
}
println(smartCastExample("Hello, world!")) // => true
println(smartCastExample("")) // => false
310
println(smartCastExample(5)) // => true
println(smartCastExample(0)) // => false
println(smartCastExample(true)) // => true
/*
Extensions are a way to add new functionality to a class.
This is similar to C# extension methods.
*/
fun String.remove(c: Char): String {
return this.filter {it != c}
}
println("Hello, world!".remove('l')) // => Heo, word!
println(EnumExample.A) // => A
println(ObjectExample.hello()) // => hello
}
/*
The "object" keyword can be used to create singleton objects.
We cannot assign it to a variable, but we can refer to it by its name.
This is similar to Scala singleton objects.
*/
object ObjectExample {
fun hello() : String {
return "hello"
}
}
Further Reading
• Kotlin tutorials
• Try Kotlin in your browser
• A list of Kotlin resources
Less
Less is a CSS pre-processor, that adds features such as variables, nesting, mixins and more. Less (and other
preprocessors, such as Sass help developers to write maintainable and DRY (Don’t Repeat Yourself) code.
/*Variables
==============================*/
311
/* You can store a CSS value (such as a color) in a variable.
Use the '@' symbol to create a variable. */
@primary-color: #A3A4FF;
@secondary-color: #51527F;
@body-font: 'Roboto', sans-serif;
body {
background-color: @primary-color;
color: @secondary-color;
font-family: @body-font;
}
/*Mixins
==============================*/
/* If you find you are writing the same code for more than one
element, you might want to reuse that easily.*/
.center {
display: block;
margin-left: auto;
margin-right: auto;
left: 0;
right: 0;
}
/* You can use the mixin by simply adding the selector as a style */
div {
.center;
background-color: @primary-color;
}
312
/*Which would compile to: */
.center {
display: block;
margin-left: auto;
margin-right: auto;
left: 0;
right: 0;
}
div {
display: block;
margin-left: auto;
margin-right: auto;
left: 0;
right: 0;
background-color: #A3A4FF;
}
/* You can omit the mixin code from being compiled by adding parenthesis
after the selector */
.center() {
display: block;
margin-left: auto;
margin-right: auto;
left: 0;
right: 0;
}
div {
.center;
background-color: @primary-color;
}
/*Functions
==============================*/
313
body {
width: round(10.25px);
}
.footer {
background-color: fadeout(#000000, 0.25)
}
/* Compiles to: */
body {
width: 10px;
}
.footer {
background-color: rgba(0, 0, 0, 0.75);
}
/* You may also define your own functions. Functions are very similar to
mixins. When trying to choose between a function or a mixin, remember
that mixins are best for generating CSS while functions are better for
logic that might be used throughout your Less code. The examples in
the Math Operators' section are ideal candidates for becoming a reusable
function. */
/* This function will take a target size and the parent size and calculate
and return the percentage */
.average(@x, @y) {
@average_result: ((@x + @y) / 2);
}
div {
.average(16px, 50px); // "call" the mixin
padding: @average_result; // use its "return" value
}
/* Compiles to: */
div {
padding: 33px;
}
/*Extend (Inheritance)
==============================*/
.display {
height: 50px;
}
314
.display-success {
&:extend(.display);
border-color: #22df56;
}
/* Compiles to: */
.display,
.display-success {
height: 50px;
}
.display-success {
border-color: #22df56;
}
/*Nesting
==============================*/
ul {
list-style-type: none;
margin-top: 2em;
li {
background-color: #FF0000;
}
}
ul {
list-style-type: none;
margin-top: 2em;
li {
background-color: red;
&:hover {
background-color: blue;
315
}
a {
color: white;
}
}
}
/* Compiles to: */
ul {
list-style-type: none;
margin-top: 2em;
}
ul li {
background-color: red;
}
ul li:hover {
background-color: blue;
}
ul li a {
color: white;
}
/* Less allows you to create partial files. This can help keep your Less
code modularized. Partial files conventionally begin with an '_',
e.g. _reset.less. and are imported into a main less file that gets
compiled into CSS */
/* Consider the following CSS which we'll put in a file called _reset.less */
html,
body,
ul,
ol {
margin: 0;
padding: 0;
}
/* Less offers @import which can be used to import partials into a file.
This differs from the traditional CSS @import statement which makes
another HTTP request to fetch the imported file. Less takes the
imported file and combines it with the compiled code. */
316
@import 'reset';
body {
font-size: 16px;
font-family: Helvetica, Arial, Sans-serif;
}
/* Compiles to: */
body {
font-size: 16px;
font-family: Helvetica, Arial, Sans-serif;
}
/*Math Operations
==============================*/
@content-area: 960px;
@main-content: 600px;
@sidebar-content: 300px;
body {
width: 100%;
}
.main-content {
width: @main-size;
}
.sidebar {
width: @sidebar-size;
}
.gutter {
width: @gutter;
}
317
/* Compiles to: */
body {
width: 100%;
}
.main-content {
width: 62.5%;
}
.sidebar {
width: 31.25%;
}
.gutter {
width: 6.25%;
}
Practice Less
If you want to play with Less in your browser, check out LESS2CSS.
Compatibility
Less can be used in any project as long as you have a program to compile it into CSS. You’ll want to verify
that the CSS you’re using is compatible with your target browsers.
QuirksMode CSS and CanIUse are great resources for checking compatibility.
Further reading
• Official Documentation
Livescript
LiveScript is a functional compile-to-JavaScript language which shares most of the underlying semantics with
its host language. Nice additions comes with currying, function composition, pattern matching and lots of
other goodies heavily borrowed from languages like Haskell, F# and Scala.
LiveScript is a fork of Coco, which is itself a fork of CoffeeScript. The language is stable, and a new version
is in active development to bring a plethora of new niceties!
Feedback is always welcome, so feel free to reach me over at [@kurisuwhyte](https://twitter.com/kurisuwhyte)
:)
# Just like its CoffeeScript cousin, LiveScript uses number symbols for
# single-line comments.
/*
Multi-line comments are written C-style. Use them if you want comments
to be preserved in the JavaScript output.
*/
318
# As far as syntax goes, LiveScript uses indentation to delimit blocks,
# rather than curly braces, and whitespace to apply functions, rather
# than parenthesis.
########################################################################
## 1. Basic values
########################################################################
# Then you get numbers. These are double-precision floats like in JS.
10
0.4 # Note that the leading `0` is required
319
fruits = [ \apple, \orange, \pear ]
########################################################################
## 2. Basic operations
########################################################################
# Comparisons are mostly the same too, except that `==` is the same as
# JS's `===`, where JS's `==` in LiveScript is `~=`, and `===` enables
# object and array comparisons, and also stricter comparisons:
2 == 2 # => true
2 == "2" # => false
320
2 ~= "2" # => true
2 === "2" # => false
+0 == -0 # => true
+0 === -0 # => false
########################################################################
## 3. Functions
########################################################################
# LiveScript uses function scope, just like JavaScript, and has proper
# closures too. Unlike JavaScript, the `=` works as a declaration
# operator, and will always declare the variable on the left hand side.
321
foo! # => 3
# Operators are not functions in LiveScript, but you can easily turn
# them into one! Enter the operator sectioning:
divide-by-two = (/ 2)
[2, 4, 8, 16].map(divide-by-two) .reduce (+)
# Other than the usual `f . g` mathematical formulae, you get the `>>`
# and `<<` operators, that describe how the flow of values through the
# functions.
double-minus-one = (* 2) >> (- 1)
double-minus-one = (- 1) << (* 2)
# And talking about flow of value, LiveScript gets the `|>` and `<|`
# operators that apply a value to a function:
map = (f, xs) --> xs.map f
[1 2 3] |> map (* 2) # => [2 4 6]
# You can also choose where you want the value to be placed, just mark
# the place with an underscore (_):
reduce = (f, xs, initial) --> xs.reduce f, initial
[1 2 3] |> reduce (+), _, 0 # => 6
322
div-by-two = div _, 2
div-by-two 4 # => 2
# Last, but not least, LiveScript has back-calls, which might help
# with some callback-based code (though you should try more functional
# approaches, like Promises):
readFile = (name, f) -> f name
a <- readFile 'foo'
b <- readFile 'bar'
console.log a + b
# Same as:
readFile 'foo', (a) -> readFile 'bar', (b) -> console.log a + b
########################################################################
## 4. Patterns, guards and control-flow
########################################################################
########################################################################
## 5. Comprehensions
########################################################################
# While the functional helpers for dealing with lists and objects are
# right there in the JavaScript's standard library (and complemented on
# the prelude-ls, which is a "standard library" for LiveScript),
# comprehensions will usually allow you to do this stuff faster and with
# a nice syntax:
oneToTwenty = [1 to 20]
evens = [x for x in oneToTwenty when x % 2 == 0]
323
# `when` and `unless` can be used as filters in the comprehension.
# Object comprehension works in the same way, except that it gives you
# back an object rather than an Array:
copy = { [k, v] for k, v of source }
########################################################################
## 4. OOP
########################################################################
Further reading
There’s just so much more to LiveScript, but this should be enough to get you started writing little functional
things in it. The official website has a lot of information on the language, and a nice online compiler for you
to try stuff out!
You may also want to grab yourself some prelude.ls, and check out the #livescript channel on the Freenode
network.
Lua
-- Two dashes start a one-line comment.
--[[
324
Adding two ['s and ]'s makes it a
multi-line comment.
--]]
--------------------------------------------------------------------------------
-- 1. Variables and flow control.
--------------------------------------------------------------------------------
-- If clauses:
if num > 40 then
print('over 40')
elseif s ~= 'walternate' then -- ~= is not equals.
-- Equality check is == like Python; ok for strs.
io.write('not over 40\n') -- Defaults to stdout.
else
-- Variables are global by default.
thisIsGlobal = 5 -- Camel case is common.
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:
ans = aBoolValue and 'yes' or 'no' --> 'no'
karlSum = 0
325
for i = 1, 100 do -- The range includes both ends.
karlSum = karlSum + i
end
--------------------------------------------------------------------------------
-- 2. Functions.
--------------------------------------------------------------------------------
function fib(n)
if n < 2 then return n end
return fib(n - 2) + fib(n - 1)
end
-- 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.
function bar(a, b, c)
print(a, b, c)
return 4, 8, 15, 16, 23, 42
end
326
-- 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.
-- 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.
-- 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.
327
-- _G is a special table of all globals.
print(_G['_G'] == _G) -- Prints 'true'.
--------------------------------------------------------------------------------
-- 3.1 Metatables and metamethods.
--------------------------------------------------------------------------------
metafraction = {}
function metafraction.__add(f1, f2)
local sum = {}
sum.b = f1.b * f2.b
sum.a = f1.a * f2.b + f2.a * f1.b
return sum
end
setmetatable(f1, metafraction)
setmetatable(f2, metafraction)
-- 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.
328
--------------------------------------------------------------------------------
-- Direct table lookups that fail will retry using the metatable's __index
-- value, and this recurses.
-- __add(a, b) for a + b
-- __sub(a, b) for a - b
-- __mul(a, b) for a * b
-- __div(a, b) for a / b
-- __mod(a, b) for a % b
-- __pow(a, b) for a ^ b
-- __unm(a) for -a
-- __concat(a, b) for a .. b
-- __len(a) for #a
-- __eq(a, b) for a == b
-- __lt(a, b) for a < b
-- __le(a, b) for a <= b
-- __index(a, b) <fn or a table> for a.b
-- __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.
Dog = {} -- 1.
function Dog:new() -- 2.
local newObj = {sound = 'woof'} -- 3.
self.__index = self -- 4.
return setmetatable(newObj, self) -- 5.
end
function Dog:makeSound() -- 6.
print('I say ' .. self.sound)
end
mrDog = Dog:new() -- 7.
mrDog:makeSound() -- 'I say woof' -- 8.
329
-- 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.
-- 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.
-- 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.
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
-- 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. Modules.
--------------------------------------------------------------------------------
--[[ I'm commenting out this section so the rest of this script remains
-- runnable.
-- Suppose the file mod.lua looks like this:
local M = {}
330
local function sayMyName()
print('Hrunkner')
end
function M.sayHello()
print('Why hello there')
sayMyName()
end
return M
-- require's return values are cached so a file is run at most once, even when
-- require'd many times.
--]]
References
I was excited to learn Lua so I could make games with the Love 2D game engine. That’s the why.
I started with BlackBulletIV’s Lua for programmers. Next I read the official Programming in Lua book.
That’s the how.
331
It might be helpful to check out the Lua short reference on lua-users.org.
The main topics not covered are standard libraries:
• string library
• table library
• math library
• io library
• os library
By the way, the entire file is valid Lua; save it as learn.lua and run it with “lua learn.lua” !
This was first written for tylerneylon.com, and is also available as a github gist. Have fun with Lua!
Make
A Makefile defines a graph of rules for creating a target (or targets). Its purpose is to do the minimum
amount of work needed to update a target to the most recent version of the source. Famously written over
a weekend by Stuart Feldman in 1976, it is still widely used (particularly on Unix and Linux) despite many
competitors and criticisms.
There are many varieties of make in existence, however this article assumes that we are using GNU make
which is the standard on Linux.
# File should be named Makefile and then can be run as `make <target>`.
# Otherwise we use `make -f "filename" <target>`.
#-----------------------------------------------------------------------
# Basics
#-----------------------------------------------------------------------
332
# A rule can have multiple targets and multiple prerequisites
file2.txt file3.txt: file0.txt file1.txt
touch file2.txt
touch file3.txt
# Make will complain about multiple recipes for the same rule. Empty
# recipes don't count though and can be used to add new dependencies.
#-----------------------------------------------------------------------
# Phony Targets
#-----------------------------------------------------------------------
# Can avoid phony rules breaking when a real file has the same name by
.PHONY: all maker process
# This is a special target. There are several others.
#-----------------------------------------------------------------------
# Automatic Variables & Wildcards
#-----------------------------------------------------------------------
#-----------------------------------------------------------------------
# Patterns
#-----------------------------------------------------------------------
# Can teach make how to convert certain files into other files.
%.png: %.svg
inkscape --export-png $^
333
# Pattern rules will only do anything if make decides to create the
# target.
# Directory paths are normally ignored when matching pattern rules. But
# make will try to use the most appropriate rule available.
small/%.png: %.svg
inkscape --export-png --export-dpi 30 $^
# make will use the last version for a pattern rule that it finds.
%.png: %.svg
@echo this rule is chosen
# However make will use the first pattern rule that can make the target
%.png: %.ps
@echo this rule is not chosen if *.svg and *.ps are both present
# make already has some pattern rules built-in. For instance, it knows
# how to turn *.c files into *.o files.
#-----------------------------------------------------------------------
# Variables
#-----------------------------------------------------------------------
# aka. macros
name = Ted
name2="Sarah"
echo:
@echo $(name)
@echo ${name2}
@echo $name # This won't work, treated as $(n)ame.
@echo $(name3) # Unknown variables are treated as empty strings.
name4 ?= Jean
# Only set the variable if environment variable is not already defined.
334
# Stops commandline arguments from changing this variable.
name4 +=grey
# Append values to variable (includes a space).
#-----------------------------------------------------------------------
# Variables 2
#-----------------------------------------------------------------------
# The first type of variables are evaluated each time they are used.
# This can be expensive, so a second type of variable exists which is
# only evaluated once. (This is a GNU make extension)
var := hello
var2 ::= $(var) hello
#:= and ::= are equivalent.
# These variables are evaluated procedurally (in the order that they
# appear), thus breaking with the rest of the language !
#-----------------------------------------------------------------------
# Functions
#-----------------------------------------------------------------------
# Some examples
ls: * src/*
@echo $(filter %.txt, $^)
335
@echo $(notdir $^)
@echo $(join $(dir $^),$(notdir $^))
#-----------------------------------------------------------------------
# Directives
#-----------------------------------------------------------------------
sport = tennis
# Conditional compilation
report:
ifeq ($(sport),tennis)
@echo 'game, set, match'
else
@echo "They think it's all over; it is now"
endif
foo = true
ifdef $(foo)
bar = 'hello'
endif
More Resources
Matlab
MATLAB stands for MATrix LABoratory. It is a powerful numerical computing language commonly used
in engineering and mathematics.
If you have any feedback please feel free to reach me at [@the_ozzinator](https://twitter.com/the_ozzinator),
or [email protected].
%% Code sections start with two percent signs. Section titles go on the same line.
% Comments start with a percent sign.
%{
Multi line comments look
something
like
this
%}
336
% either clicking the "Run Section" button
% or using Ctrl+Shift+Enter (Windows) or Cmd+Shift+Return (OS X)
%% Code sections are also known as code cells or cell mode (not to be confused with cell arrays)
% Output formatting
format short % 4 decimals in a floating number
format long % 15 decimals
format bank % only two digits after decimal point - for financial calculations
fprintf('text') % print "text" to the screen
disp('text') % print "text" to the screen
337
myVariable = 4; % Semi colon suppresses output to the Command Window
4 + 6 % ans = 10
8 * myVariable % ans = 32
2 ^ 3 % ans = 8
a = 2; b = 3;
c = exp(a)*sin(pi/2) % c = 7.3891
% Logicals
1 > 5 % ans = 0
10 >= 10 % ans = 1
3 ~= 4 % Not equal to -> ans = 1
3 == 3 % equal to -> ans = 1
3 > 1 && 4 > 1 % AND -> ans = 1
3 > 1 || 4 > 1 % OR -> ans = 1
~1 % NOT -> ans = 0
% Strings
a = 'MyString'
length(a) % ans = 8
a(2) % ans = y
[a,a] % ans = MyStringMyString
% Cells
a = {'one', 'two', 'three'}
a(1) % ans = 'one' - returns a cell
char(a(1)) % ans = one - returns a string
% Structures
A.b = {'one','two'};
A.c = [1 2];
A.d.e = false;
% Vectors
x = [4 32 53 7 1]
x(2) % ans = 32, indices in Matlab start 1, not 0
338
x(2:3) % ans = 32 53
x(2:end) % ans = 32 53 7 1
x = [1:10] % x = 1 2 3 4 5 6 7 8 9 10
x = [1:2:10] % Increment by 2, i.e. x = 1 3 5 7 9
% Matrices
A = [1 2 3; 4 5 6; 7 8 9]
% Rows are separated by a semicolon; elements are separated with space or comma
% A =
% 1 2 3
% 4 5 6
% 7 8 9
% 1 2 3
% 4 5 42
% 7 8 9
% 5 42
% 8 9
% 1
% 4
% 7
% 1 2 3
% 1 2 3
% 4 5 42
% 7 8 9
% 1 2 3
339
% 4 5 42
% 7 8 9
%ans =
% 1 2 3 1 2 3
% 4 5 42 4 5 42
% 7 8 9 7 8 9
% 3 1 2
% 42 4 5
% 9 7 8
size(A) % ans = 3 3
% There are several pairs of functions, where one acts on each element, and
% the other (whose name ends in m) acts on the whole matrix.
exp(A) % exponentiate each element
expm(A) % calculate the matrix exponential
sqrt(A) % take the square root of each element
sqrtm(A) % find the matrix whose square is A
340
% Plotting
x = 0:.10:2*pi; % Creates a vector that starts at 0 and ends at 2*pi with increments of .1
y = sin(x);
plot(x,y)
xlabel('x axis')
ylabel('y axis')
title('Plot of y = sin(x)')
axis([0 2*pi -1 1]) % x range from 0 to 2*pi, y range from -1 to 1
fplot (@(x) x^2, [2,5]) % plot the function x^2 from x=2 to x=5
z = sin(x);
plot3(x,y,z); % 3D line plot
shg % bring an existing graphics window forward, or create new one if needed
clf clear % clear current figure window, and reset most figure properties
341
h = plot(x, y); % you can save a handle to a figure when you create it
set(h, 'Color', 'r')
% 'y' yellow; 'm' magenta, 'c' cyan, 'r' red, 'g' green, 'b' blue, 'w' white, 'k' black
set(h, 'LineStyle', '--')
% '--' is solid line, '---' dashed, ':' dotted, '-.' dash-dot, 'none' is no line
get(h, 'LineStyle')
% The function gca returns a handle to the axes for the current figure
set(gca, 'XDir', 'reverse'); % reverse the direction of the x-axis
% To create a figure that contains several axes in tiled positions, use subplot
subplot(2,3,1); % select the first position in a 2-by-3 grid of subplots
plot(x1); title('First Plot') % plot something in this position
subplot(2,3,2); % select second position in the grid
plot(x2); title('Second Plot') % plot something there
% M-file Scripts
% A script file is an external file that contains a sequence of statements.
% They let you avoid repeatedly typing the same code in the Command Window
% Have .m extensions
% M-file Functions
% Like scripts, and have the same .m extension
% But can accept input arguments and return an output
% Also, they have their own workspace (ie. different variable scope).
% Function name should match file name (so save this example as double_input.m).
% 'help double_input.m' returns the comments under line beginning function
function output = double_input(x)
%double_input(x) returns twice the value of x
output = 2*x;
end
double_input(6) % ans = 12
% If you want to create a function without creating a new file you can use an
% anonymous function. Useful when quickly defining a function to pass to
342
% another function (eg. plot with fplot, evaluate an indefinite integral
% with quad, find roots with fzero, or find minimum with fminsearch).
% Example that returns the square of it's input, assigned to the handle sqr:
sqr = @(x) x.^2;
sqr(10) % ans = 100
doc function_handle % find out more
% User input
a = input('Enter the value: ')
% Stops execution of file and gives control to the keyboard: user can examine
% or change variables. Type 'return' to continue execution, or 'dbquit' to exit
keyboard
% Output
disp(a) % Print out the value of variable a
disp('Hello World') % Print out a string
fprintf % Print to Command Window with more control
% Looping
% NB. looping over elements of a vector/matrix is slow!
% Where possible, use functions that act on whole vector/matrix at once
for k = 1:5
disp(k)
end
k = 0;
while (k < 5)
k = k + 1;
end
% Timing code execution: 'toc' prints the time since 'tic' was called
tic
A = rand(1000);
A*A*A*A*A*A*A;
toc
343
dburl = ['jdbc:mysql://localhost:8889/' dbname];
javaclasspath('mysql-connector-java-5.1.xx-bin.jar'); %xx depends on version, download available at http
conn = database(dbname, username, password, driver, dburl);
sql = ['SELECT * from table_name where id = 22'] % Example sql statement
a = fetch(conn, sql) %a will contain your data
% Common constants
pi
NaN
inf
344
diag(x) % Construct a matrix with diagonal elements listed in x, and zeroes elsewhere
eye(m,n) % Identity matrix
linspace(x1, x2, n) % Return n equally spaced points, with min x1 and max x2
inv(A) % Inverse of matrix A
det(A) % Determinant of A
eig(A) % Eigenvalues and eigenvectors of A
trace(A) % Trace of matrix - equivalent to sum(diag(A))
isempty(A) % Tests if array is empty
all(A) % Tests if all elements are nonzero or true
any(A) % Tests if any elements are nonzero or true
isequal(A, B) % Tests equality of two arrays
numel(A) % Number of elements in matrix
triu(x) % Returns the upper triangular part of x
tril(x) % Returns the lower triangular part of x
cross(A,B) % Returns the cross product of the vectors A and B
dot(A,B) % Returns scalar product of two vectors (must have the same length)
transpose(A) % Returns the transpose of A
fliplr(A) % Flip matrix left to right
flipud(A) % Flip matrix up to down
% Matrix Factorisations
[L, U, P] = lu(A) % LU decomposition: PA = LU,L is lower triangular, U is upper triangular, P is permuta
[P, D] = eig(A) % eigen-decomposition: AP = PD, P's columns are eigenvectors and D's diagonals are eigen
[U,S,V] = svd(X) % SVD: XV = US, U and V are unitary matrices, S has non-negative diagonal elements in d
% Classes
% Matlab can support object-oriented programming.
% Classes must be put in a file of the class name with a .m extension.
% To begin, we create a simple class to store GPS waypoints.
% Begin WaypointClass.m
classdef WaypointClass % The class name.
properties % The properties of the class behave like Structures
latitude
longitude
end
methods
% This method that has the same name of the class is the constructor.
345
function obj = WaypointClass(lat, lon)
obj.latitude = lat;
obj.longitude = lon;
end
% The method can also be called using dot notation. In this case, the object
% does not need to be passed to the method.
ans = a.multiplyLatBy(a,1/3)
More on Matlab
• The official website http://http://www.mathworks.com/products/matlab/
• The official MATLAB Answers forum: http://www.mathworks.com/matlabcentral/answers/
Neat
Neat is basically a smaller version of D1 with some experimental syntax and a focus on terseness without
losing the basic C-like syntax.
Read more here.
346
// single line comments start with //
/*
multiline comments look like this
*/
/+
or this
/+ these can be nested too, same as D +/
+/
// Global functions!
void foo() { }
/*
byte: 8 bit signed integer
char: 8 bit UTF-8 byte component.
short: 16 bit signed integer
int: 32 bit signed integer
long: 64 bit signed integer
347
b = b && false;
assert(b == false);
// "" are "format strings". So $variable will be substituted at runtime
// with a formatted version of the variable.
writeln "$a";
// This will just print $a.
writeln `$a`;
// you can format expressions with $()
writeln "$(2+2)";
// Note: there is no special syntax for characters.
char c = "a";
// Cast values by using type: expression.
// There are three kinds of casts:
// casts that just specify conversions that would be happening automatically
// (implicit casts)
float f = float:5;
float f2 = 5; // would also work
// casts that require throwing away information or complicated computation -
// those must always be done explicitly
// (conversion casts)
int i = int:f;
// int i = f; // would not work!
// and, as a last attempt, casts that just reinterpret the raw data.
// Those only work if the types have the same size.
string s = "Hello World";
// Arrays are (length, pointer) pairs.
// This is a tuple type. Tuple types are (type, type, type).
// The type of a tuple expression is a tuple type. (duh)
(int, char*) array = (int, char*): s;
// You can index arrays and tuples using the expression[index] syntax.
writeln "pointer is $(array[1]) and length is $(array[0])";
// You can slice them using the expression[from .. to] syntax.
// Slicing an array makes another array.
writeln "$(s[0..5]) World";
// Alias name = expression gives the expression a name.
// As opposed to a variable, aliases do not have an address
// and can not be assigned to. (Unless the expression is assignable)
alias range = 0 .. 5;
writeln "$(s[range]) World";
// You can iterate over ranges.
for int i <- range {
write "$(s[i])";
}
writeln " World";
// Note that if "range" had been a variable, it would be 'empty' now!
// Range variables can only be iterated once.
// The syntax for iteration is "expression <- iterable".
// Lots of things are iterable.
for char c <- "Hello" { write "$c"; }
writeln " World";
// For loops are "for test statement";
alias test = char d <- "Hello";
for test write "$d";
writeln " World\t\x05"; // note: escapes work
348
// Pointers: function the same as in C, btw. The usual.
// Do note: the pointer star sticks with the TYPE, not the VARIABLE!
string* p;
assert(p == null); // default initializer
p = &s;
writeln "$(*p)";
// Math operators are (almost) standard.
int x = 2 + 3 * 4 << 5;
// Note: XOR is "xor". ^ is reserved for exponentiation (once I implement that).
int y = 3 xor 5;
int z = 5;
assert(z++ == 5);
assert(++z == 7);
writeln "x $x y $y z $z";
// As in D, ~ concatenates.
string hewo = "Hello " ~ "World";
// == tests for equality, "is" tests for identity.
assert (hewo == s);
assert !(hewo is s);
// same as
assert (hewo !is s);
// Scope variables are automatically freed at the end of the current scope.
scope int[auto~] someOtherAppender;
// This is the same as:
int[auto~] someOtherAppender2;
onExit { someOtherAppender2.free; }
349
do {
int i = 5;
} while (i == 5) {
assert(i == 5);
break; // otherwise we'd go back up to do {
}
350
// you can use \ too.
auto add5 = \(int a) -> new \(int b) -> a + b;
// Note!
auto nestfun = �() { } // There is NO semicolon needed here!
// "}" can always substitute for "};".
// This provides syntactic consistency with built-in statements.
// This is a class.
// Note: almost all elements of Neat can be used on the module level
// or just as well inside a function.
class C {
int a;
void writeA() { writeln "$a"; }
// It's a nested class - it exists in the context of main().
// so if you leave main(), any instances of C become invalid.
void writeS() { writeln "$s"; }
}
C cc = new C;
// cc is a *reference* to C. Classes are always references.
cc.a = 5; // Always used for property access.
auto ccp = &cc;
(*ccp).a = 6;
// or just
ccp.a = 7;
cc.writeA();
cc.writeS(); // to prove I'm not making things up
// Interfaces work same as in D, basically. Or Java.
interface E { void doE(); }
// Inheritance works same as in D, basically. Or Java.
class D : C, E {
override void writeA() { writeln "hahahahaha no"; }
override void doE() { writeln "eeeee"; }
// all classes inherit from Object. (toString is defined in Object)
override string toString() { return "I am a D"; }
}
C cd = new D;
// all methods are always virtual.
cd.writeA();
E e = E:cd; // dynamic class cast!
e.doE();
writeln "$e"; // all interfaces convert to Object implicitly.
// Templates!
// Templates are parameterized namespaces, taking a type as a parameter.
template Templ(T) {
alias hi = 5, hii = 8;
// Templates always have to include something with the same name as the template
// - this will become the template's _value_.
// Static ifs are evaluated statically, at compile-time.
// Because of this, the test has to be a constant expression,
// or something that can be optimized to a constant.
static if (types-equal (T, int)) {
alias Templ = hi;
351
} else {
alias Templ = hii;
}
}
assert(Templ!int == 5);
assert(Templ!float == 8);
}
Nim
Nim (formerly Nimrod) is a statically typed, imperative programming language that gives the programmer
power without compromises on runtime efficiency.
Nim is efficient, expressive, and elegant.
var # Declare (and assign) variables,
letter: char = 'n' # with or without type annotations
lang = "N" & "im"
nLength : int = len(lang)
boat: float
truth: bool = false
discard 1 > 2 # Note: The compiler will complain if the result of an expression
# is unused. `discard` bypasses this.
discard """
This can work as a multiline comment.
Or for unparsable, broken code
"""
#
# Data Structures
#
352
# Tuples
var
child: tuple[name: string, age: int] # Tuples have *both* field names
today: tuple[sun: string, temp: float] # *and* order.
# Sequences
var
drinks: seq[string]
drinks.add("Milk")
if "Milk" in drinks:
echo "We have Milk and ", drinks.len - 1, " other drinks"
#
# Defining Types
#
# Defining your own types puts the compiler to work for you. It's what makes
# static typing powerful and useful.
type
Name = string # A type alias gives you a new type that is interchangable
Age = int # with the old type but is more descriptive.
Person = tuple[name: Name, age: Age] # Define data structures too.
AnotherSyntax = tuple
fieldOne: string
secondField: int
var
john: Person = (name: "John B.", age: 17)
newage: int = 18 # It would be better to use Age than int
john.age = newage # But still works because int and Age are synonyms
type
Cash = distinct int # `distinct` makes a new type incompatible with its
Desc = distinct string # base type.
var
money: Cash = 100.Cash # `.Cash` converts the int to our type
description: Desc = "Interesting".Desc
353
when compileBadCode:
john.age = money # Error! age is of type int and money is Cash
john.name = description # Compiler says: "No way!"
#
# More Types and Data Structures
#
type
Color = enum cRed, cBlue, cGreen
Direction = enum # Alternative formating
dNorth
dWest
dEast
dSouth
var
orient = dNorth # `orient` is of type Direction, with the value `dNorth`
pixel = cGreen # `pixel` is of type Color, with the value `cGreen`
type
DieFaces = range[1..20] # Only an int from 1 to 20 is a valid value
var
my_roll: DieFaces = 13
when compileBadCode:
my_roll = 23 # Error!
# Arrays
type
RollCounter = array[DieFaces, int] # Array's are fixed length and
DirNames = array[Direction, string] # indexed by any ordinal type.
Truths = array[42..44, bool]
var
counter: RollCounter
directions: DirNames
possible: Truths
possible = [false, false, false] # Literal arrays are created with [V1,..,Vn]
possible[42] = true
my_roll = 13
counter[my_roll] += 1
counter[my_roll] += 1
354
var anotherArray = ["Default index", "starts at", "0"]
# More data structures are available, including tables, sets, lists, queues,
# and crit bit trees.
# http://nim-lang.org/docs/lib.html#collections-and-algorithms
#
# IO and Control Flow
#
# `case`, `readLine()`
#
# Iteration
#
for i, elem in ["Yes", "No", "Maybe so"]: # Or just `for elem in`
echo(elem, " is at index: ", i)
355
an <example>
`string` to
play with
""" # Multiline raw string
for i, c in myString: # Index and letter. Or `for j in` for just letter
if i mod 2 == 0: continue # Compact `if` form
elif c == 'X': break
else: echo(c)
#
# Procedures
#
#
# FFI
#
356
Further Reading
• Home Page
• Download
• Community
• FAQ
• Documentation
• Manual
• Standard Library
• Rosetta Code
Nix
Nix is a simple functional language developed for the Nix package manager and NixOS.
You can evaluate Nix expressions using nix-instantiate or nix-repl.
with builtins; [
# Comments
#=========================================
/* Multi-line comments
look like this. */
# Booleans
#=========================================
(true || false) # Or
#=> true
# Integers
#=========================================
(4 + 6 + 12 - 2) # Addition
#=> 20
(7 / 2) # Division
#=> 3
357
# Strings
#=========================================
"
String literals can span
multiple lines.
"
''
This is called an "indented string" literal.
It intelligently strips leading whitespace.
''
''
a
b
''
#=> "a\n b"
# Paths
#=========================================
# Imports
358
#=========================================
# Let
#=========================================
# Bindings can refer to each other, and their order does not matter.
(let y = x + "b";
x = "a"; in
y + "c")
#=> "abc"
# Functions
#=========================================
359
# Multiple arguments can be achieved with currying.
((x: y: x + "-" + y) "a" "b")
#=> "a-b"
# Lists
#=========================================
(length [1 2 3 "x"])
#=> 4
([1 2 3] ++ [4 5])
#=> [1 2 3 4 5]
(head [1 2 3])
#=> 1
(tail [1 2 3])
#=> [2 3]
(elem 2 [1 2 3])
#=> true
(elem 5 [1 2 3])
#=> false
# Sets
#=========================================
360
({ a = 1; b = 2; } // { a = 3; c = 4; })
#=> { a = 3; b = 2; c = 4; }
# With
#=========================================
# Set patterns
#=========================================
361
(args: args.x + "-" + args.y) { x = "a"; y = "b"; }
#=> "a-b"
# Errors
#=========================================
# Impurity
#=========================================
362
# The trace function is used for debugging. It prints the first
# argument to stderr and evaluates to the second argument.
(trace 1 2)
#=> trace: 1
#=> 2
# You can write files into the Nix store. Although impure, this is
# fairly safe because the file name is derived from the hash of
# its contents. You can read files from anywhere. In this example,
# we write a file into the store, and then read it back out.
(let filename = toFile "foo.txt" "hello!"; in
[filename (builtins.readFile filename)])
#=> [ "/nix/store/ayh05aay2anx135prqp0cy34h891247x-foo.txt" "hello!" ]
Further Reading
Objective-C
Objective-C is the main programming language used by Apple for the OS X and iOS operating systems and
their respective frameworks, Cocoa and Cocoa Touch. It is a general-purpose, object-oriented programming
language that adds Smalltalk-style messaging to the C programming language.
// Single-line comments start with //
/*
Multi-line comments look like this
*/
// XCode supports pragma mark directive that improve jump bar readability
#pragma mark Navigation Functions // New tag on jump bar named 'Navigation Functions'
#pragma mark - Navigation Functions // Same tag, now with a separator
// If you enable modules for iOS >= 7.0 or OS X >= 10.9 projects in
// Xcode 5 you can import frameworks like that:
@import Foundation;
363
// Your program's entry point is a function called
// main with an integer return type
int main (int argc, const char * argv[])
{
// Create an autorelease pool to manage the memory into the program
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
// If using automatic reference counting (ARC), use @autoreleasepool instead:
@autoreleasepool {
///////////////////////////////////////
// Types & Variables
///////////////////////////////////////
// Primitive declarations
int myPrimitive1 = 1;
long myPrimitive2 = 234554664565;
// Object declarations
// Put the * in front of the variable names for strongly-typed object declarations
MyClass *myObject1 = nil; // Strong typing
id myObject2 = nil; // Weak typing
// %@ is an object
// 'description' is a convention to display the value of the Objects
NSLog(@"%@ and %@", myObject1, [myObject2 description]); // prints => "(null) and (null)"
// String
NSString *worldString = @"World";
NSLog(@"Hello %@!", worldString); // prints => "Hello World!"
// NSMutableString is a mutable version of the NSString object
NSMutableString *mutableString = [NSMutableString stringWithString:@"Hello"];
[mutableString appendString:@" World!"];
NSLog(@"%@", mutableString); // prints => "Hello World!"
// Character literals
NSNumber *theLetterZNumber = @'Z';
char theLetterZ = [theLetterZNumber charValue]; // or 'Z'
NSLog(@"%c", theLetterZ);
// Integral literals
NSNumber *fortyTwoNumber = @42;
int fortyTwo = [fortyTwoNumber intValue]; // or 42
NSLog(@"%i", fortyTwo);
364
NSNumber *fortyOneShortNumber = [NSNumber numberWithShort:41];
unsigned short fortyOneUnsigned = [fortyOneShortNumber unsignedShortValue]; // or 41
NSLog(@"%u", fortyOneUnsigned);
// BOOL literals
NSNumber *yesNumber = @YES;
NSNumber *noNumber = @NO;
// or
BOOL yesBool = YES;
BOOL noBool = NO;
NSLog(@"%i", yesBool); // prints => 1
// Array object
// May contain different data types, but must be an Objective-C object
NSArray *anArray = @[@1, @2, @3, @4];
NSNumber *thirdNumber = anArray[2];
NSLog(@"Third number = %@", thirdNumber); // prints => "Third number = 3"
// Since Xcode 7, NSArray objects can be typed (Generics)
NSArray<NSString *> *stringArray = @[@"hello", @"world"];
// NSMutableArray is a mutable version of NSArray, allowing you to change
// the items in the array and to extend or shrink the array object.
// Convenient, but not as efficient as NSArray.
NSMutableArray *mutableArray = [NSMutableArray arrayWithCapacity:2];
[mutableArray addObject:@"Hello"];
365
[mutableArray addObject:@"World"];
[mutableArray removeObjectAtIndex:0];
NSLog(@"%@", [mutableArray objectAtIndex:0]); // prints => "World"
// Dictionary object
NSDictionary *aDictionary = @{ @"key1" : @"value1", @"key2" : @"value2" };
NSObject *valueObject = aDictionary[@"A Key"];
NSLog(@"Object = %@", valueObject); // prints => "Object = (null)"
// Since Xcode 7, NSDictionary objects can be typed (Generics)
NSDictionary<NSString *, NSNumber *> *numberDictionary = @{@"a": @1, @"b": @2};
// NSMutableDictionary also available as a mutable dictionary object
NSMutableDictionary *mutableDictionary = [NSMutableDictionary dictionaryWithCapacity:2];
[mutableDictionary setObject:@"value1" forKey:@"key1"];
[mutableDictionary setObject:@"value2" forKey:@"key2"];
[mutableDictionary removeObjectForKey:@"key1"];
// Set object
NSSet *set = [NSSet setWithObjects:@"Hello", @"Hello", @"World", nil];
NSLog(@"%@", set); // prints => {(Hello, World)} (may be in different order)
// Since Xcode 7, NSSet objects can be typed (Generics)
NSSet<NSString *> *stringSet = [NSSet setWithObjects:@"hello", @"world", nil];
// NSMutableSet also available as a mutable set object
NSMutableSet *mutableSet = [NSMutableSet setWithCapacity:2];
[mutableSet addObject:@"Hello"];
[mutableSet addObject:@"Hello"];
NSLog(@"%@", mutableSet); // prints => {(Hello)}
///////////////////////////////////////
// Operators
///////////////////////////////////////
///////////////////////////////////////
// Control Structures
///////////////////////////////////////
// If-Else statement
366
if (NO)
{
NSLog(@"I am never run");
} else if (0)
{
NSLog(@"I am also never run");
} else
{
NSLog(@"I print");
}
// Switch statement
switch (2)
{
case 0:
{
NSLog(@"I am never run");
} break;
case 1:
{
NSLog(@"I am also never run");
} break;
default:
{
NSLog(@"I print");
} break;
}
// Foreach statements
NSArray *values = @[@0, @1, @2, @3];
for (NSNumber *value in values)
{
NSLog(@"%@,", value);
} // prints => "0,"
367
// "1,"
// "2,"
// "3,"
// Object for loop statement. Can be used with any Objective-C object type
for (id item in values) {
NSLog(@"%@,", item);
} // prints => "0,"
// "1,"
// "2,"
// "3,"
// Try-Catch-Finally statements
@try
{
// Your statements here
@throw [NSException exceptionWithName:@"FileNotFoundException"
reason:@"File Not Found on System" userInfo:nil];
} @catch (NSException * e) // use: @catch (id exceptionName) to catch all objects.
{
NSLog(@"Exception: %@", e);
} @finally
{
NSLog(@"Finally. Time to clean up.");
} // prints => "Exception: File Not Found on System"
// "Finally. Time to clean up."
// NSError objects are useful for function arguments to populate on user mistakes.
NSError *error = [NSError errorWithDomain:@"Invalid email." code:4 userInfo:nil];
///////////////////////////////////////
// Objects
///////////////////////////////////////
// End of @autoreleasepool
}
///////////////////////////////////////
368
// Classes And Functions
///////////////////////////////////////
// Methods
+/- (return type)methodSignature:(Parameter Type *)parameterName;
// To access public variables from the implementation file, @property generates a setter method
// automatically. Method name is 'set' followed by @property variable name:
MyClass *myClass = [[MyClass alloc] init]; // create MyClass object instance
[myClass setCount:10];
NSLog(@"%d", [myClass count]); // prints => 10
// Or using the custom getter and setter method defined in @interface:
[myClass lengthSet:32];
NSLog(@"%i", [myClass lengthGet]); // prints => 32
369
// For convenience, you may use dot notation to set and access object instance variables:
myClass.count = 45;
NSLog(@"%i", myClass.count); // prints => 45
// Selectors
// Way to dynamically represent methods. Used to call methods of a class, pass methods
// through functions to tell other classes they should call it, and to save methods
// as a variable
// SEL is the data type. @selector() returns a selector from method name provided
// methodAParameterAsString:andAParameterAsNumber: is method name for method in MyClass
SEL selectorVar = @selector(methodAParameterAsString:andAParameterAsNumber:);
if ([myClass respondsToSelector:selectorVar]) { // Checks if class contains method
// Must put all method arguments into one object to send to performSelector function
NSArray *arguments = [NSArray arrayWithObjects:@"Hello", @4, nil];
[myClass performSelector:selectorVar withObject:arguments]; // Calls the method
} else {
// NSStringFromSelector() returns a NSString of the method name of a given selector
NSLog(@"MyClass does not have method: %@", NSStringFromSelector(selectedVar));
}
// To access a public variable from the interface file, use '_' followed by variable name:
_count = 5; // References "int count" from MyClass interface
// Access variables defined in implementation file:
distance = 18; // References "long distance" from MyClass implementation
// To use @property variable in implementation, use @synthesize to create accessor variable:
@synthesize roString = _roString; // _roString available now in @implementation
370
}
+ (NSString *)classMethod
{
return @"Some string";
}
// Objective-C does not have private method declarations, but you can simulate them.
// To simulate a private method, create the method in the @implementation but not in the @interface.
- (NSNumber *)secretPrivateMethod {
return @72;
}
[self secretPrivateMethod]; // Calls private method
371
///////////////////////////////////////
// Categories
///////////////////////////////////////
// A category is a group of methods designed to extend a class. They allow you to add new methods
// to an existing class for organizational purposes. This is not to be mistaken with subclasses.
// Subclasses are meant to CHANGE functionality of an object while categories instead ADD
// functionality to an object.
// Categories allow you to:
// -- Add methods to an existing class for organizational purposes.
// -- Allow you to extend Objective-C object classes (ex: NSString) to add your own methods.
// -- Add ability to create protected and private methods to classes.
// NOTE: Do not override methods of the base class in a category even though you have the ability
// to. Overriding methods may cause compiler errors later between different categories and it
// ruins the purpose of categories to only ADD functionality. Subclass instead to override methods.
- (void)turnOn;
- (void)accelerate;
@end
@implementation Car
- (void)turnOn {
NSLog(@"Car is on.");
}
- (void)accelerate {
NSLog(@"Accelerating.");
}
@end
// Now, if we wanted to create a Truck object, we would instead create a subclass of Car as it would
// be changing the functionality of the Car to behave like a truck. But lets say we want to just add
// functionality to this existing Car. A good example would be to clean the car. So we would create
// a category to add these cleaning methods:
// @interface filename: Car+Clean.h (BaseClassName+CategoryName.h)
#import "Car.h" // Make sure to import base class to extend.
@interface Car (Clean) // The category name is inside () following the name of the base class.
- (void)washWindows; // Names of the new methods we are adding to our Car object.
372
- (void)wax;
@end
- (void)washWindows {
NSLog(@"Windows washed.");
}
- (void)wax {
NSLog(@"Waxed.");
}
@end
// Any Car object instance has the ability to use a category. All they need to do is import it:
#import "Car+Clean.h" // Import as many different categories as you want to use.
#import "Car.h" // Also need to import base class to use it's original functionality.
// Objective-C does not have protected method declarations but you can simulate them.
// Create a category containing all of the protected methods, then import it ONLY into the
// @implementation file of a class belonging to the Car class:
@interface Car (Protected) // Naming category 'Protected' to remember methods are protected.
@end
//To use protected methods, import the category, then implement the methods:
#import "Car+Protected.h" // Remember, import in the @implementation file only.
@implementation Car
- (void)lockCar {
NSLog(@"Car locked."); // Instances of Car can't use lockCar because it's not in the @interface.
}
@end
///////////////////////////////////////
373
// Extensions
///////////////////////////////////////
// Extensions allow you to override public access property attributes and methods of an @interface.
// @interface filename: Shape.h
@interface Shape : NSObject // Base Shape class extension overrides below.
- (int)getNumOfSides;
@end
// You can override numOfSides variable or getNumOfSides method to edit them with an extension:
// @implementation filename: Shape.m
#import "Shape.h"
// Extensions live in the same file as the class @implementation.
@interface Shape () // () after base class name declares an extension.
@end
// The main @implementation:
@implementation Shape
@end
- (void)handleSuccess:(void(^)(A))success
failure:(void(^)(NSError *))failure;
@end
374
@interface Result : NSObject
- (void)handleSuccess:(void(^)(NSArray *))success
failure:(void(^)(NSError *))failure;
@property (nonatomic) NSArray * object;
@end
@implementation Result
- (void)handleSuccess:(void (^)(id))success
failure:(void (^)(NSError *))failure {
// Do something
}
@end
///////////////////////////////////////
// Protocols
///////////////////////////////////////
// A protocol declares methods that can be implemented by any class.
// Protocols are not classes themselves. They simply define an interface
// that other objects are responsible for implementing.
// @protocol filename: "CarUtilities.h"
@protocol CarUtilities <NSObject> // <NSObject> => Name of another protocol this protocol includes.
@property BOOL engineOn; // Adopting class must @synthesize all defined @properties and
- (void)turnOnEngine; // all defined methods.
@end
// Below is an example class implementing the protocol.
#import "CarUtilities.h" // Import the @protocol file.
@synthesize engineOn = _engineOn; // Create a @synthesize statement for the engineOn @property.
- (void)turnOnEngine { // Implement turnOnEngine however you would like. Protocols do not define
_engineOn = YES; // how you implement a method, it just requires that you do implement it.
}
375
// You may use a protocol as data as you know what methods and variables it has implemented.
- (void)turnOnEngineWithCarUtilities:(id <CarUtilities>)objectOfSomeKind {
[objectOfSomeKind engineOn]; // You have access to object variables
[objectOfSomeKind turnOnEngine]; // and the methods inside.
[objectOfSomeKind engineOn]; // May or may not be YES. Class implements it however it wants.
}
@end
// Instances of Car now have access to the protocol.
Car *carInstance = [[Car alloc] init];
[carInstance setEngineOn:NO];
[carInstance turnOnEngine];
if ([carInstance engineOn]) {
NSLog(@"Car engine is on."); // prints => "Car engine is on."
}
// Make sure to check if an object of type 'id' implements a protocol before calling protocol methods:
if ([myClass conformsToProtocol:@protocol(CarUtilities)]) {
NSLog(@"This does not run as the MyClass class does not implement the CarUtilities protocol.");
} else if ([carInstance conformsToProtocol:@protocol(CarUtilities)]) {
NSLog(@"This does run as the Car class implements the CarUtilities protocol.");
}
// Categories may implement protocols as well: @interface Car (CarCategory) <CarUtilities>
// You may implement many protocols: @interface Car : NSObject <CarUtilities, CarCleaning>
// NOTE: If two or more protocols rely on each other, make sure to forward-declare them:
#import "Brother.h"
@protocol Brother; // Forward-declare statement. Without it, compiler will throw error.
- (void)beNiceToBrother:(id <Brother>)brother;
@end
// See the problem is that Sister relies on Brother, and Brother relies on Sister.
#import "Sister.h"
@protocol Sister; // These lines stop the recursion, resolving the issue.
- (void)beNiceToSister:(id <Sister>)sister;
@end
///////////////////////////////////////
// Blocks
///////////////////////////////////////
// Blocks are statements of code, just like a function, that are able to be used as data.
// Below is a simple block with an integer argument that returns the argument plus 4.
int (^addUp)(int n); // Declare a variable to store the block.
void (^noParameterBlockVar)(void); // Example variable declaration of block with no arguments.
// Blocks have access to variables in the same scope. But the variables are readonly and the
376
// value passed to the block is the value of the variable when the block is created.
int outsideVar = 17; // If we edit outsideVar after declaring addUp, outsideVar is STILL 17.
__block long mutableVar = 3; // __block makes variables writable to blocks, unlike outsideVar.
addUp = ^(int n) { // Remove (int n) to have a block that doesn't take in any parameters.
NSLog(@"You may have as many lines in a block as you would like.");
NSSet *blockSet; // Also, you can declare local variables.
mutableVar = 32; // Assigning new value to __block variable.
return n + outsideVar; // Return statements are optional.
}
int addUp = addUp(10 + 16); // Calls block code with arguments.
// Blocks are often used as arguments to functions to be called later, or for callbacks.
@implementation BlockExample : NSObject
- (void)runBlock:(void (^)(NSString))block {
NSLog(@"Block argument returns nothing and takes in a NSString object.");
block(@"Argument given to block to execute."); // Calling block.
}
@end
///////////////////////////////////////
// Memory Management
///////////////////////////////////////
/*
For each object used in an application, memory must be allocated for that object. When the application
is done using that object, memory must be deallocated to ensure application efficiency.
Objective-C does not use garbage collection and instead uses reference counting. As long as
there is at least one reference to an object (also called "owning" an object), then the object
will be available to use (known as "ownership").
When an instance owns an object, its reference counter is increments by one. When the
object is released, the reference counter decrements by one. When reference count is zero,
the object is removed from memory.
MyClass *classVar = [MyClass alloc]; // 'alloc' sets classVar's reference count to one. Returns pointer
[classVar release]; // Decrements classVar's reference count
// 'retain' claims ownership of existing object instance and increments reference count. Returns pointer
MyClass *newVar = [classVar retain]; // If classVar is released, object is still in memory because newVa
[classVar autorelease]; // Removes ownership of object at end of @autoreleasepool block. Returns pointer
// @property can use 'retain' and 'assign' as well for small convenient definitions
@property (retain) MyClass *instance; // Release old value and retain a new one (strong reference)
@property (assign) NSSet *set; // Pointer to new value without retaining/releasing old (weak reference)
377
// ... code using arcMyClass
// Without ARC, you will need to call: [arcMyClass release] after you're done using arcMyClass. But with
// there is no need. It will insert this release statement for you
// As for the 'assign' and 'retain' @property attributes, with ARC you use 'weak' and 'strong'
@property (weak) MyClass *weakVar; // 'weak' does not take ownership of object. If original instance's r
// is set to zero, weakVar will automatically receive value of nil to avoid application crashing
@property (strong) MyClass *strongVar; // 'strong' takes ownership of object. Ensures object will stay i
// For regular variables (not @property declared variables), use the following:
__strong NSString *strongString; // Default. Variable is retained in memory until it leaves it's scope
__weak NSSet *weakSet; // Weak reference to existing object. When existing object is released, weakSet i
__unsafe_unretained NSArray *unsafeArray; // Like __weak, but unsafeArray not set to nil when existing o
Further Reading
Wikipedia Objective-C
Programming with Objective-C. Apple PDF book
Programming with Objective-C for iOS
Programming with Objective-C for Mac OSX
iOS For High School Students: Getting Started
Ocaml
OCaml is a strictly evaluated functional language with some imperative features.
Along with StandardML and its dialects it belongs to ML language family. F# is also heavily influenced by
OCaml.
Just like StandardML, OCaml features both an interpreter, that can be used interactively, and a compiler.
The interpreter binary is normally called “ocaml” and the compiler is “ocamlopt”. There is also a bytecode
compiler, “ocamlc”, but there are few reasons to use it.
It is strongly and statically typed, but instead of using manually written type annotations, it infers types of
expressions using Hindley-Milner algorithm. It makes type annotations unnecessary in most cases, but can
be a major source of confusion for beginners.
When you are in the top level loop, OCaml will print the inferred type after you enter an expression.
# let inc x = x + 1 ;;
val inc : int -> int = <fun>
# let a = 99 ;;
val a : int = 99
For a source file you can use “ocamlc -i /path/to/file.ml” command to print all names and type signatures.
$ cat sigtest.ml
let inc x = x + 1
let add x y = x + y
let a = 1
$ ocamlc -i ./sigtest.ml
val inc : int -> int
378
val add : int -> int -> int
val a : int
Note that type signatures of functions of multiple arguments are written in curried form. A function that
takes multiple arguments can be represented as a composition of functions that take only one argument. The
“f(x,y) = x + y” function from the example above applied to arguments 2 and 3 is equivalent to the “f0(y)
= 2 + y” function applied to 3. Hence the “int -> int -> int” signature.
(*** Comments ***)
(* Since OCaml compiler infers types automatically, you normally don't need to
specify argument types explicitly. However, you can do it if
you want or need to. *)
let inc_int (x: int) : int = x + 1 ;;
(* You need to mark recursive function definitions as such with "rec" keyword. *)
let rec factorial n =
if n = 0 then 1
else n * factorial (n-1)
;;
379
(* Every function must have at least one argument.
Since some functions naturally don't take any arguments, there's
"unit" type for it that has the only one value written as "()" *)
let print_hello () = print_endline "hello world" ;;
(* Note that you must specify "()" as argument when calling it. *)
print_hello () ;;
(* Alternatively you can use "let ... and ... in" construct.
This is especially useful for mutually recursive functions,
with ordinary "let .. in" the compiler will complain about
unbound values. *)
let rec
is_even = function
| 0 -> true
| n -> is_odd (n-1)
and
is_odd = function
| 0 -> false
| n -> is_even (n-1)
;;
380
let my_lambda = fun x -> x * x ;;
(+) 3 4 (* Same as 3 + 4 *)
12 / 3 ;; (* Integer division. *)
12.0 /. 3.0 ;; (* Floating point division. *)
5 mod 2 ;; (* Remainder. *)
(* Corollary: if you try to separate list items by commas, you get a list
with a tuple inside, probably not what you want. *)
let bad_list = [1, 2] ;; (* Becomes [(1, 2)] *)
381
(* You can access individual list items with the List.nth function. *)
List.nth my_list 1 ;;
(* There are higher-order functions for lists such as map and filter. *)
List.map (fun x -> x * 2) [1; 2; 3] ;;
List.filter (fun x -> x mod 2 = 0) [1; 2; 3; 4] ;;
(* You can add an item to the beginning of a list with the "::" constructor
often referred to as "cons". *)
1 :: [2; 3] ;; (* Gives [1; 2; 3] *)
382
(* You can define types with the "type some_type =" construct. Like in this
useless type alias: *)
type my_int = int ;;
let is_zero x =
match x with
| 0 -> true
| _ -> false (* The "_" pattern means "anything else". *)
;;
383
(* Matching predicates, aka "guarded pattern matching". *)
let abs x =
match x with
| x when x < 0 -> -x
| _ -> x
;;
abs 5 ;; (* 5 *)
abs (-5) (* 5 again *)
let say x =
match x with
| Dog x -> x ^ " says woof"
| Cat x -> x ^ " says meow"
;;
(* Built-in syntax for cons obscures the structure a bit, so we'll make
our own list for demonstration. *)
Further reading
• Visit the official website to get the compiler and read the docs: http://ocaml.org/
384
• Try interactive tutorials and a web-based interpreter by OCaml Pro: http://try.ocamlpro.com/
• Read “OCaml for the skeptical” course: http://www2.lib.uchicago.edu/keith/ocaml-class/home.html
Paren
Paren is a dialect of Lisp. It is designed to be an embedded language.
Some examples are from http://learnxinyminutes.com/docs/racket/.
;;; Comments
# comments
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; 1. Primitive Datatypes and Operators
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; Numbers
123 ; int
3.14 ; double
6.02e+23 ; double
(int 3.14) ; => 3 : int
(double 123) ; => 123 : double
;;; Booleans
true ; for true
false ; for false
(! true) ; => false
(&& true false (prn "doesn't get here")) ; => false
(|| false true (prn "doesn't get here")) ; => true
385
;; Strings can be added too!
(strcat "Hello " "world!") ; => "Hello world!"
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; 2. Variables
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; You can create or set a variable using (set)
;; a variable name can use any character except: ();#"
(set some-var 5) ; => 5
some-var ; => 5
;; Local binding: Use lambda calculus! 'a' and 'b' are bound to '1' and '2' only within the (fn ...)
((fn (a b) (+ a b)) 1 2) ; => 3
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; 3. Collections
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; Lists
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; 3. Functions
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
386
;; Use parentheses to call all functions, including a lambda expression
((fn () "Hello World")) ; => "Hello World"
;; You can shorten this using the function definition syntactic sugar:
(defn hello-world2 () "Hello World")
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; 4. Equality
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; 5. Control Flow
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; Conditionals
;;; Loops
;; while loop
((fn (i)
(while (< i 10)
(pr i)
(++ i))) 0) ; => prints 0123456789
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; 6. Mutation
387
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; 7. Macros
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Pcre
A regular expression (regex or regexp for short) is a special text string for describing a search pattern.
e.g. to extract domain name from a string we can say /ˆ[a-z]+:/ and it will match http: from
http://github.com/.
PCRE (Perl Compatible Regular Expressions) is a C library implementing regex. It was written in 1997
when Perl was the de-facto choice for complex text processing tasks. The syntax for patterns used in PCRE
closely resembles Perl. PCRE syntax is being used in many big projects including PHP, Apache, R to name
a few.
There are two different sets of metacharacters: * Those that are recognized anywhere in the pattern except
within square brackets
\ general escape character with several uses
^ assert start of string (or line, in multiline mode)
$ assert end of string (or line, in multiline mode)
. match any character except newline (by default)
[ start character class definition
| start of alternative branch
( start subpattern
) end subpattern
? extends the meaning of (
also 0 or 1 quantifier
also quantifier minimizer
* 0 or more quantifier
+ 1 or more quantifier
388
also "possessive quantifier"
{ start min/max quantifier
• Those that are recognized within square brackets. Outside square brackets. They are also called as
character classes.
PCRE provides some generic character types, also called as character classes.
\d any decimal digit
\D any character that is not a decimal digit
\h any horizontal white space character
\H any character that is not a horizontal white space character
\s any white space character
\S any character that is not a white space character
\v any vertical white space character
\V any character that is not a vertical white space character
\w any "word" character
\W any "non-word" character
Examples
We will test our examples on following string 66.249.64.13 - - [18/Sep/2004:11:07:48 +1000] "GET
/robots.txt HTTP/1.0" 200 468 "-" "Googlebot/2.1". It is a standard Apache access log.
389
Regex Result Comment
(+̣.){3}+̣ 66.249.64.13 (\d+\.){3}
is trying
to match
group
(\d+\.)
exactly
three
times.
[.+] [18/Sep/2004:11:07:48 .+
+1000] matches
any
character
(except
newline),
. is any
character
ˆ§+ 66.249.64.13 ˆ means
start of
the line,
\S+
matches
any
number of
non-space
characters
+[0-9]+ +1000 \+
matches
the
character
+ literally.
[0-9]
character
class
means
single
number.
Same can
be
achieved
using
\+\d+
390
Further Reading
Perl
Perl 5 is a highly capable, feature-rich programming language with over 25 years of development.
Perl 5 runs on over 100 platforms from portables to mainframes and is suitable for both rapid prototyping
and large scale development projects.
# Single line comments start with a number sign.
use strict;
use warnings;
# All perl scripts and modules should include these lines. Strict causes
# compilation to fail in cases like misspelled variable names, and
# warnings will print warning messages in case of common pitfalls like
# concatenating to an undefined value.
### Perl has three main variable types: $scalar, @array, and %hash.
## Scalars
# A scalar represents a single value:
my $animal = "camel";
my $answer = 42;
## Arrays
# An array represents a list of values:
my @animals = ("camel", "llama", "owl");
my @numbers = (23, 42, 69);
my @mixed = ("camel", 42, 1.23);
## Hashes
# A hash represents a set of key/value pairs:
# You can use whitespace and the "=>" operator to lay them out more
# nicely:
391
my %fruit_color = (
apple => "red",
banana => "yellow",
);
# Hash elements are accessed using curly braces, again with the $ sigil.
my $color = $fruit_color{apple};
#### References
my $array_ref = \@array;
my $hash_ref = \%hash;
my @array_of_arrays = (\@array1, \@array2, \@array3);
my @fruits_array = @$fruits;
my %colors_hash = %$colors;
my $first = $array_ref->[0];
my $value = $hash_ref->{banana};
if ($var) {
...
} elsif ($var eq 'bar') {
...
} else {
...
}
unless (condition) {
...
392
}
# This is provided as a more readable version of "if (!condition)"
# while
while (condition) {
...
}
# implicitly
for (@elements) {
print;
}
# Perl's regular expression support is both broad and deep, and is the
# subject of lengthy documentation in perlrequick, perlretut, and
# elsewhere. However, in short:
# Simple matching
if (/foo/) { ... } # true if $_ contains "foo"
if ($x =~ /foo/) { ... } # true if $x contains "foo"
# Simple substitution
393
#### Files and I/O
# You can open a file for input or output using the "open()" function.
# You can read from an open filehandle using the "<>" operator. In
# scalar context it reads a single line from the filehandle, and in list
# context it reads the whole file in, assigning each line to an element
# of the list:
my $line = <$in>;
my @lines = <$in>;
sub logger {
my $logmessage = shift;
open my $logfile, ">>", "my.log" or die "Could not open my.log: $!";
# Now we can use the subroutine just as any other built-in function:
#### Modules
package MyModule;
use strict;
use warnings;
sub trim {
my $string = shift;
$string =~ s/^\s+//;
$string =~ s/\s+$//;
return $string;
}
1;
# From elsewhere:
use MyModule;
394
MyModule::trim($string);
#### Objects
# Objects in Perl are just references that know which class (package)
# they belong to, so that methods (subroutines) called on it can be
# found there. The bless function is used in constructors (usually new)
# to set this up. However, you never need to call it yourself if you use
# a module like Moose or Moo (see below).
package MyCounter;
use strict;
use warnings;
sub new {
my $class = shift;
my $self = {count => 0};
return bless $self, $class;
}
sub count {
my $self = shift;
return $self->{count};
}
sub increment {
my $self = shift;
$self->{count}++;
}
1;
use MyCounter;
my $counter = MyCounter->new;
print $counter->count, "\n"; # 0
$counter->increment;
print $counter->count, "\n"; # 1
# The modules Moose and Moo from CPAN can help you set up your object
395
# classes. They provide a constructor and simple syntax for declaring
# attributes. This class can be used equivalently to the one above.
package MyCounter;
use Moo; # imports strict and warnings
has 'count' => (is => 'rwp', default => 0, init_arg => undef);
sub increment {
my $self = shift;
$self->_set_count($self->count + 1);
}
1;
FAQ
perlfaq contains questions and answers related to many common tasks, and often provides suggestions for
good CPAN modules to use.
Further Reading
• perl-tutorial
• Learn at www.perl.com
• perldoc
• and perl built-in : perldoc perlintro
Perl6
Perl 6 is a highly capable, feature-rich programming language made for at least the next hundred years.
The primary Perl 6 compiler is called Rakudo, which runs on the JVM and the MoarVM.
Meta-note : the triple pound signs are here to denote headlines, double paragraphs, and single notes.
#=> represents the output of a command.
# Single line comment start with a pound
#`(
Multiline comments use #` and a quoting construct.
(), [], {}, ��, etc, will work.
)
### Variables
396
my $str = 'String';
# 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 !
## * Lists. They represent multiple values. Their name start with `@`.
my @keys = 0, 2;
@array[@keys] = @letters; # Assign using an array
say @array; #=> a 6 b
397
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)
## You can also give them a default value when they're not passed:
sub hello-to($name = "World") {
say "Hello, $name !";
}
hello-to; #=> Hello, World !
hello-to(); #=> Hello, World !
hello-to('You'); #=> Hello, You !
## You can also, by using a syntax akin to the one of hashes (yay unified syntax !),
## pass *named* arguments to a `sub`.
# They're optional, and will default to "Any".
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);
# To make a named argument mandatory, you can use `?`'s inverse, `!`
sub with-mandatory-named(:$str!) {
say "$str !";
}
with-mandatory-named(str => "My String"); #=> My String !
with-mandatory-named; # run time error: "Required named parameter not passed"
with-mandatory-named(3); # run time error: "Too many positional parameters passed"
398
## 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
### Containers
# 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 !";
}
399
# 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
# - `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.
if True {
say "It's true !";
}
unless False {
say "It's not false !";
}
# You can also use their postfix versions, with the keyword after:
say "Quite truthy" if True;
400
# 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
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).
}
401
}
### Operators
## * Equality Checking
## * 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
402
# 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
# 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.
# You can use that in most places you'd expect, even assigning to an array
my @numbers = ^20;
## * And, Or
3 && 4; # 4, which is Truthy. Calls `.Bool` on `4` and gets `True`.
0 || False; # False. Calls `.Bool` on `0`
## Unpacking !
# It's the ability to "extract" arrays and keys (AKA "destructuring").
# It'll work in `my`s and in parameter lists.
my ($a, $b) = 1, 2;
say $a; #=> 1
my ($, $, $c) = 1, 2, 3; # keep the non-interesting anonymous
403
say $c; #=> 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 }
first-of-array(@small); #=> 1
first-of-array(@tail); # Throws an error "Too many positional parameters passed"
# (which means the array is too big).
# You could even extract on a slurpy (but it's pretty useless ;-).)
sub fst(*@ [$fst]) { # or simply : `sub fst($fst) { ... }`
say $fst;
}
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))`.
# 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.";
}
# Then call it with a hash: (you need to keep the brackets for it to be a hash)
key-of({value => 'foo', qua => 1});
#key-of(%hash); # the same (for an equivalent `%hash`)
404
# 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
}
}
my @list3 = list-of(3); #=> (0, 1, 2)
## You can create a lambda with `-> {}` ("pointy block") or `{}` ("block")
my &lambda = -> $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.
# 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
# (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); # Same as `-> $a, $b { $a + $b + 3 }`
# also `sub ($a, $b) { $a + $b + 3 }`
say (*/2)(4); #=> 2
# Immediatly execute the function Whatever created.
say ((*+3)/5)(5); #=> 1.6
# works even in parens !
## About types...
# Perl6 is gradually typed. This means you can specify the type
405
# 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.
## Multiple Dispatch
# Perl 6 can decide which variant of a `sub` to call based on the type of the
# arguments, or on arbitrary preconditions, like with a type or a `where`:
# 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
say "String: $s";
}
sayit("foo"); # prints "String: foo"
sayit(True); # fails at *compile time* with
# "calling 'sayit' will never work with arguments of types ..."
406
# sub trait_mod:<is>(Routine $r, :$rw!) {}
#
# (commented because running this would be a terrible idea !)
### Scoping
# In Perl 6, contrarily to many scripting languages (like Python, Ruby, PHP),
# you are to declare your variables before using them. You know `my`.
# (there are 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.
my $foo = 'Foo';
sub foo {
my $bar = 'Bar';
sub bar {
say "$foo $bar";
}
&bar; # return the function
}
foo()(); #=> 'Foo Bar'
# You declare a class with the keyword `class`, fields with `has`,
# methods with `method`. Every attribute that is private is named `$!attr`.
# Immutable public attributes are named `$.attr`
# (you can make them mutable with `is rw`)
class A {
has $.field; # `$.field` is immutable.
# From inside the class, use `$!field` to modify it.
407
has $.other-field is rw; # You can mark a public attribute `rw`.
has Int $!private-field = 10;
method get-value {
$.field + $!private-field;
}
method set-value($n) {
# $.field = $n; # As stated before, you can't use the `$.` immutable version.
$!field = $n; # This works, because `$!` is always mutable.
method !private-method {
say "This method is private to the class !";
}
};
class A {
has $.val;
submethod not-inherited {
say "This method won't be available on B.";
say "This is most useful for BUILD, which we'll see later";
}
# 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`)
# Also note that `BUILD` (the method called inside `new`)
# will set parent properties too, so you can pass `val => 5`.
my B $b .= new(val => 5);
408
# $b.not-inherited; # This won't work, for reasons explained above
$b.foo; # prints 5
$b.bar; #=> 50, since it calls B's `bar`
# However, this:
# method print {}
# is ONLY valid when `print` isn't a `multi` with the same dispatch.
# (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.
}
### Exceptions
# Exceptions are built on top of classes, in the package `X` (like `X::IO`).
# Unlike many other languages, in Perl 6, you put the `CATCH` block *within* the
# block to `try`. By default, a `try` has a `CATCH` block that catches
# any exception (`CATCH { default {} }`).
# You can redefine it using `when`s (and `default`)
# to handle the exceptions you want:
try {
open 'foo';
CATCH {
when X::AdHoc { say "unable to open file !" }
# 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.
}
}
409
# You can access the last exception with `$!` (use `$_` in a `CATCH` block)
# There are also some subtelties 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.
# (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!" }
}
}
### Packages
# Packages are a way to reuse code. Packages are like "namespaces", and any
# element of the six model (`module`, `role`, `class`, `grammar`, `subset`
# and `enum`) are actually packages. (Packages are the lowest common denominator)
# Packages are important - especially as Perl is well-known for CPAN,
# the Comprehensive Perl Archive Network.
# You're not supposed to use the package keyword, usually:
# you use `class Package::Name::Here;` to declare a class,
# or if you only want to export variables/subs, you can use `module`:
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 ...
}
unit module Parse::Text; # file-scoped form
grammar Parse::Text::Grammar { # A grammar is a package, which you could `use`
}
# You can use a module (bring its declarations into scope) with `use`
use JSON::Tiny; # if you installed Rakudo* or Panda, you'll have this module
say from-json('[1]').perl; #=> [1]
# We'll see how to export variables and subs in the next part:
### Declarators
# 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.
410
## * `our` (happens 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 Foo::Bar {
our $n = 1; # note: you can't put a type constraint on an `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'd get burned.";
}
my sub unavailable { # `my sub` is the default
say "Can't access me from outside, I'm my !";
}
say ++$n; # increment the package variable and output its value
}
}
say $Foo::Bar::n; #=> 1
Foo::Bar::inc; #=> 2
Foo::Bar::inc; #=> 3
411
### Phasers
# Phasers in Perl 6 are blocks that happen at determined points of time in your
# program. When the program is compiled, when a for loop runs, when you leave a
# block, when 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
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
INIT { say "[*] Runs at run time, as soon as possible, only once" }
END { say "Runs at run time, as late as possible, only once" }
## * 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." }
## * 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 (by throwing an exception)" }
}
## * 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" }
}
## * Role/class phasers
COMPOSE { "When a role is composed into a class. /!\ NOT YET IMPLEMENTED" }
412
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
}
# - `lazy` - Defer actual evaluation until value is fetched (forces lazy context)
# Not yet implemented !!
413
constant nilthingie = sink for ^3 { .say } #=> 0 1 2
say nilthingie.perl; #=> Nil
# * 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:
!$a! # with left-associative `!`, this is `(!$a)!`
!$a! # with right-associative `!`, this is `!($a!)`
!$a! # with non-associative `!`, this is illegal
# you can still call the sub with its "full name"
say prefix:<!>(True); #=> False
414
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`.
}
}
3 times -> { say "hello" }; #=> hello
#=> hello
#=> hello
# You're very recommended to put spaces
# around your infix operator calls.
## Meta operators !
# 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).
# Meta-operators, as their name suggests, are *composed* operators.
# Basically, they're operators that apply another operator.
## * 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).
#
415
# 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..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)
# You can also call it with a function you made up, using double brackets:
sub add($a, $b) { $a + $b }
say [[&add]] 1, 2, 3; #=> 6
## * Zip meta-operator
# This one is an infix meta-operator than 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
# And, as it turns out, you can also use the reduce meta-operator with it:
[Z||] (True, False), (False, False), (False, False); # (True, False)
## * 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
416
# (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)
# 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 (`$0`, `$1`, ... starting at 0, not 1 !).
#
417
# 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.
# It is, however, important as for how modifiers (that you're gonna see just below)
# are applied ...
# - `+` - 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.
418
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)
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"
# 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.
so 'fooABCABCbar' ~~ / foo ( 'A' <[A..Z]> 'C' ) + bar /; # `True`. (using `so` here, `$/` below)
# 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 `?`).
# Let's use examples to see that:
so 'fooABCbar' ~~ / foo ( A B C )? bar /; # `True`
say $/[0]; #=> �ABC�
say $0.WHAT; #=> (Match)
# It can't be more than one, so it's only a single match object.
so 'foobar' ~~ / foo ( A B C )? bar /; #=> True
say $0.WHAT; #=> (Any)
# This capture did not match, so it's empty
419
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).
# 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][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)
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.
# You'll see named capture below with grammars.
# 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 two parts:
# The "declarative prefix" (the part that can be statically analyzed)
# and the procedural parts.
# Declarative prefixes include alternations (`|`), conjuctions (`&`),
# 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.
#
# Then, all the alternatives are tried at once, and the longest wins.
# Exemples:
# DECLARATIVE | PROCEDURAL
/ 'foo' \d+ [ <subrule1> || <subrule2> ] /;
# 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)
# Note: the first-matching `or` still exists, but is now spelled `||`
'foo' ~~ / fo || foo /; # `fo` now.
420
### Extra: the MAIN subroutine
# 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 !" }
# This produces:
# $ perl6 cli.pl
# Usage:
# t.pl <name>
# And since it's a regular Perl 6 sub, you can haz multi-dispatch:
# (using a "Bool" for the named argument so that we can do `--replace`
# instead of `--replace=1`)
subset File of Str where *.IO.d; # convert to IO object to check the file exists
###
### APPENDIX A:
###
### List of things
###
## 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
421
# Like `or` and `||`, but instead returns the first *defined* value :
say Any // Nil // 0 // 5; #=> 0
422
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
}
# - `===` is value identity and uses `.WHICH` on the objects to compare them
# - `=:=` is container identity and uses `VAR()` on the objects to compare them
If you want to go further, you can:
• Read the Perl 6 Advent Calendar. This is probably the greatest source of Perl 6 information, snippets
and such.
• Come along on #perl6 at irc.freenode.net. The folks here are always helpful.
• Check the source of Perl 6’s functions and classes. 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. They explain P6 from an implementor point-of-view, but it’s
still very interesting.
Php-Composer
Composer is a tool for dependency management in PHP. It allows you to declare the libraries your project
depends on and it will manage (install/update) them for you.
Installing
## Installs the composer.phar binary into the current directory
curl -sS https://getcomposer.org/installer | php
## If you use this approach, you will need to invoke composer like this:
php composer.phar about
Confirming installation
## Check version and list options
composer
423
composer help require
Usage
Composer stores your project dependencies in composer.json. You can edit this file, but it is best to let
Composer manage it for you.
## Create a new project in the current folder
composer init
## runs an interactive questionnaire asking you for details about your project. Leaving them blank is f
## To download the just the production dependencies, i.e. excluding development dependencies
composer install --no-dev
## For more information on Composer version matching, see [Composer's documentation on Versions](https:/
424
composer.json vs composer.lock
The composer.json file stores your project’s floating version preferences for each dependency, along with
other information.
The composer.lock file stores exactly which version it has downloaded for each dependency. Never edit this
file.
If you include the composer.lock file in your git repository, every developer will install the currently used
version of the dependency. Even when a new version of a dependency is released, Composer will continue to
download the version recorded in the lock file.
## If you want to update all the dependencies to their newest version still matching your version prefer
composer update
## If you wish to migrate a package to a newer version preference, you may need to remove the older pack
composer remove --dev phpunit/phpunit
composer require --dev phpunit/phpunit:^5.0
Autoloader
Composer creates an autoloader class you can require from your application. You can make instances of
classes via their namespace.
require __DIR__ . '/vendor/autoload.php';
PSR-4 Autoloader
## Optimizes PSR0 and PSR4 packages to be loaded with classmaps too. Slow to run, but improves performan
composer dump-autoload --optimize --no-dev
425
Composer’s Cache
## Composer will retain downloaded packages to use in the future. Clear it with:
composer clear-cache
Troubleshooting
composer diagnose
composer self-update
composer clear-cache
References
Php
This document describes PHP 5+.
<?php // PHP code must be enclosed with <?php tags
/*
Surrounding text in slash-asterisk and asterisk-slash
makes it a multi-line comment.
*/
426
/************************************
* Types & Variables
*/
// Integers
$int1 = 12; // => 12
$int2 = -12; // => -12
$int3 = 012; // => 10 (a leading 0 denotes an octal number)
$int4 = 0x0F; // => 15 (a leading 0x denotes a hex literal)
// Binary integer literals are available since PHP 5.4.0.
$int5 = 0b11111111; // 255 (a leading 0b denotes a binary number)
// Delete variable
unset($int1);
// Arithmetic
$sum = 1 + 1; // 2
$difference = 2 - 1; // 1
$product = 2 * 2; // 4
$quotient = 2 / 1; // 2
// Shorthand arithmetic
$number = 0;
$number += 1; // Increment $number by 1
echo $number++; // Prints 1 (increments after evaluation)
echo ++$number; // Prints 3 (increments before evaluation)
$number /= $float; // Divide and assign the quotient to $number
427
$oranges = "I have ${number} oranges to eat.";
$money = "I have $${number} in the bank.";
/********************************
* Constants
*/
/********************************
* Arrays
*/
428
// Add an element to an associative array
$associative['Four'] = 4;
/********************************
* Output
*/
echo('Hello World!');
// Prints Hello World! to stdout.
// Stdout is the web page if running in a browser.
// echo and print are language constructs too, so you can drop the parentheses
echo 'Hello World!';
print 'Hello World!';
$paragraph = 'paragraph';
$x = 1;
$y = 2;
$x = $y; // $x now contains the same value as $y
$z = &$y;
// $z now contains a reference to $y. Changing the value of
// $z will change the value of $y also, and vice-versa.
// $x will remain unchanged as the original value of $y
429
// Dumps type and value of variable to stdout
var_dump($z); // prints int(0)
/********************************
* Logic
*/
$a = 0;
$b = '0';
$c = '1';
$d = '1';
// These comparisons will always be true, even if the types aren't the same.
assert($a == $b); // equality
assert($c != $a); // inequality
assert($c <> $a); // alternative inequality
assert($a < $c);
assert($c > $b);
assert($a <= $b);
assert($c >= $d);
// The following will only be true if the values match and are the same type.
assert($c === $d);
assert($a !== $d);
assert(1 === '1');
assert(1 !== '1');
$a = 100;
$b = 1000;
$integer = 1;
echo $integer + $integer; // => 2
$string = '1';
echo $string + $string; // => 2 (strings are coerced to integers)
$string = 'one';
echo $string + $string; // => 0
430
// Outputs 0 because the + operator cannot cast the string 'one' to a number
$zero = 0;
$boolean = (boolean) $zero; // => false
/********************************
* Control Structures
*/
if (true) {
print 'I get printed';
}
if (false) {
print 'I don\'t';
} else {
print 'I get printed';
}
if (false) {
print 'Does not get printed';
} elseif(true) {
print 'Does';
}
// ternary operator
print (false ? 'Does not get printed' : 'Does');
$x = 0;
if ($x === '0') {
print 'Does not print';
431
} elseif($x == '1') {
print 'Does not print';
} else {
print 'Does print';
}
<?php
echo "\n";
$i = 0;
do {
echo $i++;
} while ($i < 5); // Prints "01234"
echo "\n";
echo "\n";
432
$wheels = ['bicycle' => 2, 'car' => 4];
echo "\n";
echo "\n";
$i = 0;
while ($i < 5) {
if ($i === 3) {
break; // Exit out of the while loop
}
echo $i++;
} // Prints "012"
/********************************
* Functions
*/
433
// $result is not accessible outside the function
// print $result; // Gives a warning.
434
variable("Separate", "Hello", "World") // Separate || Hello | World |
/********************************
* Includes
*/
<?php
// PHP within included files must also begin with a PHP open tag.
include 'my-file.php';
// The code in my-file.php is now available in the current scope.
// If the file cannot be included (e.g. file not found), a warning is emitted.
include_once 'my-file.php';
// If the code in my-file.php has been included elsewhere, it will
// not be included again. This prevents multiple class declaration errors
require 'my-file.php';
require_once 'my-file.php';
// Same as include(), except require() will cause a fatal error if the
// file cannot be included.
// Contents of my-include.php:
<?php
// Files are included based on the file path given or, if none is given,
// the include_path configuration directive. If the file isn't found in
// the include_path, include will finally check in the calling script's
// own directory and the current working directory before failing.
/* */
/********************************
* Classes
*/
class MyClass
{
const MY_CONST = 'value'; // A constant
435
protected static $protectedStaticVar = 'protectedStatic';
// Magic Methods
// opposite to __construct()
// called when object is no longer referenced
public function __destruct() {
print "Destroying";
}
/*
* Declaring class properties or methods as static makes them accessible without
* needing an instantiation of the class. A property declared as static can not
* be accessed with an instantiated class object (though a static method can).
*/
436
MyClass::myStaticMethod(); // Outputs 'I am static';
// Override a method
function myMethod()
{
parent::myMethod();
print ' > MyOtherClass';
}
}
$x = new MyMapClass();
echo $x->property; // Will use the __get() method
437
$x->property = 'Something'; // Will use the __set() method
interface InterfaceOne
{
public function doSomething();
}
interface InterfaceTwo
{
public function doSomethingElse();
}
438
/********************************
* Traits
*/
// Traits are available from PHP 5.4.0 and are declared using "trait"
trait MyTrait
{
public function myTraitMethod()
{
print 'I have MyTrait';
}
}
class MyTraitfulClass
{
use MyTrait;
}
/********************************
* Namespaces
*/
<?php
class MyClass
{
}
439
use My\Namespace\MyClass;
namespace My\Other\Namespace;
/**********************
* Late Static Binding
*
*/
class ParentClass {
public static function who() {
echo "I'm a " . __CLASS__ . "\n";
}
public static function test() {
// self references the class the method is defined within
self::who();
// static references the class the method was invoked on
static::who();
}
}
ParentClass::test();
/*
I'm a ParentClass
I'm a ParentClass
*/
ChildClass::test();
/*
I'm a ParentClass
But I'm ChildClass
*/
/**********************
* Magic constants
*
*/
440
echo "Current class name is " . __CLASS__;
// Typical usage
require __DIR__ . '/vendor/autoload.php';
// Get the name of the current method. Only returns a value when used inside a trait or object declarati
echo "Current method is " . __METHOD__;
// Get the name of the current trait. Only returns a value when used inside a trait or object declaratio
echo "Current namespace is " . __TRAIT__;
/**********************
* Error Handling
*
*/
try {
// Do something
} catch (Exception $e) {
// Handle exception
}
// When using try catch blocks in a namespaced enviroment use the following
try {
// Do something
} catch (\Exception $e) {
// Handle exception
}
// Custom exceptions
try {
$condition = true;
441
if ($condition) {
throw new MyException('Something just happend');
}
More Information
Visit the official PHP documentation for reference and community input.
If you’re interested in up-to-date best practices, visit PHP The Right Way.
If you’re coming from a language with good package management, check out Composer.
For common standards, visit the PHP Framework Interoperability Group’s PSR standards.
Pogo
Pogoscript is a little language that emphasises readability, DSLs and provides excellent asynchronous prim-
itives for writing connected JavaScript applications for the browser or server.
// defining a variable
water temperature = 24
// calling a function
current temperature = temperature at 3200 altitude
442
// `self` is similar to `this` in JavaScript with the
// exception that `self` isn't redefined in each new
// function definition
// `self` just does what you expect
// calling methods
position (7, 2).distance from position (position (5, 1))
// arrays
positions = [
position (1, 1)
position (1, 2)
position (1, 3)
]
// indexing an array
positions.0.y
n = 2
positions.(n).y
// strings
poem = 'Tail turned to red sunset on a juniper crown a lone magpie cawks.
Mad at Oryoki in the shrine-room -- Thistles blossomed late afternoon.
Put on my shirt and took it off in the sun walking the path to lunch.
A dandelion seed floats above the marsh grass with the mosquitos.
At 4 A.M. the two middleaged men sleeping together holding hands.
In the half-light of dawn a few birds warble under the Pleiades.
Sky reddens behind fir trees, larks twitter, sparrows cheep cheep cheep
cheep cheep.'
// interpolation
outlook = 'amazing!'
console.log "the weather tomorrow is going to be #(outlook)"
// regular expressions
r/(\d+)m/i
r/(\d+) degrees/mg
// operators
true @and true
false @or true
@not false
2 < 4
2 >= 2
2 > 1
443
// to define your own
(p1) plus (p2) =
position (p1.x + p2.x, p1.y + p2.y)
// explicit return
(x) times (y) = return (x * y)
// new
now = @new Date ()
// asynchronous calls
444
// Node.js includes the `fs` module for accessing the file system.
// Let's list the contents of a directory
fs = require 'fs'
directory listing = fs.readdir! '.'
try
another directory listing = fs.readdir! 'a-missing-dir'
catch (ex)
console.log (ex)
// in fact, if you don't use `try catch`, it will raise the error up the
// stack to the outer-most `try catch` or to the event loop, as you'd expect
// with non-async exceptions
// all the other control structures work with asynchronous calls too
// here's `if else`
config =
if (fs.stat! 'config.json'.is file ())
JSON.parse (fs.read file! 'config.json' 'utf-8')
else
{
color: 'red'
}
// now we wait for the calls to finish and print the results
console.log "size of a.txt is #(a!.size)"
console.log "size of b.txt is #(b!.size)"
445
Powershell
PowerShell is the Windows scripting language and configuration management framework from Microsoft
built on the .NET Framework. Windows 7 and up ship with PowerShell.
Nearly all examples below can be a part of a shell script or executed directly in the shell.
A key difference with Bash is that it is mostly objects that you manipulate rather than plain text.
Read more here.
If you are uncertain about your environment:
Get-ExecutionPolicy -List
Set-ExecutionPolicy AllSigned
# Execution policies include:
# - Restricted: Scripts won't run.
# - RemoteSigned: Downloaded scripts run only if signed by a trusted publisher.
# - AllSigned: Scripts need to be signed by a trusted publisher.
# - Unrestricted: Run all scripts.
help about_Execution_Policies # for more info
446
# Using variables:
echo $aString
echo "Interpolation: $aString"
echo "`$aString has length of $($aString.Length)"
echo '$aString'
echo @"
This is a Here-String
$aString
"@
# Note that ' (single quote) won't expand the variables!
# Here-Strings also work with single quote
# Builtin variables:
# There are some useful builtin variables, like
echo "Booleans: $TRUE and $FALSE"
echo "Empty value: $NULL"
echo "Last program's return value: $?"
echo "Exit code of last run Windows-based program: $LastExitCode"
echo "The last token in the last line received by the session: $$"
echo "The first token: $^"
echo "Script's PID: $PID"
echo "Full path of current script directory: $PSScriptRoot"
echo 'Full path of current script: ' + $MyInvocation.MyCommand.Path
echo "FUll path of current directory: $Pwd"
echo "Bound arguments in a function, script or code block: $PSBoundParameters"
echo "Unbound arguments: $($Args -join ', ')."
# More builtins: `help about_Automatic_Variables`
447
# The classic for
for($i = 1; $i -le 10; $i++) {
"Loop number $i"
}
# Or shorter
1..10 | % { "Loop number $_" }
# Exception handling
try {} catch {} finally {}
try {} catch [System.NullReferenceException] {
echo $_.Exception | Format-List -Force
}
### Providers
# List files and directories in the current directory
ls # or `dir`
cd ~ # goto home
### Pipeline
# Cmdlets have parameters that control their execution:
Get-ChildItem -Filter *.txt -Name # Get just the name of all txt files
# Only need to type as much of a parameter name until it is no longer ambiguous
ls -fi *.txt -n # -f is not possible because -Force also exists
# Use `Get-Help Get-ChildItem -Full` for a complete overview
448
| Stop-Process -WhatIf
### Functions
# The [string] attribute is optional.
function foo([string]$name) {
echo "Hey $name, have a function"
}
449
### It's all .NET
# A PS string is in fact a .NET System.String
# All .NET methods and properties are thus available
'string'.ToUpper().Replace('G', 'ggg')
# Or more powershellish
'string'.ToUpper() -replace 'G', 'ggg'
### IO
# Reading a value from input:
$Name = Read-Host "What's your name?"
echo "Hello, $Name!"
[int]$Age = Read-Host "What's your age?"
450
$host.UI.RawUI.ReadKey()
return
# Create a shortcut
$WshShell = New-Object -comObject WScript.Shell
$Shortcut = $WshShell.CreateShortcut($link)
$Shortcut.TargetPath = $file
$Shortcut.WorkingDirectory = Split-Path $file
$Shortcut.Save()
Configuring your shell
# $Profile is the full path for your `Microsoft.PowerShell_profile.ps1`
# All code there will be executed when the PS session starts
if (-not (Test-Path $Profile)) {
New-Item -Type file -Path $Profile -Force
notepad $Profile
}
# More info: `help about_profiles`
# For a more usefull shell, be sure to check the project PSReadLine below
Interesting Projects
• Channel9 PowerShell tutorials
• PSGet NuGet for PowerShell
• PSReadLine A bash inspired readline implementation for PowerShell (So good that it now ships with
Windows10 by default!)
• Posh-Git Fancy Git Prompt (Recommended!)
• PSake Build automation tool
• Pester BDD Testing Framework
• Jump-Location Powershell cd that reads your mind
• PowerShell Community Extensions (Dead)
Not covered
• WMI: Windows Management Intrumentation (Get-CimInstance)
Purescript
PureScript is a small strongly, statically typed language compiling to Javascript.
• Learn more at http://www.purescript.org/
• Documentation: http://pursuit.purescript.org/
• Book: Purescript by Example, https://leanpub.com/purescript/
All the noncommented lines of code can be run in the PSCI REPL, though some will require the
--multi-line-mode flag.
--
-- 1. Primitive datatypes that corresponds to their Javascript
-- equivalents at runtime.
import Prelude
451
-- Numbers
1.0 + 7.2*5.5 :: Number -- 40.6
-- Ints
1 + 2*5 :: Int -- 11
-- Types are inferred, so the following works fine
9.0/2.5 + 4.4 -- 8.0
-- But Ints and Numbers don't mix, so the following won't
5/2 + 2.5 -- Expression 2.5 does not have type Int
-- Hexadecimal literals
0xff + 1 -- 256
-- Unary negation
6 * -3 -- -18
6 * negate 3 -- -18
-- Modulus, from purescript-math (Math)
3.0 % 2.0 -- 1.0
4.0 % 2.0 -- 0.0
-- Inspect the type of an expression in psci
:t 9.5/2.5 + 4.4 -- Prim.Number
-- Booleans
true :: Boolean -- true
false :: Boolean -- false
-- Negation
not true -- false
23 == 23 -- true
1 /= 4 -- true
1 >= 4 -- false
-- Comparisons < <= > >=
-- are defined in terms of compare
compare 1 2 -- LT
compare 2 2 -- EQ
compare 3 2 -- GT
-- Conjunction and Disjunction
true && (9 >= 19 || 1 < 2) -- true
-- Strings
"Hellow" :: String -- "Hellow"
-- Multiline string without newlines, to run in psci use the --multi-line-mode flag
"Hellow\
\orld" -- "Helloworld"
-- Multiline string with newlines
"""Hello
world""" -- "Hello\nworld"
-- Concatenate
"such " ++ "amaze" -- "such amaze"
--
-- 2. Arrays are Javascript arrays, but must be homogeneous
452
1 : [2,4,3] -- [1,2,4,3]
--
-- 3. Records are Javascript objects, with zero or more fields, which
-- can have different types.
-- In psci you have to write `let` in front of the function to get a
-- top level binding.
let book = {title: "Foucault's pendulum", author: "Umberto Eco"}
-- Access properties
book.title -- "Foucault's pendulum"
--
-- 4. Functions
-- In psci's multiline mode
let sumOfSquares :: Int -> Int -> Int
sumOfSquares x y = x*x + y*y
sumOfSquares 3 4 -- 25
let myMod x y = x % y
myMod 3.0 2.0 -- 1.0
-- Infix application of function
3 `mod` 2 -- 1
-- Conditional
453
let abs' n = if n>=0 then n else -n
abs' (-3) -- 3
-- Guarded equations
let abs'' n | n >= 0 = n
| otherwise = -n
-- Pattern matching
-- Note the type signature, input is a list of numbers. The pattern matching
-- destructures and binds the list into parts.
-- Requires purescript-lists (Data.List)
let first :: forall a. List a -> a
first (Cons x _) = x
first (toList [3,4,5]) -- 3
let second :: forall a. List a -> a
second (Cons _ (Cons y _)) = y
second (toList [3,4,5]) -- 4
let sumTwo :: List Int -> List Int
sumTwo (Cons x (Cons y rest)) = x + y : rest
fromList (sumTwo (toList [2,3,4,5,6])) :: Array Int -- [5,4,5,6]
-- sumTwo doesn't handle when the list is empty or there's only one element in
-- which case you get an error.
sumTwo [1] -- Failed pattern match
-- Use underscore to match any, where you don't care about the binding name
let isZero 0 = true
isZero _ = false
-- Lambda expressions
(\x -> x*x) 3 -- 9
(\x y -> x*x + y*y) 4 5 -- 41
let sqr = \x -> x*x
-- Currying
let myAdd x y = x + y -- is equivalent with
let myAdd' = \x -> \y -> x + y
454
let add3 = myAdd 3
:t add3 -- Prim.Int -> Prim.Int
Python
Python was created by Guido Van Rossum in the early 90s. It is now one of the most popular languages in
existence. I fell in love with Python for its syntactic clarity. It’s basically executable pseudocode.
Feedback would be highly appreciated! You can reach me at [@louiedinh](http://twitter.com/louiedinh) or
louiedinh [at] [google’s email service]
Note: This article applies to Python 2.7 specifically, but should be applicable to Python 2.x. Python 2.7
is reaching end of life and will stop being maintained in 2020, it is though recommended to start learning
Python with Python 3. For Python 3.x, take a look at the Python 3 tutorial.
It is also possible to write Python code which is compatible with Python 2.7 and 3.x at the same time, using
Python __future__ imports. __future__ imports allow you to write Python 3 code that will run on Python
2, so check out the Python 3 tutorial.
####################################################
## 1. Primitive Datatypes and Operators
####################################################
455
# Math is what you would expect
1 + 1 # => 2
8 - 1 # => 7
10 * 2 # => 20
35 / 5 # => 7
# Result of integer division truncated down both for positive and negative.
5 // 3 # => 1
5.0 // 3.0 # => 1.0 # works on floats too
-5 // 3 # => -2
-5.0 // 3.0 # => -2.0
# Modulo operation
7 % 3 # => 1
# Boolean Operators
# Note "and" and "or" are case-sensitive
True and False #=> False
False or True #=> True
# Equality is ==
1 == 1 # => True
456
2 == 1 # => False
# Inequality is !=
1 != 1 # => False
2 != 1 # => True
# More comparisons
1 < 10 # => True
1 > 10 # => False
2 <= 2 # => True
2 >= 2 # => True
# ... or multiplied
"Hello" * 3 # => "HelloHelloHello"
# None is an object
None # => None
457
None is None # => True
####################################################
## 2. Variables and Collections
####################################################
458
li.append(4) # li is now [1, 2, 4]
li.append(3) # li is now [1, 2, 4, 3]
# Remove from the end with pop
li.pop() # => 3 and li is now [1, 2, 4]
# Let's put it back
li.append(3) # li is now [1, 2, 4, 3] again.
459
# Check for existence in a list with "in"
1 in li # => True
460
# Use "get()" method to avoid the KeyError
filled_dict.get("one") # => 1
filled_dict.get("four") # => None
# The get method supports a default argument when the value is missing
filled_dict.get("one", 4) # => 1
filled_dict.get("four", 4) # => 4
# note that filled_dict.get("four") is still => None
# (get doesn't set the value in the dictionary)
# "setdefault()" inserts into a dictionary only if the given key isn't present
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)
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])
461
####################################################
## 3. Control Flow
####################################################
"""
For loops iterate over lists
prints:
dog is a mammal
cat is a mammal
mouse is a mammal
"""
for animal in ["dog", "cat", "mouse"]:
# You can use {0} to interpolate formatted strings. (See above.)
print "{0} is a mammal".format(animal)
"""
"range(number)" returns a list of numbers
from zero to the given number
prints:
0
1
2
3
"""
for i in range(4):
print i
"""
"range(lower, upper)" returns a list of numbers
from the lower number to the upper number
prints:
4
5
6
7
"""
for i in range(4, 8):
print i
"""
462
While loops go until a condition is no longer met.
prints:
0
1
2
3
"""
x = 0
while x < 4:
print x
x += 1 # Shorthand for x = x + 1
####################################################
## 4. Functions
####################################################
463
varargs(1, 2, 3) # => (1, 2, 3)
# you can pass args and kwargs along to other functions that take args/kwargs
# by expanding them with * and ** respectively
def pass_all_the_args(*args, **kwargs):
all_the_args(*args, **kwargs)
print varargs(*args)
print keyword_args(**kwargs)
# Function Scope
x = 5
def set_x(num):
# Local var x not the same as global variable x
x = num # => 43
print x # => 43
def set_global_x(num):
global x
print x # => 5
x = num # global var x is now set to 6
print x # => 6
set_x(43)
set_global_x(6)
464
def create_adder(x):
def adder(y):
return x + y
return adder
add_10 = create_adder(10)
add_10(3) # => 13
####################################################
## 5. Classes
####################################################
# Initialize property
self.age = 0
465
# They are called with the calling class as the first argument
@classmethod
def get_species(cls):
return cls.species
# Instantiate a class
i = Human(name="Ian")
print i.say("hi") # prints out "Ian: hi"
j = Human("Joel")
print j.say("hello") # prints out "Joel: hello"
466
i.age # => raises an AttributeError
####################################################
## 6. Modules
####################################################
####################################################
## 7. Advanced
####################################################
# Generators
# A generator "generates" values as they are requested instead of storing
# everything up front
# The following method (*NOT* a generator) will double all values and store it
# in `double_arr`. For large size of iterables, that might get huge!
def double_numbers(iterable):
467
double_arr = []
for i in iterable:
double_arr.append(i + i)
# Running the following would mean we'll double all values first and return all
# of them back to be checked by our condition
for value in double_numbers(range(1000000)): # `test_non_generator`
print value
if value > 5:
break
# We could instead use a generator to "generate" the doubled value as the item
# is being requested
def double_numbers_generator(iterable):
for i in iterable:
yield i + i
# Running the same code as before, but with a generator, now allows us to iterate
# over the values and doubling them one by one as they are being consumed by
# our logic. Hence as soon as we see a value > 5, we break out of the
# loop and don't need to double most of the values sent in (MUCH FASTER!)
for value in double_numbers_generator(xrange(1000000)): # `test_generator`
print value
if value > 5:
break
# BTW: did you notice the use of `range` in `test_non_generator` and `xrange` in `test_generator`?
# Just as `double_numbers_generator` is the generator version of `double_numbers`
# We have `xrange` as the generator version of `range`
# `range` would return back and array with 1000000 values for us to use
# `xrange` would generate 1000000 values for us as we request / iterate over those items
# Just as you can create a list comprehension, you can create generator
# comprehensions as well.
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
# Decorators
# in this example beg wraps say
# Beg will call say. If say_please is True then it will change the returned
# message
from functools import wraps
def beg(target_function):
@wraps(target_function)
def wrapper(*args, **kwargs):
msg, say_please = target_function(*args, **kwargs)
468
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
Dead Tree
• Programming Python
• Dive Into Python
• Python Essential Reference
Python3
Python was created by Guido Van Rossum in the early 90s. It is now one of the most popular languages in
existence. I fell in love with Python for its syntactic clarity. It’s basically executable pseudocode.
Feedback would be highly appreciated! You can reach me at [@louiedinh](http://twitter.com/louiedinh) or
louiedinh [at] [google’s email service]
Note: This article applies to Python 3 specifically. Check out here if you want to learn the old Python 2.7
469
####################################################
## 1. Primitive Datatypes and Operators
####################################################
# Result of integer division truncated down both for positive and negative.
5 // 3 # => 1
5.0 // 3.0 # => 1.0 # works on floats too
-5 // 3 # => -2
-5.0 // 3.0 # => -2.0
# Modulo operation
7 % 3 # => 1
# Boolean Operators
# Note "and" and "or" are case-sensitive
True and False # => False
False or True # => True
# Equality is ==
470
1 == 1 # => True
2 == 1 # => False
# Inequality is !=
1 != 1 # => False
2 != 1 # => True
# More comparisons
1 < 10 # => True
1 > 10 # => False
2 <= 2 # => True
2 >= 2 # => True
# (is vs. ==) is checks if two variables refer to the same object, but == checks
# if the objects pointed to have the same values.
a = [1, 2, 3, 4] # Point a at a new list, [1, 2, 3, 4]
b = a # Point b at what a is pointing to
b is a # => True, a and b refer to the same object
b == a # => True, a's and b's objects are equal
b = [1, 2, 3, 4] # Point b at a new list, [1, 2, 3, 4]
b is a # => False, a and b do not refer to the same object
b == a # => True, a's and b's objects are equal
# If your Python 3 code also needs to run on Python 2.5 and below, you can also
# still use the old style of formatting:
471
"%s can be %s the %s way" % ("Strings", "interpolated", "old") # => "Strings can be interpolated the ol
# None is an object
None # => None
####################################################
## 2. Variables and Collections
####################################################
# By default the print function also prints out a newline at the end.
# Use the optional argument end to change the end character.
print("Hello, World", end="!") # => Hello, World!
472
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]
# Remove from the end with pop
li.pop() # => 3 and li is now [1, 2, 4]
# Let's put it back
li.append(3) # li is now [1, 2, 4, 3] again.
# Get the index of the first item found matching the argument
li.index(2) # => 1
li.index(4) # Raises a ValueError as 4 is not in the list
473
# Check for existence in a list with "in"
1 in li # => True
# Note that a tuple of length one has to have a comma after the last element but
# tuples of other lengths, even zero, do not.
type((1)) # => <class 'int'>
type((1,)) # => <class 'tuple'>
type(()) # => <class 'tuple'>
# Note keys for dictionaries have to be immutable types. This is to ensure that
# the key can be converted to a constant hash value for quick look-ups.
# Immutable types include ints, floats, strings, tuples.
invalid_dict = {[1,2,3]: "123"} # => Raises a TypeError: unhashable type: 'list'
valid_dict = {(1,2,3):[1,2,3]} # Values can be of any type, however.
# 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"]
474
# 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]
# "setdefault()" inserts into a dictionary only if the given key isn't present
filled_dict.setdefault("five", 5) # filled_dict["five"] is set to 5
filled_dict.setdefault("five", 6) # filled_dict["five"] is still 5
# Adding to a dictionary
filled_dict.update({"four":4}) # => {"one": 1, "two": 2, "three": 3, "four": 4}
#filled_dict["four"] = 4 #another way to add to dict
# From Python 3.5 you can also use the additional unpacking options
{'a': 1, **{'b': 2}} # => {'a': 1, 'b': 2}
{'a': 1, **{'a': 2}} # => {'a': 2}
475
filled_set & other_set # => {3, 4, 5}
####################################################
## 3. Control Flow and Iterables
####################################################
"""
For loops iterate over lists
prints:
dog is a mammal
cat is a mammal
mouse is a mammal
"""
for animal in ["dog", "cat", "mouse"]:
# You can use format() to interpolate formatted strings
print("{} is a mammal".format(animal))
"""
"range(number)" returns an iterable of numbers
from zero to the given number
476
prints:
0
1
2
3
"""
for i in range(4):
print(i)
"""
"range(lower, upper)" returns an iterable of numbers
from the lower number to the upper number
prints:
4
5
6
7
"""
for i in range(4, 8):
print(i)
"""
"range(lower, upper, step)" returns an iterable of numbers
from the lower number to the upper number, while incrementing
by step. If step is not indicated, the default value is 1.
prints:
4
6
"""
for i in range(4, 8, 2):
print(i)
"""
477
print("All good!") # Runs only if the code in try raises no exceptions
finally: # Execute under all circumstances
print("We can clean up resources here")
# Our iterator is an object that can remember the state as we traverse through it.
# We get the next object with "next()".
next(our_iterator) # => "one"
# After the iterator has returned all of its data, it gives you a StopIterator Exception
next(our_iterator) # Raises StopIteration
# You can grab all the elements of an iterator by calling list() on it.
list(filled_dict.keys()) # => Returns ["one", "two", "three"]
####################################################
## 4. Functions
####################################################
478
# Another way to call functions is with keyword arguments
add(y=6, x=5) # Keyword arguments can arrive in any order.
x = 1
y = 2
x, y = swap(x, y) # => x = 2, y = 1
# (x, y) = swap(x,y) # Again parenthesis have been excluded but can be included.
# Function Scope
x = 5
def set_x(num):
# Local var x not the same as global variable x
x = num # => 43
print (x) # => 43
479
def set_global_x(num):
global x
print (x) # => 5
x = num # global var x is now set to 6
print (x) # => 6
set_x(43)
set_global_x(6)
add_10 = create_adder(10)
add_10(3) # => 13
####################################################
## 5. Modules
####################################################
480
# Warning: this is not recommended
from math import *
####################################################
## 6. Classes
####################################################
# Initialize property
self.age = 0
481
# A class method is shared among all instances
# They are called with the calling class as the first argument
@classmethod
def get_species(cls):
return cls.species
# When a Python interpreter reads a source file it executes all its code.
# This __name__ check makes sure this code block is only executed when this
# module is the main program.
if __name__ == '__main__':
# Instantiate a class
i = Human(name="Ian")
i.say("hi") # "Ian: hi"
j = Human("Joel")
j.say("hello") # "Joel: hello"
# i and j are instances of type Human, or in other words: they are Human objects
482
i.say(i.age) # => 42
j.say(j.age) # => 0
# Delete the property
del i.age
# i.age # => this would raise an AttributeError
####################################################
## 6.1 Multiple Inheritance
####################################################
species = 'Baty'
if __name__ == '__main__':
b = Bat()
print(b.say('hello'))
print(b.fly)
# Batman has its own value for the species class attribute
species = 'Superhero'
483
# override the value for the name attribute
self.name = 'Sad Affleck'
def sing(self):
return 'nan nan nan nan nan batman!'
if __name__ == '__main__':
sup = Batman()
# Get the Method Resolution search Order used by both getattr() and super().
# This attribute is dynamic and can be updated
print(Batman.__mro__) # => (<class '__main__.Batman'>, <class 'human.Human'>, <class 'bat.Bat'
# Inherited attribute from 2nd ancestor whose default value was overridden.
print('Can I fly? ' + str(sup.fly))
####################################################
## 7. Advanced
####################################################
# Generators are memory-efficient because they only load the data needed to
# process the next value in the iterable. This allows them to perform
484
# operations on otherwise prohibitively large value ranges.
# NOTE: `range` replaces `xrange` in Python 3.
for i in double_numbers(range(1, 900000000)): # `range` is a generator.
print(i)
if i >= 30:
break
# Just as you can create a list comprehension, you can create generator
# comprehensions as well.
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
# Decorators
# In this example `beg` wraps `say`. If say_please is True then it
# will change the returned message.
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
485
• The Official Docs
• Hitchhiker’s Guide to Python
• A Crash Course in Python for Scientists
• Python Course
• First Steps With Python
• A curated list of awesome Python frameworks, libraries and software
• 30 Python Language Features and Tricks You May Not Know About
• Official Style Guide for Python
• Python 3 Computer Science Circles
Dead Tree
• Programming Python
• Dive Into Python
• Python Essential Reference
Pythonstatcomp
This is a tutorial on how to do some typical statistical programming tasks using Python. It’s intended for
people basically familiar with Python and experienced at statistical programming in a language like R, Stata,
SAS, SPSS, or MATLAB.
""" Get set up with IPython and pip install the following: numpy, scipy, pandas,
matplotlib, seaborn, requests.
Make sure to do this tutorial in the IPython notebook so that you get
the inline plots and easy documentation lookup.
"""
""" One reason people choose Python over R is that they intend to interact a lot
with the web, either by scraping pages directly or requesting data through
an API. You can do those things in R, but in the context of a project
already using Python, there's a benefit to sticking with one language.
"""
# web scraping
r = requests.get("https://github.com/adambard/learnxinyminutes-docs")
r.status_code # if 200, request was successful
r.text # raw page source
print(r.text) # prettily formatted
# save the page source in a file:
os.getcwd() # check what's the working directory
f = open("learnxinyminutes.html", "wb")
f.write(r.text.encode("UTF-8"))
486
f.close()
# downloading a csv
fp = "https://raw.githubusercontent.com/adambard/learnxinyminutes-docs/master/"
fn = "pets.csv"
r = requests.get(fp + fn)
print(r.text)
f = open(fn, "wb")
f.write(r.text.encode("UTF-8"))
f.close()
""" Wes McKinney's pandas package gives you 'DataFrame' objects in Python. If
you've used R, you will be familiar with the idea of the "data.frame" already.
"""
import pandas as pd
import numpy as np
import scipy as sp
pets = pd.read_csv(fn)
pets
# name age weight species
# 0 fluffy 3 14 cat
# 1 vesuvius 6 23 fish
# 2 rex 5 34 dog
""" R users: note that Python, like most normal programming languages, starts
indexing from 0. R is the unusual one for starting from 1.
"""
pets.name[1] # 'vesuvius'
pets.species[0] # 'cat'
pets["weight"][2] # 34
# in R, you would expect to get 3 rows doing this, but here you get 2:
pets.age[0:2]
# 0 3
# 1 6
sum(pets.age) * 2 # 28
max(pets.weight) - min(pets.weight) # 20
487
""" If you are doing some serious linear algebra and number-crunching, you may
just want arrays, not DataFrames. DataFrames are ideal for combining columns
of different types.
"""
# 3. Charts ====
plt.hist(pets.age);
plt.boxplot(pets.weight);
plt.scatter(pets.age, pets.weight)
plt.xlabel("age")
plt.ylabel("weight");
plt.scatter(pets.age, pets.weight)
plt.xlabel("age")
plt.ylabel("weight");
488
url = "https://raw.githubusercontent.com/e99n09/R-notes/master/data/hre.csv"
r = requests.get(url)
fp = "hre.csv"
with open(fp, "wb") as f:
f.write(r.text.encode("UTF-8"))
hre = pd.read_csv(fp)
hre.head()
"""
Ix Dynasty Name Birth Death Election 1
0 NaN Carolingian Charles I 2 April 742 28 January 814 NaN
1 NaN Carolingian Louis I 778 20 June 840 NaN
2 NaN Carolingian Lothair I 795 29 September 855 NaN
3 NaN Carolingian Louis II 825 12 August 875 NaN
4 NaN Carolingian Charles II 13 June 823 6 October 877 NaN
Descent from whom 1 Descent how 1 Descent from whom 2 Descent how 2
0 NaN NaN NaN NaN
1 Charles I son NaN NaN
2 Louis I son NaN NaN
3 Lothair I son NaN NaN
4 Louis I son NaN NaN
"""
""" This function applies the regular expression to an input column (here Birth,
Death), flattens the resulting list, converts it to a Series object, and
finally converts the type of the Series object from string to integer. For
more information into what different parts of the code do, see:
- https://docs.python.org/2/howto/regex.html
- http://stackoverflow.com/questions/11860476/how-to-unlist-a-python-list
- http://pandas.pydata.org/pandas-docs/stable/generated/pandas.Series.html
"""
def extractYear(v):
return(pd.Series(reduce(lambda x, y: x + y, map(rx.findall, v), [])).astype(int))
hre["BirthY"] = extractYear(hre.Birth)
hre["DeathY"] = extractYear(hre.Death)
489
hre["EstAge"] = hre.DeathY.astype(int) - hre.BirthY.astype(int)
# use seaborn to make a scatterplot and plot the linear regression trend line
sns.lmplot("BirthY", "EstAge", data=hre);
Qt
Qt is a widely-known framework for developing cross-platform software that can be run on various software
and hardware platforms with little or no change in the code, while having the power and speed of native
applications. Though Qt was originally written in C++, there are its ports to other languages: PyQt,
QtRuby, PHP-Qt, etc.
Qt is beautiful for creating applications with graphical user interface (GUI). This tutorial is how to do it in
C++.
/*
* Let's start clasically
*/
490
// all headers from Qt framework start with capital letter 'Q'
#include <QApplication>
#include <QLineEdit>
#include <QApplication>
#include <QDialog>
#include <QVBoxLayout>
#include <QPushButton>
#include <QLabel>
QDialog dialogWindow;
dialogWindow.show();
return app.exec();
}
491
Notice that QObject::connect part. This method is used to connect SIGNALS of one objects to SLOTS of
another.
Signals are being emited when certain things happen with objects, like pressed signal is emited when user
presses on QPushButton object.
Slots are actions that might be performed in response to received signals.
READ MORE ABOUT SLOTS AND SIGNALS
Next, let’s learn that we can not only use standard widgets but also extend their behaviour using inheritance.
Let’s create a button and count how many times it was pressed. For this purpose we define our own class
CounterLabel. It must be declared in separate file because of specific Qt architecture.
// counterlabel.hpp
#ifndef COUNTERLABEL
#define COUNTERLABEL
#include <QLabel>
public:
CounterLabel() : counter(0) {
setText("Counter has not been increased yet"); // method of QLabel
}
public slots:
// action that will be called in response to button press
void increaseCounter() {
setText(QString("Counter value: %1").arg(QString::number(++counter)));
}
private:
int counter;
};
#endif // COUNTERLABEL
// main.cpp
// Almost the same as in previous example
#include <QApplication>
#include <QDialog>
#include <QVBoxLayout>
#include <QPushButton>
#include <QString>
#include "counterlabel.hpp"
QDialog dialogWindow;
dialogWindow.show();
492
QVBoxLayout layout;
dialogWindow.setLayout(&layout);
CounterLabel counterLabel;
layout.addWidget(&counterLabel);
return app.exec();
}
Furter reading
That’s it! Of course Qt framework is much much larger than the part that was covered in this tutorial, so
be ready to read and practice.
READ MORE ABOUT QT
Good luck and have fun
R
R is a statistical computing language. It has lots of libraries for uploading and cleaning data sets, running
statistical procedures, and making graphs. You can also run R commands within a LaTeX document.
#############################################################################
# Stuff you can do without understanding anything about programming
#############################################################################
# In this section, we show off some of the cool stuff you can do in
# R without understanding anything about programming. Do not worry
# about understanding everything the code does. Just enjoy!
493
# 141
summary(rivers) # what are some summary statistics?
# Min. 1st Qu. Median Mean 3rd Qu. Max.
# 135.0 310.0 425.0 591.2 680.0 3710.0
stem(log(rivers)) # Notice that the data are neither normal nor log-normal!
# Take that, Bell curve fundamentalists.
494
# make a histogram:
hist(rivers, col="#333333", border="white", breaks=25) # play around with these parameters
hist(log(rivers), col="#333333", border="white", breaks=25) # you'll do more plotting later
# Here's another neat data set that comes pre-loaded. R has tons of these.
data(discoveries)
plot(discoveries, col="#333333", lwd=3, xlab="Year",
main="Number of important discoveries per year")
plot(discoveries, col="#333333", lwd=3, type = "h", xlab="Year",
main="Number of important discoveries per year")
stem(discoveries, scale=2)
#
# The decimal point is at the |
#
# 0 | 000000000
# 1 | 000000000000
# 2 | 00000000000000000000000000
# 3 | 00000000000000000000
# 4 | 000000000000
# 5 | 0000000
# 6 | 000000
# 7 | 0000
# 8 | 0
# 9 | 0
# 10 | 0
# 11 |
# 12 | 0
max(discoveries)
# 12
summary(discoveries)
# Min. 1st Qu. Median Mean 3rd Qu. Max.
# 0.0 2.0 3.0 3.1 4.0 12.0
495
##################################################
# Data types and basic arithmetic
##################################################
# INTEGERS
# Long-storage integers are written with L
5L # 5
class(5L) # "integer"
# (Try ?class for more information on the class() function.)
# In R, every single value, like 5L, is considered a vector of length 1
length(5L) # 1
# You can have an integer vector with length > 1 too:
c(4L, 5L, 8L, 3L) # 4 5 8 3
length(c(4L, 5L, 8L, 3L)) # 4
class(c(4L, 5L, 8L, 3L)) # "integer"
# NUMERICS
# A "numeric" is a double-precision floating-point number
5 # 5
class(5) # "numeric"
# Again, everything in R is a vector;
# you can make a numeric vector with more than one element
c(3,3,3,2,2,1) # 3 3 3 2 2 1
# You can use scientific notation too
5e4 # 50000
6.02e23 # Avogadro's number
1.6e-35 # Planck length
# You can also have infinitely large or small numbers
class(Inf) # "numeric"
class(-Inf) # "numeric"
# You might use "Inf", for example, in integrate(dnorm, 3, Inf);
# this obviates Z-score tables.
# BASIC ARITHMETIC
# You can do arithmetic with numbers
# Doing arithmetic on a mix of integers and numerics gives you another numeric
10L + 66L # 76 # integer plus integer gives integer
53.2 - 4 # 49.2 # numeric minus numeric gives numeric
2.0 * 2L # 4 # numeric times integer gives numeric
3L / 4 # 0.75 # integer over numeric gives numeric
3 %% 2 # 1 # the remainder of two numerics is another numeric
# Illegal arithmetic yeilds you a "not-a-number":
0 / 0 # NaN
class(NaN) # "numeric"
# You can do arithmetic on two vectors with length greater than 1,
# so long as the larger vector's length is an integer multiple of the smaller
c(1,2,3) + c(1,2,3) # 2 4 6
496
# Since a single number is a vector of length one, scalars are applied
# elementwise to vectors
(4 * c(1,2,3) - 2) / 2 # 1 3 5
# Except for scalars, use caution when performing arithmetic on vectors with
# different lengths. Although it can be done,
c(1,2,3,1,2,3) * c(1,2) # 1 4 3 2 2 6
# Matching lengths is better practice and easier to read
c(1,2,3,1,2,3) * c(1,2,1,2,1,2)
# CHARACTERS
# There's no difference between strings and characters in R
"Horatio" # "Horatio"
class("Horatio") # "character"
class('H') # "character"
# Those were both character vectors of length 1
# Here is a longer one:
c('alef', 'bet', 'gimmel', 'dalet', 'he')
# =>
# "alef" "bet" "gimmel" "dalet" "he"
length(c("Call","me","Ishmael")) # 3
# You can do regex operations on character vectors:
substr("Fortuna multis dat nimis, nulli satis.", 9, 15) # "multis "
gsub('u', 'ø', "Fortuna multis dat nimis, nulli satis.") # "Fortøna møltis dat nimis, nølli satis."
# R has several built-in character vectors:
letters
# =>
# [1] "a" "b" "c" "d" "e" "f" "g" "h" "i" "j" "k" "l" "m" "n" "o" "p" "q" "r" "s"
# [20] "t" "u" "v" "w" "x" "y" "z"
month.abb # "Jan" "Feb" "Mar" "Apr" "May" "Jun" "Jul" "Aug" "Sep" "Oct" "Nov" "Dec"
# LOGICALS
# In R, a "logical" is a boolean
class(TRUE) # "logical"
class(FALSE) # "logical"
# Their behavior is normal
TRUE == TRUE # TRUE
TRUE == FALSE # FALSE
FALSE != FALSE # FALSE
FALSE != TRUE # TRUE
# Missing data (NA) is logical, too
class(NA) # "logical"
# Use | and & for logic operations.
# OR
TRUE | FALSE # TRUE
# AND
TRUE & FALSE # FALSE
# Applying | and & to vectors returns elementwise logic operations
c(TRUE,FALSE,FALSE) | c(FALSE,TRUE,FALSE) # TRUE TRUE FALSE
c(TRUE,FALSE,TRUE) & c(FALSE,TRUE,TRUE) # FALSE FALSE TRUE
# You can test if x is TRUE
isTRUE(TRUE) # TRUE
# Here we get a logical vector with many elements:
c('Z', 'o', 'r', 'r', 'o') == "Zorro" # FALSE FALSE FALSE FALSE FALSE
c('Z', 'o', 'r', 'r', 'o') == "Z" # TRUE FALSE FALSE FALSE FALSE
497
# FACTORS
# The factor class is for categorical data
# Factors can be ordered (like childrens' grade levels) or unordered (like gender)
factor(c("female", "female", "male", NA, "female"))
# female female male <NA> female
# Levels: female male
# The "levels" are the values the categorical data can take
# Note that missing data does not enter the levels
levels(factor(c("male", "male", "female", NA, "female"))) # "female" "male"
# If a factor vector has length 1, its levels will have length 1, too
length(factor("male")) # 1
length(levels(factor("male"))) # 1
# Factors are commonly seen in data frames, a data structure we will cover later
data(infert) # "Infertility after Spontaneous and Induced Abortion"
levels(infert$education) # "0-5yrs" "6-11yrs" "12+ yrs"
# NULL
# "NULL" is a weird one; use it to "blank out" a vector
class(NULL) # NULL
parakeet = c("beak", "feathers", "wings", "eyes")
parakeet
# =>
# [1] "beak" "feathers" "wings" "eyes"
parakeet <- NULL
parakeet
# =>
# NULL
# TYPE COERCION
# Type-coercion is when you force a value to take on a different type
as.character(c(6, 8)) # "6" "8"
as.logical(c(1,0,1,1)) # TRUE FALSE TRUE TRUE
# If you put elements of different types into a vector, weird coercions happen:
c(TRUE, 4) # 1 4
c("dog", TRUE, 4) # "dog" "TRUE" "4"
as.numeric("Bilbo")
# =>
# [1] NA
# Warning message:
# NAs introduced by coercion
##################################################
# Variables, loops, if/else
##################################################
498
# VARIABLES
# Lots of way to assign stuff:
x = 5 # this is possible
y <- "1" # this is preferred
TRUE -> z # this works but is weird
# LOOPS
# We've got for loops
for (i in 1:4) {
print(i)
}
# We've got while loops
a <- 10
while (a > 4) {
cat(a, "...", sep = "")
a <- a - 1
}
# Keep in mind that for and while loops run slowly in R
# Operations on entire vectors (i.e. a whole row, a whole column)
# or apply()-type functions (we'll discuss later) are preferred
# IF/ELSE
# Again, pretty standard
if (4 > 3) {
print("4 is greater than 3")
} else {
print("4 is not greater than 3")
}
# =>
# [1] "4 is greater than 3"
# FUNCTIONS
# Defined like so:
jiggle <- function(x) {
x = x + rnorm(1, sd=.1) #add in a bit of (controlled) noise
return(x)
}
# Called like any other R function:
jiggle(5) # 5±�. After set.seed(2716057), jiggle(5)==5.005043
###########################################################################
# Data structures: Vectors, matrices, data frames, and arrays
###########################################################################
# ONE-DIMENSIONAL
# Let's start from the very beginning, and with something you already know: vectors.
vec <- c(8, 9, 10, 11)
vec # 8 9 10 11
# We ask for specific elements by subsetting with square brackets
# (Note that R starts counting from 1)
499
vec[1] # 8
letters[18] # "r"
LETTERS[13] # "M"
month.name[9] # "September"
c(6, 8, 7, 5, 3, 0, 9)[3] # 7
# We can also search for the indices of specific components,
which(vec %% 2 == 0) # 1 3
# grab just the first or last few entries in the vector,
head(vec, 1) # 8
tail(vec, 2) # 10 11
# or figure out if a certain value is in the vector
any(vec == 10) # TRUE
# If an index "goes over" you'll get NA:
vec[6] # NA
# You can find the length of your vector with length()
length(vec) # 4
# You can perform operations on entire vectors or subsets of vectors
vec * 4 # 16 20 24 28
vec[2:3] * 5 # 25 30
any(vec[2:3] == 8) # FALSE
# and R has many built-in functions to summarize vectors
mean(vec) # 9.5
var(vec) # 1.666667
sd(vec) # 1.290994
max(vec) # 11
min(vec) # 8
sum(vec) # 38
# Some more nice built-ins:
5:15 # 5 6 7 8 9 10 11 12 13 14 15
seq(from=0, to=31337, by=1337)
# =>
# [1] 0 1337 2674 4011 5348 6685 8022 9359 10696 12033 13370 14707
# [13] 16044 17381 18718 20055 21392 22729 24066 25403 26740 28077 29414 30751
# You can make a matrix out of entries all of the same type like so:
mat <- matrix(nrow = 3, ncol = 2, c(1,2,3,4,5,6))
mat
# =>
# [,1] [,2]
# [1,] 1 4
# [2,] 2 5
# [3,] 3 6
# Unlike a vector, the class of a matrix is "matrix", no matter what's in it
class(mat) # => "matrix"
# Ask for the first row
mat[1,] # 1 4
# Perform operation on the first column
3 * mat[,1] # 3 6 9
# Ask for a specific cell
mat[3,2] # 6
500
t(mat)
# =>
# [,1] [,2] [,3]
# [1,] 1 2 3
# [2,] 4 5 6
# Matrix multiplication
mat %*% t(mat)
# =>
# [,1] [,2] [,3]
# [1,] 17 22 27
# [2,] 22 29 36
# [3,] 27 36 45
501
# 3 George 2 G
# 4 Cho 1 R
# 5 Draco 0 S
# 6 Ginny -1 G
class(students$year) # "numeric"
class(students[,3]) # "factor"
# find the dimensions
nrow(students) # 6
ncol(students) # 3
dim(students) # 6 3
# The data.frame() function converts character vectors to factor vectors
# by default; turn this off by setting stringsAsFactors = FALSE when
# you create the data.frame
?data.frame
# There are many twisty ways to subset data frames, all subtly unalike
students$year # 3 2 2 1 0 -1
students[,2] # 3 2 2 1 0 -1
students[,"year"] # 3 2 2 1 0 -1
502
# 4: S Salazar
setkey(students, house)
setkey(founders, house)
students <- founders[students] # merge the two data sets by matching "house"
setnames(students, c("house","houseFounderName","studentName","year"))
students[,order(c("name","year","house","houseFounderName")), with=F]
# =>
# studentName year house houseFounderName
# 1: Fred 2 G Godric
# 2: George 2 G Godric
# 3: Ginny -1 G Godric
# 4: Cedric 3 H Helga
# 5: Cho 1 R Rowena
# 6: Draco 0 S Salazar
503
# 6 S Salazar Draco 0
# Lists are not the most efficient data structure to work with in R;
# unless you have a very good reason, you should stick to data.frames
# Lists are often returned by functions that perform linear regressions
##################################################
# The apply() family of functions
##################################################
# Remember mat?
504
mat
# =>
# [,1] [,2]
# [1,] 1 4
# [2,] 2 5
# [3,] 3 6
# Use apply(X, MARGIN, FUN) to apply function FUN to a matrix X
# over rows (MAR = 1) or columns (MAR = 2)
# That is, R does FUN to each row (or column) of X, much faster than a
# for or while loop would do
apply(mat, MAR = 2, jiggle)
# =>
# [,1] [,2]
# [1,] 3 15
# [2,] 7 19
# [3,] 11 23
# Other functions: ?lapply, ?sapply
# Don't feel too intimidated; everyone agrees they are rather confusing
# The plyr package aims to replace (and improve upon!) the *apply() family.
install.packages("plyr")
require(plyr)
?plyr
#########################
# Loading data
#########################
#########################
# Statistical Analysis
#########################
# Linear regression!
linearModel <- lm(price ~ time, data = list1)
linearModel # outputs result of regression
# =>
505
# Call:
# lm(formula = price ~ time, data = list1)
#
# Coefficients:
# (Intercept) time
# 0.1453 0.4943
summary(linearModel) # more verbose output from the regression
# =>
# Call:
# lm(formula = price ~ time, data = list1)
#
# Residuals:
# Min 1Q Median 3Q Max
# -8.3134 -3.0131 -0.3606 2.8016 10.3992
#
# Coefficients:
# Estimate Std. Error t value Pr(>|t|)
# (Intercept) 0.14527 1.50084 0.097 0.923
# time 0.49435 0.06379 7.749 2.44e-09 ***
# ---
# Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
#
# Residual standard error: 4.657 on 38 degrees of freedom
# Multiple R-squared: 0.6124, Adjusted R-squared: 0.6022
# F-statistic: 60.05 on 1 and 38 DF, p-value: 2.44e-09
coef(linearModel) # extract estimated parameters
# =>
# (Intercept) time
# 0.1452662 0.4943490
summary(linearModel)$coefficients # another way to extract results
# =>
# Estimate Std. Error t value Pr(>|t|)
# (Intercept) 0.1452662 1.50084246 0.09678975 9.234021e-01
# time 0.4943490 0.06379348 7.74920901 2.440008e-09
summary(linearModel)$coefficients[,4] # the p-values
# =>
# (Intercept) time
# 9.234021e-01 2.440008e-09
506
# Degrees of Freedom: 39 Total (i.e. Null); 38 Residual
# Null Deviance: 55.35
# Residual Deviance: 55.12 AIC: 59.12
summary(glModel) # more verbose output from the regression
# =>
# Call:
# glm(formula = success ~ time,
# family = binomial(link = "logit"), data = list1)
# Deviance Residuals:
# Min 1Q Median 3Q Max
# -1.245 -1.118 -1.035 1.202 1.327
#
# Coefficients:
# Estimate Std. Error z value Pr(>|z|)
# (Intercept) 0.17018 0.64621 0.263 0.792
# time -0.01321 0.02757 -0.479 0.632
#
# (Dispersion parameter for binomial family taken to be 1)
#
# Null deviance: 55.352 on 39 degrees of freedom
# Residual deviance: 55.121 on 38 degrees of freedom
# AIC: 59.121
#
# Number of Fisher Scoring iterations: 3
#########################
# Plots
#########################
# GGPLOT2
# But these are not even the prettiest of R's plots
# Try the ggplot2 package for more and better graphics
install.packages("ggplot2")
require(ggplot2)
?ggplot2
pp <- ggplot(students, aes(x=house))
pp + geom_histogram()
ll <- as.data.table(list1)
pp <- ggplot(ll, aes(x=time,price))
pp + geom_point()
507
# ggplot2 has excellent documentation (available http://docs.ggplot2.org/current/)
How do I get R?
• Get R and the R GUI from http://www.r-project.org/
• RStudio is another GUI
Racket
Racket is a general purpose, multi-paradigm programming language in the Lisp/Scheme family.
Feedback is appreciated! You can reach me at [@th3rac25](http://twitter.com/th3rac25) or th3rac25 [at]
[google’s email service]
#lang racket ; defines the language we are using
;;; Comments
#| Block comments
can span multiple lines and...
#|
they can be nested!
|#
|#
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; 1. Primitive Datatypes and Operators
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; Numbers
9999999999999999999999 ; integers
#b111 ; binary => 7
#o111 ; octal => 73
#x111 ; hexadecimal => 273
3.14 ; reals
6.02e+23
1/2 ; rationals
1+2i ; complex numbers
508
(+ 1 1) ; => 2
(- 8 1) ; => 7
(* 10 2) ; => 20
(expt 2 3) ; => 8
(quotient 5 2) ; => 2
(remainder 5 2) ; => 1
(/ 35 5) ; => 7
(/ 1 3) ; => 1/3
(exact->inexact 1/3) ; => 0.3333333333333333
(+ 1+2i 2-3i) ; => 3-1i
;;; Booleans
#t ; for true
#f ; for false -- any value other than #f is true
(not #t) ; => #f
(and 0 #f (error "doesn't get here")) ; => #f
(or #f 0 (error "doesn't get here")) ; => 0
;;; Characters
#\A ; => #\A
#\� ; => #\�
#\u03BB ; => #\�
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; 2. Variables
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; You can create a variable using define
;; a variable name can use any character except: ()[]{}",'`;#|\
(define some-var 5)
some-var ; => 5
509
; x ; => x: undefined ...
;; Local binding: `me' is bound to "Bob" only within the (let ...)
(let ([me "Bob"])
"Alice"
me) ; => "Bob"
;; let* is like let, but allows you to use previous bindings in creating later bindings
(let* ([x 1]
[y (+ x 1)])
(* x y))
;; finally, letrec allows you to define recursive and mutually recursive functions
(letrec ([is-even? (lambda (n)
(or (zero? n)
(is-odd? (sub1 n))))]
[is-odd? (lambda (n)
(and (not (zero? n))
(is-even? (sub1 n))))])
(is-odd? 11))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; 3. Structs and Collections
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Structs
; By default, structs are immutable
(struct dog (name breed age))
(define my-pet
(dog "lassie" "collie" 5))
my-pet ; => #<dog>
; returns whether the variable was constructed with the dog constructor
(dog? my-pet) ; => #t
; accesses the name field of the variable constructed with the dog constructor
(dog-name my-pet) ; => "lassie"
; You can explicitly declare a struct to be mutable with the #:mutable option
(struct rgba-color (red green blue alpha) #:mutable)
(define burgundy
(rgba-color 144 0 32 1.0))
(set-color-green! burgundy 10)
(color-green burgundy) ; => 10
;;; Lists
;; Lists are linked-list data structures, made of `cons' pairs and end
;; with a `null' (or '()) to mark the end of the list
510
(cons 1 (cons 2 (cons 3 null))) ; => '(1 2 3)
;; `list' is a convenience variadic constructor for lists
(list 1 2 3) ; => '(1 2 3)
;; and a quote can also be used for a literal list value
'(1 2 3) ; => '(1 2 3)
;; Racket has predefined functions on top of car and cdr, to extract parts of a list
(cadr (list 1 2 3)) ; => 2
(car (cdr (list 1 2 3))) ; => 2
;;; Vectors
;;; Sets
511
;;; Hashes
;; Retrieve a value
(hash-ref m 'a) ; => 1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; 3. Functions
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; You can shorten this using the function definition syntactic sugar:
(define (hello-world2) "Hello World")
512
(string-append "Hello " name))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; 4. Equality
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
513
(let ([x '()] [y '()])
(eq? x y)) ; => #t, same as above
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; 5. Control Flow
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; Conditionals
514
; => 'yep
(define (fizzbuzz? n)
(match (list (remainder n 3) (remainder n 5))
[(list 0 0) 'fizzbuzz]
[(list 0 _) 'fizz]
[(list _ 0) 'buzz]
[_ #f]))
;;; Loops
;; See below how to add a new `loop' form, but Racket already has a very
;; flexible `for' form for loops:
(for ([i 10])
(printf "i=~a\n" i)) ; => i=0, i=1, ...
(for ([i (in-range 5 10)])
(printf "i=~a\n" i)) ; => i=5, i=6, ...
515
(for ([i (in-set (set 'x 'y 'z))])
(displayln i))
;; Nested loops
(for* ([i 2] [j '(x y z)]) (printf "~a:~a\n" i j))
; => 0:x, 0:y, 0:z, 1:x, 1:y, 1:z
;; Conditions
(for ([i 1000]
#:when (> i 5)
#:unless (odd? i)
#:break (> i 10))
(printf "i=~a\n" i))
; => i=6, i=8, i=10
;;; Comprehensions
;; Very similar to `for' loops -- just collect the results
(for/list ([i 1000] #:when (> i 5) #:unless (odd? i) #:break (> i 10))
i) ; => '(6 8 10)
;; There are many kinds of other built-in ways to collect loop values:
(for/sum ([i 10]) (* i i)) ; => 285
(for/product ([i (in-range 1 11)]) (* i i)) ; => 13168189440000
(for/and ([i 10] [j (in-range 10 20)]) (< i j)) ; => #t
(for/or ([i 10] [j (in-range 0 20 2)]) (= i j)) ; => #t
;; And to use any arbitrary combination, use `for/fold'
(for/fold ([sum 0]) ([i '(1 2 3 4)]) (+ sum i)) ; => 10
;; (This can often replace common imperative loops)
;;; Exceptions
516
;; To catch exceptions, use the `with-handlers' form
(with-handlers ([exn:fail? (lambda (exn) 999)])
(+ 1 "2")) ; => 999
(with-handlers ([exn:break? (lambda (exn) "no time")])
(sleep 3)
"phew") ; => "phew", but if you break it => "no time"
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; 6. Mutation
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Many Racket datatypes are immutable (pairs, lists, etc), some come in
;; both mutable and immutable flavors (strings, vectors, hash tables,
;; etc...)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; 7. Modules
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Modules let you organize code into multiple files and reusable
;; libraries; here we use sub-modules, nested in the whole module that
517
;; this text makes (starting from the "#lang" line)
(define (print-cake n)
(show " ~a " n #\.)
(show " .-~a-. " n #\|)
(show " | ~a | " n #\space)
(show "---~a---" n #\-))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; 8. Classes and Objects
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
518
(define my-color color)
(define/public (get-color) my-color)))
(define colored-fish% (add-color fish%))
(define charlie2 (new colored-fish% [size 10] [color 'red]))
(send charlie2 get-color)
;; or, with no names:
(send (new (add-color fish%) [size 10] [color 'red]) get-color)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; 9. Macros
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(define tmp 2)
(define other 3)
(swap! tmp other)
(printf "tmp = ~a; other = ~a\n" tmp other)
;; The variable `tmp` is renamed to `tmp_1`
;; in order to avoid name conflict
;; (let ([tmp_1 tmp])
;; (set! tmp other)
;; (set! other tmp_1))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; 10. Contracts
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
519
;; Contracts impose constraints on values exported from modules
(define amount 0)
(define (deposit a) (set! amount (+ amount a)))
(define (balance) amount)
)
(require 'bank-account)
(deposit 5)
(balance) ; => 5
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; 11. Input & output
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Append to "/tmp/tmp.txt"
(define out-port (open-output-file "/tmp/tmp.txt"
#:exists 'append))
(displayln "Hola mundo" out-port)
(close-output-port out-port)
520
(� (out-port)
(displayln "World Hello!" out-port)))
Further Reading
Still up for more? Try Getting Started with Racket
Red
Red was created out of the need to get work done, and the tool the author wanted to use, the language of
REBOL, had a couple of drawbacks. It was not Open Sourced at that time and it is an interpreted language,
what means that it is on average slow compared to a compiled language.
Red, together with its C-level dialect Red/System, provides a language that covers the entire programming
space you ever need to program something in. Red is a language heavily based on the language of REBOL.
Where Red itself reproduces the flexibility of the REBOL language, the underlying language Red will be
built upon, Red/System, covers the more basic needs of programming like C can, being closer to the metal.
Red will be the world’s first Full Stack Programming Language. This means that it will be an effective tool
to do (almost) any programming task on every level from the metal to the meta without the aid of other
stack tools. Furthermore Red will be able to cross-compile Red source code without using any GCC like
toolchain from any platform to any other platform. And it will do this all from a binary executable that is
supposed to stay under 1 MB.
Ready to learn your first Red?
All text before the header will be treated as comment, as long as you avoid using the
word "red" starting with a capital "R" in this pre-header text. This is a temporary
shortcoming of the used lexer but most of the time you start your script or program
with the header itself.
The header of a red script is the capitalized word "red" followed by a
whitespace character followed by a block of square brackets [].
The block of brackets can be filled with useful information about this script or
program: the author's name, the filename, the version, the license, a summary of
what the program does or any other files it needs.
The red/System header is just like the red header, only saying "red/System" and
not "red".
Red []
comment {
This is a multiline comment.
You just saw the Red version of the "Hello World" program.
}
521
; Your program's entry point is the first executable code that is found
; no need to restrict this to a 'main' function.
; Valid variable names start with a letter and can contain numbers,
; variables containing only capital A thru F and numbers and ending with 'h' are
; forbidden, because that is how hexadecimal numbers are expressed in Red and
; Red/System.
; print output using print, or prin for printing without a newline or linefeed at the
; end of the printed text.
; In case you haven't already noticed: statements do NOT end with a semicolon ;-)
;
; Datatypes
;
; If you know Rebol, you probably have noticed it has lots of datatypes. Red
; does not have yet all those types, but as Red want to be close to Rebol it
; will have a lot of datatypes.
; You can recognize types by the exclamation sign at the end. But beware
; names ending with an exclamation sign are allowed.
; Some of the available types are integer! string! block!
522
; A variable can be initialized using another variable that gets initialized
; at the same time.
i2: 1 + i1: 1
; Arithmetic is straightforward
i1 + i2 ; result 3
i2 - i1 ; result 1
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.
; 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 false
2 <= 2 ; result true
2 >= 2 ; result true
;
; 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.
if a < 0 [print "a is negative"]
; either
; Evaluate a block of code if a given condition is true, else evaluate an alternative
; block of code. If the last expressions in both blocks have the same type, EITHER can
; be used inside an expression.
either a < 0 [
either a = 0 [
msg: "zero"
][
msg: "negative"
]
][
msg: "positive"
]
523
"negative"
]
][
"positive"
]
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.
c: 5
until [
prin "o"
c: c - 1
c = 0 ; the condition to end the until loop
]
; will output:
ooooo
; Note that the loop will always be evaluated at least once, even if the condition is
; not met from the beginning.
; while
; While a given condition is met, evaluate a block of code.
; WHILE does not return any value, so it cannot be used in an expression.
c: 5
while [c > 0][
prin "o"
c: c - 1
]
; will output:
ooooo
;
; Functions
;
; function example
twice: function [a [integer!] /one return: [integer!]][
c: 2
a: a * c
either one [a + 1][a]
]
b: 3
print twice b ; will output 6.
; Import external files with #include and filenames start with a % sign
#include %includefile.red
; Now the functions in the included file can be used too.
Further Reading
The main source for information about Red is the Red language homepage.
The source can be found on github.
524
The Red/System language specification can be found here.
To learn more about Rebol and Red join the chat on Gitter. And if that is not working for you drop a mail
to us on the Red mailing list (remove NO_SPAM).
Browse or ask questions on Stack Overflow.
Maybe you want to try Red right away? That is possible on the try Rebol and Red site.
You can also learn Red by learning some Rebol.
Rst
RST is file format formely created by Python community to write documentation (and so, is part of Docutils).
RST files are simple text files with lightweight syntaxe (comparing to HTML).
Installation
To use Restructured Text, you will have to install Python and the docutils package.
docutils can be installed using the commandline:
$ easy_install docutils
If your system have pip, you can use it too:
$ pip install docutils
File syntaxe
A simple example of the file syntax:
.. Line with two dotes are special commands. But if no command can be found, the line is considered as a
=========================================================
Main titles are written using equals signs over and under
=========================================================
You can put text in *italic* or in **bold**, you can "mark" text as code with double backquote ``: ``pr
- First item
- Second item
- Sub item
525
or
* First item
* Second item
* Sub item
=========== ========
Country Capital
=========== ========
France Paris
Japan Tokyo
=========== ========
More complexe tabless can be done easily (merged columns and/or rows) but I suggest you to read the comp
- By adding an underscore after a word : Github_ and by adding the target after the text (this have the
- By typing a full comprehensible URL : https://github.com/ (will be automatically converted in link)
- By making a more "markdown" link: `Github <https://github.com/>`_ .
.. _Github https://github.com/
How to use it
RST comes with docutils in which you have rst2html for exemple:
$ rst2html myfile.rst output.html
Note : On some systems the command could be rst2html.py
But their is more complexe applications that uses RST file format:
• Pelican, a static site generator
• Sphinx, a documentation generator
• and many others
Readings
• Official quick reference
Ruby-Ecosystem
People using Ruby generally have a way to install different Ruby versions, manage their packages (or gems),
and manage their gem dependencies.
Ruby Managers
Some platforms have Ruby pre-installed or available as a package. Most rubyists do not use these, or if
they do, they only use them to bootstrap another Ruby installer or implementation. Instead rubyists tend
526
to install a Ruby manager to install and switch between many versions of Ruby and their projects’ Ruby
environments.
The following are the popular Ruby environment managers:
• RVM - Installs and switches between rubies. RVM also has the concept of gemsets to isolate projects’
environments completely.
• ruby-build - Only installs rubies. Use this for finer control over your rubies’ installations.
• rbenv - Only switches between rubies. Used with ruby-build. Use this for finer control over how rubies
load.
• chruby - Only switches between rubies. Similar in spirit to rbenv. Unopinionated about how rubies
are installed.
Ruby Versions
Ruby was created by Yukihiro “Matz” Matsumoto, who remains somewhat of a BDFL, although that is
changing recently. As a result, the reference implementation of Ruby is called MRI (Matz’ Reference Imple-
mentation), and when you hear a Ruby version, it is referring to the release version of MRI.
The three major version of Ruby in use are:
• 2.0.0 - Released in February 2013. Most major libraries and frameworks support 2.0.0.
• 1.9.3 - Released in October 2011. This is the version most rubyists use currently. Also retired
• 1.8.7 - Ruby 1.8.7 has been retired.
The change between 1.8.7 to 1.9.x is a much larger change than 1.9.3 to 2.0.0. For instance, the 1.9 series
introduced encodings and a bytecode VM. There are projects still on 1.8.7, but they are becoming a small
minority, as most of the community has moved to at least 1.9.2 or 1.9.3.
Ruby Implementations
The Ruby ecosystem enjoys many different implementations of Ruby, each with unique strengths and states
of compatibility. To be clear, the different implementations are written in different languages, but they are
all Ruby. Each implementation has special hooks and extra features, but they all run normal Ruby files well.
For instance, JRuby is written in Java, but you do not need to know Java to use it.
Very mature/compatible:
• MRI - Written in C, this is the reference implementation of Ruby. By definition it is 100% compatible
(with itself). All other rubies maintain compatibility with MRI (see RubySpec below).
• JRuby - Written in Java and Ruby, this robust implementation is quite fast. Most importantly, JRuby’s
strength is JVM/Java interop, leveraging existing JVM tools, projects, and languages.
• Rubinius - Written primarily in Ruby itself with a C++ bytecode VM. Also mature and fast. Because
it is implemented in Ruby itself, it exposes many VM features into rubyland.
Medium mature/compatible:
• Maglev - Built on top of Gemstone, a Smalltalk VM. Smalltalk has some impressive tooling, and this
project tries to bring that into Ruby development.
• RubyMotion - Brings Ruby to iOS development.
Less mature/compatible:
• Topaz - Written in RPython (using the PyPy toolchain), Topaz is fairly young and not yet compatible.
It shows promise to be a high-performance Ruby implementation.
• IronRuby - Written in C# targeting the .NET platform, work on IronRuby seems to have stopped
since Microsoft pulled their support.
527
Ruby implementations may have their own release version numbers, but they always target a specific version
of MRI for compatability. Many implementations have the ability to enter different modes (for example, 1.8
or 1.9 mode) to specify which MRI version to target.
RubySpec
Most Ruby implementations rely heavily on RubySpec. Ruby has no official specification, so the community
has written executable specs in Ruby to test their implementations’ compatibility with MRI.
RubyGems
RubyGems is a community-run package manager for Ruby. RubyGems ships with Ruby, so there is no need
to download it separately.
Ruby packages are called “gems,” and they can be hosted by the community at RubyGems.org. Each gem
contains its source code and some metadata, including things like version, dependencies, author(s), and
license(s).
Bundler
Bundler is a gem dependency resolver. It uses a project’s Gemfile to find dependencies, and then fetches those
dependencies’ dependencies recursively. It does this until all dependencies are resolved and downloaded, or
it will stop if a conflict has been found.
Bundler will raise an error if it finds conflicting dependencies. For example, if gem A requires version 3
or greater of gem Z, but gem B requires version 2, Bundler will notify you of the conflict. This becomes
extremely helpful as many gems refer to other gems (which refer to other gems), which can form a large
dependency graph to resolve.
Testing
Testing is a large part of Ruby culture. Ruby comes with its own Unit-style testing framework called minitest
(Or TestUnit for Ruby version 1.8.x). There are many testing libraries with different goals.
• TestUnit - Ruby 1.8’s built-in “Unit-style” testing framework
• minitest - Ruby 1.9/2.0’s built-in testing framework
• RSpec - A testing framework that focuses on expressivity
• Cucumber - A BDD testing framework that parses Gherkin formatted tests
Be Nice
The Ruby community takes pride in being an open, diverse, welcoming community. Matz himself is extremely
friendly, and the generosity of rubyists on the whole is amazing.
Ruby
# This is a comment
=begin
This is a multiline comment
No-one uses them
528
You shouldn't either
=end
# Bitwise operators
3 & 5 #=> 1
3 | 5 #=> 7
3 ^ 5 #=> 6
# Equality
1 == 1 #=> true
2 == 1 #=> false
# Inequality
1 != 1 #=> false
2 != 1 #=> true
# apart from false itself, nil is the only other 'falsey' value
# More comparisons
529
1 < 10 #=> true
1 > 10 #=> false
2 <= 2 #=> true
2 >= 2 #=> true
# Logical operators
true && false #=> false
true || false #=> true
!true #=> false
# There are alternate versions of the logical operators with much lower
# precedence. These are meant to be used as flow-control constructs to chain
# statements together until one of them returns true or false.
# Append to string
'hello' << ' world' #=> "hello world"
530
print "I'm printing!"
#=> I'm printing! => nil
# Variables
x = 25 #=> 25
x #=> 25
x = y = 10 #=> 10
x #=> 10
y #=> 10
status = :pending
# Arrays
# This is an array
array = [1, 2, 3, 4, 5] #=> [1, 2, 3, 4, 5]
531
array.[] 0 #=> 1
array.[] 12 #=> nil
# Reverse an Array
a=[1,2,3]
a.reverse! #=> [3,2,1]
# Or with a range
array[1..3] #=> [2, 3, 4]
# Since Ruby 1.9, there's a special syntax when using symbols as keys:
# Control structures
if true
532
'if statement'
elsif false
'else if, optional'
else
'else, also optional'
end
(1..5).each do |counter|
puts "iteration #{counter}"
end
#=> iteration 1
#=> iteration 2
#=> iteration 3
#=> iteration 4
#=> iteration 5
# If you still need an index you can use "each_with_index" and define an index
# variable
array.each_with_index do |element, index|
puts "#{element} is number #{index} in the array"
end
counter = 1
while counter <= 5 do
533
puts "iteration #{counter}"
counter += 1
end
#=> iteration 1
#=> iteration 2
#=> iteration 3
#=> iteration 4
#=> iteration 5
grade = 'B'
case grade
when 'A'
puts 'Way to go kiddo'
when 'B'
puts 'Better luck next time'
when 'C'
puts 'You can do better'
when 'D'
puts 'Scraping through'
when 'F'
puts 'You failed!'
else
puts 'Alternative grading system, eh?'
end
#=> "Better luck next time"
# exception handling:
begin
534
# code here that might raise an exception
raise NoMemoryError, 'You ran out of memory.'
rescue NoMemoryError => exception_variable
puts 'NoMemoryError was raised', exception_variable
rescue RuntimeError => other_exception_variable
puts 'RuntimeError was raised now'
else
puts 'This runs if no exceptions were thrown at all'
ensure
puts 'This code always runs no matter what'
end
# Functions
def double(x)
x * 2
end
# Functions (and all blocks) implicitly return the value of the last statement
double(2) #=> 4
def sum(x, y)
x + y
end
# yield
# All methods have an implicit, optional block parameter
# it can be called with the 'yield' keyword
def surround
puts '{'
yield
puts '}'
end
# {
# hello world
# }
535
def guests(&block)
block.call 'some_argument'
end
# You can pass a list of arguments, which will be converted into an array
# That's what splat operator ("*") is for
def guests(*array)
array.each { |guest| puts guest }
end
# By convention, all methods that return booleans end with a question mark
5.even? # false
5.odd? # true
# Basic initializer
def initialize(name, age = 0)
# Assign the argument to the "name" instance variable for the instance
@name = name
# If no age given, we will fall back to the default in the arguments list.
@age = age
end
536
end
# The above functionality can be encapsulated using the attr_accessor method as follows
attr_accessor :name
def species
@@species
end
end
# Instantiate a class
jim = Human.new('Jim Halpert')
537
# Class is also an object in ruby. So class can have instance variables.
# Class variable is shared among the class and all of its descendants.
# base class
class Human
@@foo = 0
def self.foo
@@foo
end
def self.foo=(value)
@@foo = value
end
end
# derived class
class Worker < Human
end
Human.foo # 0
Worker.foo # 0
Human.foo = 2 # 2
Worker.foo # 2
class Human
@bar = 0
def self.bar
@bar
end
def self.bar=(value)
@bar = value
end
end
Human.bar # 0
Doctor.bar # nil
module ModuleExample
def foo
'foo'
end
end
538
class Person
include ModuleExample
end
class Book
extend ModuleExample
end
module ConcernExample
def self.included(base)
base.extend(ClassMethods)
base.send(:include, InstanceMethods)
end
module ClassMethods
def bar
'bar'
end
end
module InstanceMethods
def qux
'qux'
end
end
end
class Something
include ConcernExample
end
Additional resources
• Learn Ruby by Example with Challenges - A variant of this reference with in-browser challenges.
• An Interactive Tutorial for Ruby - Learn Ruby through a series of interactive tutorials.
• Official Documentation
• Ruby from other languages
• Programming Ruby - An older free edition is available online.
• Ruby Style Guide - A community-driven Ruby coding style guide.
• Try Ruby - Learn the basic of Ruby programming language, interactive in the browser.
539
Rust
Rust is a programming language developed by Mozilla Research. Rust combines low-level control over
performance with high-level convenience and safety guarantees.
It achieves these goals without requiring a garbage collector or runtime, making it possible to use Rust
libraries as a “drop-in replacement” for C.
Rust’s first release, 0.1, occurred in January 2012, and for 3 years development moved so quickly that until
recently the use of stable releases was discouraged and instead the general advice was to use nightly builds.
On May 15th 2015, Rust 1.0 was released with a complete guarantee of backward compatibility. Improve-
ments to compile times and other aspects of the compiler are currently available in the nightly builds. Rust
has adopted a train-based release model with regular releases every six weeks. Rust 1.1 beta was made
available at the same time of the release of Rust 1.0.
Although Rust is a relatively low-level language, Rust has some functional concepts that are generally found
in higher-level languages. This makes Rust not only fast, but also easy and efficient to code in.
// This is a comment. Line comments look like this...
// and extend multiple lines like this.
/// Documentation comments look like this and support markdown notation.
/// # Examples
///
/// ```
/// let five = 5
/// ```
///////////////
// 1. Basics //
///////////////
// Functions
// `i32` is the type for 32-bit signed integers
fn add2(x: i32, y: i32) -> i32 {
// Implicit return (no semicolon)
x + y
}
// Main function
fn main() {
// Numbers //
// Immutable bindings
let x: i32 = 1;
// Integer/float suffixes
let y: i32 = 13i32;
let f: f64 = 1.3f64;
// Type inference
// Most of the time, the Rust compiler can infer what type a variable is, so
// you don’t have to write an explicit type annotation.
// Throughout this tutorial, types are explicitly annotated in many places,
// but only for demonstrative purposes. Type inference can handle this for
// you most of the time.
540
let implicit_x = 1;
let implicit_f = 1.3;
// Arithmetic
let sum = x + y + 13;
// Mutable variable
let mut mutable = 1;
mutable = 4;
mutable += 2;
// Strings //
// String literals
let x: &str = "hello world!";
// Printing
println!("{} {}", f, x); // 1.3 hello world
// Vectors/arrays //
// A fixed-size array
let four_ints: [i32; 4] = [1, 2, 3, 4];
// Tuples //
// Destructuring `let`
let (a, b, c) = x;
541
println!("{} {} {}", a, b, c); // 1 hello 3.4
// Indexing
println!("{}", x.1); // hello
//////////////
// 2. Types //
//////////////
// Struct
struct Point {
x: i32,
y: i32,
}
let up = Direction::Up;
// Generics //
// Methods //
impl<T> Foo<T> {
542
// Methods take an explicit `self` parameter
fn get_bar(self) -> T {
self.bar
}
}
trait Frobnicate<T> {
fn frobnicate(self) -> Option<T>;
}
/////////////////////////
// 3. Pattern matching //
/////////////////////////
match bar {
FooBar { x: 0, y: OptionalI32::AnI32(0) } =>
println!("The numbers are zero!"),
FooBar { x: n, y: OptionalI32::AnI32(m) } if n == m =>
println!("The numbers are the same"),
FooBar { x: n, y: OptionalI32::AnI32(m) } =>
println!("Different numbers: {} {}", n, m),
FooBar { x: _, y: OptionalI32::Nothing } =>
println!("The second number is Nothing!"),
}
/////////////////////
// 4. Control flow //
/////////////////////
// `for` loops/iteration
543
let array = [1, 2, 3];
for i in array.iter() {
println!("{}", i);
}
// Ranges
for i in 0u32..10 {
print!("{} ", i);
}
println!("");
// prints `0 1 2 3 4 5 6 7 8 9 `
// `if`
if 1 == 1 {
println!("Maths is working!");
} else {
println!("Oh no...");
}
// `if` as expression
let value = if true {
"good"
} else {
"bad"
};
// `while` loop
while 1 == 1 {
println!("The universe is operating normally.");
}
// Infinite loop
loop {
println!("Hello!");
}
/////////////////////////////////
// 5. Memory safety & pointers //
/////////////////////////////////
// Owned pointer – only one thing can ‘own’ this pointer at a time
// This means that when the `Box` leaves its scope, it can be automatically deallocated safely.
let mut mine: Box<i32> = Box::new(3);
*mine = 5; // dereference
// Here, `now_its_mine` takes ownership of `mine`. In other words, `mine` is moved.
let mut now_its_mine = mine;
*now_its_mine += 2;
println!("{}", now_its_mine); // 7
// println!("{}", mine); // this would not compile because `now_its_mine` now owns the pointer
544
// A borrow lasts until the end of the scope it was created in.
let mut var = 4;
var = 3;
let ref_var: &i32 = &var;
// Mutable reference
// While a value is mutably borrowed, it cannot be accessed at all.
let mut var2 = 4;
let ref_var2: &mut i32 = &mut var2;
*ref_var2 += 2; // '*' is used to point to the mutably borrowed var2
Further reading
There’s a lot more to Rust—this is just the basics of Rust so you can understand the most important things.
To learn more about Rust, read The Rust Programming Language and check out the /r/rust subreddit. The
folks on the #rust channel on irc.mozilla.org are also always keen to help newcomers.
You can also try out features of Rust with an online compiler at the official Rust playpen or on the main
Rust website.
Sass
Sass is a CSS extension language that adds features such as variables, nesting, mixins and more. Sass (and
other preprocessors, such as Less) help developers write maintainable and DRY (Don’t Repeat Yourself)
code.
Sass has two different syntax options to choose from. SCSS, which has the same syntax as CSS but with the
added features of Sass. Or Sass (the original syntax), which uses indentation rather than curly braces and
semicolons. This tutorial is written using SCSS.
If you’re already familiar with CSS3, you’ll be able to pick up Sass relatively quickly. It does not provide
any new styling properties but rather the tools to write your CSS more efficiently and make maintenance
much easier.
/* Variables
============================== */
545
/* You can store a CSS value (such as a color) in a variable.
Use the '$' symbol to create a variable. */
$primary-color: #A3A4FF;
$secondary-color: #51527F;
$body-font: 'Roboto', sans-serif;
body {
background-color: $primary-color;
color: $secondary-color;
font-family: $body-font;
}
/* Control Directives
============================== */
/* Sass lets you use @if, @else, @for, @while, and @each to control the
compilation of your code to CSS. */
@mixin debugmode {
@if $debug {
@debug "Debug mode enabled";
display: inline-block;
}
@else {
display: none;
}
}
.info {
@include debugmode;
546
}
.info {
display: inline-block;
}
@for $c from 1 to 4 {
div:nth-of-type(#{$c}) {
left: ($c - 1) * 900 / 3;
}
}
div:nth-of-type(1) {
left: 0;
}
div:nth-of-type(2) {
left: 300;
}
div:nth-of-type(3) {
left: 600;
}
.myclass-1 {
color: #555555;
}
.myclass-2 {
color: #aaaaaa;
}
.myclass-3 {
color: white;
// SASS automatically converts #FFFFFF to white
547
}
$columns: 4;
$column-width: 80px;
$columns: $columns - 1;
}
.col-4 {
width: 80px;
left: 240px;
}
.col-3 {
width: 80px;
left: 160px;
}
.col-2 {
width: 80px;
left: 80px;
}
.col-1 {
width: 80px;
left: 0px;
}
/* @each functions like @for, except using a list instead of ordinal values
Note: you specify lists just like other variables, with spaces as
delimiters. */
.social-links {
@each $sm in $social-links {
.icon-#{$sm} {
background-image: url("images/#{$sm}.png");
}
}
}
548
.social-links .icon-facebook {
background-image: url("images/facebook.png");
}
.social-links .icon-twitter {
background-image: url("images/twitter.png");
}
.social-links .icon-linkedin {
background-image: url("images/linkedin.png");
}
.social-links .icon-reddit {
background-image: url("images/reddit.png");
}
/*Mixins
==============================*/
/* If you find you are writing the same code for more than one
element, you might want to store that code in a mixin.
@mixin center {
display: block;
margin-left: auto;
margin-right: auto;
left: 0;
right: 0;
}
/* You can use the mixin with '@include' and the mixin name. */
div {
@include center;
background-color: $primary-color;
}
549
height: $height;
}
.rectangle {
@include size(100px, 60px);
}
.square {
@include size(40px, 40px);
}
/* Compiles to: */
.rectangle {
width: 100px;
height: 60px;
}
.square {
width: 40px;
height: 40px;
}
/* Functions
============================== */
.footer {
background-color: fade_out(#000000, 0.25);
}
/* Compiles to: */
body {
width: 10px;
}
.footer {
background-color: rgba(0, 0, 0, 0.75);
}
550
/* You may also define your own functions. Functions are very similar to
mixins. When trying to choose between a function or a mixin, remember
that mixins are best for generating CSS while functions are better for
logic that might be used throughout your Sass code. The examples in
the Math Operators' section are ideal candidates for becoming a reusable
function. */
/* This function will take a target size and the parent size and calculate
and return the percentage */
.main-content {
width: $main-content;
}
.sidebar {
width: calculate-percentage(300px, 960px);
}
/* Compiles to: */
.main-content {
width: 62.5%;
}
.sidebar {
width: 31.25%;
}
/* Extend (Inheritance)
============================== */
.display {
@include size(5em, 5em);
border: 5px solid $secondary-color;
}
.display-success {
@extend .display;
border-color: #22df56;
}
/* Compiles to: */
551
.display, .display-success {
width: 5em;
height: 5em;
border: 5px solid #51527F;
}
.display-success {
border-color: #22df56;
}
/* Nesting
============================== */
ul {
list-style-type: none;
margin-top: 2em;
li {
background-color: #FF0000;
}
}
ul {
list-style-type: none;
margin-top: 2em;
li {
background-color: red;
&:hover {
background-color: blue;
}
a {
color: white;
552
}
}
}
/* Compiles to: */
ul {
list-style-type: none;
margin-top: 2em;
}
ul li {
background-color: red;
}
ul li:hover {
background-color: blue;
}
ul li a {
color: white;
}
/* Sass allows you to create partial files. This can help keep your Sass
code modularized. Partial files should begin with an '_', e.g. _reset.css.
Partials are not generated into CSS. */
/* Consider the following CSS which we'll put in a file called _reset.css */
html,
body,
ul,
ol {
margin: 0;
padding: 0;
}
/* Sass offers @import which can be used to import partials into a file.
This differs from the traditional CSS @import statement which makes
another HTTP request to fetch the imported file. Sass takes the
imported file and combines it with the compiled code. */
@import 'reset';
body {
font-size: 16px;
font-family: Helvetica, Arial, Sans-serif;
553
}
/* Compiles to: */
body {
font-size: 16px;
font-family: Helvetica, Arial, Sans-serif;
}
/* Placeholder Selectors
============================== */
%content-window {
font-size: 14px;
padding: 10px;
color: #000;
border-radius: 4px;
}
.message-window {
@extend %content-window;
background-color: #0000ff;
}
/* Compiles to: */
.message-window {
font-size: 14px;
padding: 10px;
color: #000;
border-radius: 4px;
}
.message-window {
background-color: #0000ff;
}
/* Math Operations
554
============================== */
$content-area: 960px;
$main-content: 600px;
$sidebar-content: 300px;
body {
width: 100%;
}
.main-content {
width: $main-size;
}
.sidebar {
width: $sidebar-size;
}
.gutter {
width: $gutter;
}
/* Compiles to: */
body {
width: 100%;
}
.main-content {
width: 62.5%;
}
.sidebar {
width: 31.25%;
}
.gutter {
width: 6.25%;
}
555
SASS or Sass?
Have you ever wondered whether Sass is an acronym or not? You probably haven’t, but I’ll tell you anyway.
The name of the language is a word, “Sass”, and not an acronym. Because people were constantly writing
it as “SASS”, the creator of the language jokingly called it “Syntactically Awesome StyleSheets”.
Practice Sass
If you want to play with Sass in your browser, check out SassMeister. You can use either syntax, just go
into the settings and select either Sass or SCSS.
Compatibility
Sass can be used in any project as long as you have a program to compile it into CSS. You’ll want to verify
that the CSS you’re using is compatible with your target browsers.
QuirksMode CSS and CanIUse are great resources for checking compatibility.
Further reading
• Official Documentation
• The Sass Way provides tutorials (beginner-advanced) and articles.
Scala
Scala - the scalable language
/////////////////////////////////////////////////
// 0. Basics
/////////////////////////////////////////////////
/*
Setup Scala:
/*
Try the REPL
Scala has a tool called the REPL (Read-Eval-Print Loop) that is anologus to
commandline interpreters in many other languages. You may type any Scala
expression, and the result will be evaluated and printed.
The REPL is a very handy tool to test and verify code. Use it as you read
this tutorial to quickly explore concepts on your own.
*/
// Start a Scala REPL by running `scala`. You should see the prompt:
$ scala
scala>
556
// By default each expression you type is saved as a new numbered value
scala> 2 + 2
res0: Int = 4
// Default values can be reused. Note the value type displayed in the result..
scala> res0 + 2
res1: Int = 6
// Scala is a strongly typed language. You can use the REPL to check the type
// without evaluating an expression.
scala> :type (true, 2.0)
(Boolean, Double)
// Now that you know how to play, let's learn a little scala...
/////////////////////////////////////////////////
// 1. Basics
/////////////////////////////////////////////////
/*
Multi-line comments, as you can already see from above, look like this.
*/
557
// Declaring values is done using either var or val.
// val declarations are immutable, whereas vars are mutable. Immutability is
// a good thing.
val x = 10 // x is now 10
x = 20 // error: reassignment to val
var y = 10
y = 20 // y is now 20
/*
Scala is a statically typed language, yet note that in the above declarations,
we did not specify a type. This is due to a language feature called type
inference. In most cases, Scala compiler can guess what the type of a variable
is, so you don't have to type it every time. We can explicitly declare the
type of a variable like so:
*/
val z: Int = 10
val a: Double = 1.0
// Boolean values
true
false
// Boolean operations
!true // false
!false // true
true == false // false
10 > 5 // true
// Evaluating an expression in the REPL gives you the type and value of the result
1 + 7
scala> 1 + 7
res29: Int = 8
558
results of the expressions you typed, your output may differ.
*/
// They also have some extra Scala methods. See also: scala.collection.immutable.StringOps
"hello world".take(5)
"hello world".drop(5)
// Triple double-quotes let strings span multiple rows and contain quotes
val html = """<form id="daform">
<p>Press belo', Joe</p>
<input type="submit">
</form>"""
/////////////////////////////////////////////////
// 2. Functions
/////////////////////////////////////////////////
559
def sumOfSquares(x: Int, y: Int): Int = {
val x2 = x * x
val y2 = y * y
x2 + y2
}
subtract(10, 3) // => 7
subtract(y=10, x=3) // => -7
// In most cases (with recursive functions the most notable exception), function
// return type can be omitted, and the same type inference we saw with variables
// will work with function return values:
def sq(x: Int) = x * x // Compiler can guess return type is Int
// Unlike defs, even the input type of anonymous functions can be omitted if the
// context makes it clear. Notice the type "Int => Int" which means a function
// that takes Int and returns Int.
val sq: Int => Int = x => x * x
addOne(5) // => 6
weirdSum(2, 4) // => 16
// The return keyword exists in Scala, but it only returns from the inner-most
// def that surrounds it.
// WARNING: Using return in Scala is error-prone and should be avoided.
560
// It has no effect on anonymous functions. For example:
def foo(x: Int): Int = {
val anonFunc: Int => Int = { z =>
if (z > 5)
return z // This line makes z the return value of foo!
else
z + 2 // This line is the return value of anonFunc
}
anonFunc(x) // This line is the return value of foo
}
/////////////////////////////////////////////////
// 3. Flow Control
/////////////////////////////////////////////////
1 to 5
val r = 1 to 5
r.foreach(println)
r foreach println
// NB: Scala is quite lenient when it comes to dots and brackets - study the
// rules separately. This helps write DSLs and APIs that read like English
// A while loop
var i = 0
while (i < 10) { println("i " + i); i += 1 }
while (i < 10) { println("i " + i); i += 1 } // Yes, again. What happened? Why?
i // Show the value of i. Note that while is a loop in the classical sense -
// it executes sequentially while changing the loop variable. while is very
// fast, but using the combinators and comprehensions above is easier
// to understand and parallelize
// A do-while loop
i = 0
do {
println("i is still less than 10")
i += 1
} while (i < 10)
561
// Conditionals
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")
/////////////////////////////////////////////////
// 4. Data Structures
/////////////////////////////////////////////////
val m = Map("fork" -> "tenedor", "spoon" -> "cuchara", "knife" -> "cuchillo")
m("fork") // java.lang.String = tenedor
m("spoon") // java.lang.String = cuchara
m("bottle") // Throws an exception
val s = Set(1, 3, 7)
s(0) // Boolean = false
s(1) // Boolean = true
// Tuples
(1, 2)
(4, 3, 2)
(1, 2, "three")
(a, 2, "three")
562
// The function divideInts gives you the result and the remainder
divideInts(10, 3) // (Int, Int) = (3,1)
// To access the elements of a tuple, use _._n where n is the 1-based index of
// the element
val d = divideInts(10, 3) // (Int, Int) = (3,1)
d._1 // Int = 3
d._2 // Int = 1
div // Int = 3
mod // Int = 1
/////////////////////////////////////////////////
// 5. Object Oriented Programming
/////////////////////////////////////////////////
/*
Aside: Everything we've done so far in this tutorial has been simple
expressions (values, functions, etc). These expressions are fine to type into
the command-line interpreter for quick tests, but they cannot exist by
themselves in a Scala file. For example, you cannot have just "val x = 5" in
a Scala file. Instead, the only top-level constructs allowed in Scala are:
- objects
- classes
- case classes
- traits
// Values and methods are assumed public. "protected" and "private" keywords
// are also available.
private def sleep(hours: Int) =
println(s"I'm sleeping for $hours hours")
// Abstract methods are simply methods with no body. If we uncomment the next
// line, class Dog would need to be declared abstract
563
// abstract class Dog(...) { ... }
// def chaseAfter(what: String): String
}
// Case classes are classes that have extra functionality built in. A common
// question for Scala beginners is when to use classes and when to use case
// classes. The line is quite fuzzy, but in general, classes tend to focus on
// encapsulation, polymorphism, and behavior. The values in these classes tend
// to be private, and only methods are exposed. The primary purpose of case
// classes is to hold immutable data. They often have few methods, and the
// methods rarely have side-effects.
case class Person(name: String, phoneNumber: String)
// With case classes, you get a few perks for free, like getters:
george.phoneNumber // => "1234"
// And many others. Case classes also get pattern matching for free, see below.
/////////////////////////////////////////////////
// 6. Pattern Matching
/////////////////////////////////////////////////
564
// Pattern matching is a powerful and commonly used feature in Scala. Here's how
// you pattern match a case class. NB: Unlike other languages, Scala cases do
// not need breaks, fall-through does not happen.
// Pattern matching might look familiar to the switch statements in the C family
// of languages, but this is much more powerful. In Scala, you can match much
// more:
def matchEverything(obj: Any): String = obj match {
// You can match values:
case "Hello world" => "Got the string Hello world"
// In fact, you can pattern match any object with an "unapply" method. This
// feature is so powerful that Scala lets you define whole functions as
// patterns:
val patternFunc: Person => String = {
case Person("George", number) => s"George's number: $number"
case Person(name, number) => s"Random person's number: $number"
}
565
/////////////////////////////////////////////////
// 7. Functional Programming
/////////////////////////////////////////////////
val add10: Int => Int = _ + 10 // A function taking an Int and returning an Int
List(1, 2, 3) map add10 // List(11, 12, 13) - add10 is applied to each element
// And the underscore symbol, can be used if there is just one argument to the
// anonymous function. It gets bound as the variable
List(1, 2, 3) map (_ + 10)
// If the anonymous block AND the function you are applying both take one
// argument, you can even omit the underscore
List("Dom", "Bob", "Natalia") foreach println
// Combinators
s.map(sq)
sSquared.reduce (_+_)
// The filter function takes a predicate (a function from A -> Boolean) and
// selects all elements which satisfy the predicate
List(1, 2, 3) filter (_ > 2) // List(3)
case class Person(name: String, age: Int)
List(
Person(name = "Dom", age = 23),
Person(name = "Bob", age = 30)
).filter(_.age > 25) // List(Person("Bob", 30))
// For comprehensions
566
for { n <- nSquared2 if n < 10 } yield n
/* NB Those were not for loops. The semantics of a for loop is 'repeat', whereas
a for-comprehension defines a relationship between two sets of data. */
/////////////////////////////////////////////////
// 8. Implicits
/////////////////////////////////////////////////
// The difference is that these values are now eligible to be used when another
// piece of code "needs" an implicit value. One such situation is implicit
// function arguments:
def sendGreetings(toWhom: String)(implicit howMany: Int) =
s"Hello $toWhom, $howMany blessings to you and yours!"
// But if we omit the implicit parameter, an implicit value of the same type is
// used, in this case, "myImplicitInt":
sendGreetings("Jane") // => "Hello Jane, 100 blessings to you and yours!"
// Another situation in which the compiler looks for an implicit is if you have
// obj.method(...)
567
// but "obj" doesn't have "method" as a method. In this case, if there is an
// implicit conversion of type A => B, where A is the type of obj, and B has a
// method called "method", that conversion is applied. So having
// myImplicitFunction above in scope, we can say:
"Retriever".breed // => "Golden Retriever"
"Sheperd".bark // => "Woof, woof!"
// Here the String is first converted to Dog using our function above, and then
// the appropriate method is called. This is an extremely powerful feature, but
// again, it is not to be used lightly. In fact, when you defined the implicit
// function above, your compiler should have given you a warning, that you
// shouldn't do this unless you really know what you're doing.
/////////////////////////////////////////////////
// 9. Misc
/////////////////////////////////////////////////
// Importing things
import scala.collection.immutable.List
// Import all classes, except some. The following excludes Map and Set:
import scala.collection.immutable.{Map => _, Set => _, _}
// Your programs entry point is defined in an scala file using an object, with a
// single method, main:
object Application {
def main(args: Array[String]): Unit = {
// stuff goes here.
}
}
// Files can contain multiple classes and objects. Compile with scalac
568
println(line)
Further resources
• Scala for the impatient
• Twitter Scala school
• The scala documentation
• Try Scala in your browser
• Join the Scala user group
Self
Self is a fast prototype based OO language which runs in its own JIT vm. Most development is done through
interacting with live objects through a visual development environment called morphic with integrated
browsers and debugger.
Everything in Self is an object. All computation is done by sending messages to objects. Objects in Self can
be understood as sets of key-value slots.
Constructing objects
The inbuild Self parser can construct objects, including method objects.
"This is a comment"
"A string:"
'This is a string with \'escaped\' characters.\n'
"-20"
-14r16
"An object which only understands one message, 'x' which returns 20"
(|
x = 20.
|)
"An object which also understands 'x:' which sets the x slot"
(|
x <- 20.
|)
569
"An object which understands the method 'doubleX' which
doubles the value of x and then returns the object"
(|
x <- 20.
doubleX = (x: x * 2. self)
|)
"sends the message '+' with '7' to '23', then the message '*' with '8' to the result"
(23 + 7) * 8
Blocks
Self defines flow control like Smalltalk and Ruby by way of blocks. Blocks are delayed computations of the
form:
[|:x. localVar| x doSomething with: localVar]
Examples of the use of a block:
"returns 'HELLO'"
'hello' copyMutable mapBy: [|:c| c capitalize]
"returns 'Nah'"
'hello' size > 5 ifTrue: ['Yay'] False: ['Nah']
570
"returns 'HaLLO'"
'hello' copyMutable mapBy: [|:c|
c = 'e' ifTrue: [c capitalize]
False: ['a']]
Multiple expressions are separated by a period. ˆ returns immediately.
"returns An 'E'! How icky!"
'hello' copyMutable mapBy: [|:c. tmp <- ''|
tmp: c capitalize.
tmp = 'E' ifTrue: [^ 'An \'E\'! How icky!'].
c capitalize
]
Blocks are performed by sending them the message ‘value’ and inherit (delegate to) their contexts:
"returns 0"
[|x|
x: 15.
"Repeatedly sends 'value' to the first block while the result of sending 'value' to the
second block is the 'true' object"
[x > 0] whileTrue: [x: x - 1].
x
] value
Methods
Methods are like blocks but they are not within a context but instead are stored as values of slots. Unlike
Smalltalk, methods by default return their final value not ‘self’.
"Here is an object with one assignable slot 'x' and a method 'reduceXTo: y'.
Sending the message 'reduceXTo: 10' to this object will put
the object '10' in the 'x' slot and return the original object"
(|
x <- 50.
reduceXTo: y = (
[x > y] whileTrue: [x: x - 1].
self)
|)
.
Prototypes
Self has no classes. The way to get an object is to find a prototype and copy it.
| d |
d: dictionary copy.
d at: 'hello' Put: 23 + 8.
d at: 'goodbye' Put: 'No!.
"Prints No!"
( d at: 'goodbye' IfAbsent: 'Yes! ) printLine.
"Prints 31"
( d at: 'hello' IfAbsent: -1 ) printLine.
571
Further information
The Self handbook has much more information, and nothing beats hand-on experience with Self by down-
loading it from the homepage.
Smallbasic
About
SmallBASIC is a fast and easy to learn BASIC language interpreter ideal for everyday calculations, scripts
and prototypes. SmallBASIC includes trigonometric, matrices and algebra functions, a built in IDE, a
powerful string library, system, sound, and graphic commands along with structured programming syntax.
Development
SmallBASIC was originally developed by Nicholas Christopoulos in late 1999 for the Palm Pilot. Project
development has been continued by Chris Warren-Smith since around 2005.
Versions of SmallBASIC have been made for a number of early hand held devices including Franklin eBook-
man and the Nokia 770. Also various desktop versions have been released based on a variety of GUI tool-kits,
some of which have become defunct. The current supported platforms are Linux and Windows based on
SDL2 and Android based on NDK. A desktop command line version is also available, although not typically
released in binary form.
In around 2008 a large corporation released a BASIC like programming environment with a similar sounding
name. SmallBASIC is not related to this other project.
REM This is a comment
' and this is also a comment
572
End Select
REM SmallBASIC is great for experimenting with fractals and other interesting effects
Delay 3000
Randomize
ff = 440.03
For j = 0 to 20
r = rnd * 1000 % 255
b = rnd * 1000 % 255
g = rnd * 1000 % 255
c = rgb(r,b,g)
ff += 9.444
for i=0 to 25000
f += ff
x = min(xmax, -x + cos(f*i))
y = min(ymax, -y + sin(f*i))
pset x, y color c
if (i%1000==0) then
showpage
fi
573
next
Next j
REM SmallBASIC also has support for a few modern concepts such as JSON
aa = array("{\"cat\":{\"name\":\"harry\"},\"pet\":\"true\"}")
If (ismap(aa) == false) Then
throw "not an map"
End If
Print aa
PAUSE
Articles
• Getting started
• Welcome to SmallBASIC
GitHub
• Source code
• Reference snapshot
Smalltalk
• Smalltalk is an object-oriented, dynamically typed, reflective programming language.
• 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 [email protected].
Allowable characters:
• a-z
• A-Z
• 0-9
• .+/*~<>@%|&?
• blank, tab, cr, ff, lf
574
Variables:
• variables must be declared before use
• shared vars must begin with uppercase
• local vars must begin with lowercase
• reserved names: nil, true, false, self, super, and Smalltalk
Variable scope:
• Global: defined in Dictionary Smalltalk and accessible by all objects in system - Special: (reserved)
Smalltalk, super, self, true, false, & nil
• Method Temporary: local to a method
• Block Temporary: local to a block
• Pool: variables in a Dictionary object
• Method Parameters: automatic local vars created as a result of message call with params
• Block Parameters: automatic local vars created as a result of value: message call
• Class: shared with all instances of one class & its subclasses
• Class Instance: unique to each instance of a class
• Instance Variables: unique to each instance
"Comments are enclosed in quotes"
"Period (.) is the statement separator"
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"
Assignment:
| x y |
x _ 4. "assignment (Squeak) <-"
x := 5. "assignment"
x := y := z := 6. "compound assignment"
x := (y := 6) + 1.
x := Object new. "bind to allocated instance of a class"
x := 123 class. "discover the object class"
x := Integer superclass. "discover the superclass of a class"
x := Object allInstances. "get an array of all instances of a class"
x := Integer allSuperclasses. "get all superclasses of a class"
x := 1.2 hash. "hash value for object"
y := x copy. "copy object"
y := x shallowCopy. "copy object (not overridden)"
y := x deepCopy. "copy object and instance vars"
575
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"
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"
576
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"
577
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"
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 := 15 printStringBase: 16.
x := 15 storeStringBase: 16.
Blocks:
• blocks are objects and may be assigned to a variable
• value is last expression evaluated unless explicit return
• blocks may be nested
• specification [ arguments | | localvars | expressions ]
• Squeak does not currently support localvars in blocks
• max of three arguments allowed
• ˆexpression terminates block & method (exits all nested blocks)
• blocks intended for long term storage should not contain ˆ
| x y z |
x := [ y := 1. z := 2. ]. x value. "simple block usage"
x := [ :argOne :argTwo | argOne, ' and ' , argTwo.]. "set up block with argument passing"
Transcript show: (x value: 'First' value: 'Second'); cr. "use block with argument passing"
"x := [ | z | z := 1.]. *** localvars not available in squeak blocks"
578
Method calls:
• unary methods are messages with no arguments
• binary methods
• keyword methods are messages with selectors including colons standard categories/protocols: -
initialize-release (methods called for new instance)
• accessing (get/set methods)
• testing (boolean tests - is)
• comparing (boolean tests with parameter
• displaying (gui related methods)
• printing (methods for printing)
• updating (receive notification of changes)
• private (methods private to class)
• instance-creation (class methods for creating instance)
| 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"
show: 'hello ';
show: 'world';
cr.
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"
ifTrue: [Transcript show: 'ifTrue'; cr]
ifFalse: [Transcript show: 'ifFalse'; cr].
x > 10 "if else then"
ifFalse: [Transcript show: 'ifFalse'; cr]
ifTrue: [Transcript show: 'ifTrue'; cr].
Transcript
show:
(x > 10
ifTrue: ['ifTrue']
ifFalse: ['ifFalse']);
cr.
Transcript "nested if then else"
show:
(x > 10
ifTrue: [x > 5
ifTrue: ['A']
ifFalse: ['B']]
579
ifFalse: ['C']);
cr.
switch := Dictionary new. "switch functionality"
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].
result := (switch at: $B) value.
Iteration statements:
| 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"
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"
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"
580
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"
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"
581
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"
582
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"
583
y := x asBag. "convert to bag collection"
y := x asSet. "convert to set collection"
584
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"
Interval:
| b x y sum max |
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 := 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"
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"
Associations:
| x y |
x := #myVar->'hello'.
y := x key.
y := x value.
Dictionary:
585
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"
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"
((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"
Transcript show: k printString; cr].
CMRDictionary values do: [ :k | "print out values in dictionary"
Transcript show: k printString; cr].
CMRDictionary keysAndValuesDo: [:aKey :aValue | "print out keys and values"
Transcript
show: aKey printString;
space;
show: aValue printString;
586
cr].
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"
Internal Stream:
| 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].
ios position: 3.
ios position.
x := ios next.
x := ios peek.
x := ios contents.
b := ios atEnd.
FileStream:
| b x ios |
ios := FileStream newFileNamed: 'ios.txt'.
ios nextPut: $H; cr.
ios nextPutAll: 'Hello File'; cr.
'Hello File' printOn: ios.
'Hello File' storeOn: ios.
ios close.
587
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"
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"
1 to: 1000 do: [:index | y := 3.14 * index]].
b := (x <= Time now). "comparison"
588
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 := ([email protected]) rounded. "round x and y"
x := ([email protected]) 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:
Rectangle fromUser.
Pen:
| myPen |
Display restoreAfter: [
Display fillWhite.
].
589
Dynamic Message Calling/Compiling:
| receiver message result argument keyword1 keyword2 argument1 argument2 |
"unary message"
receiver := 5.
message := 'factorial' asSymbol.
result := receiver perform: message.
result := Compiler evaluate: ((receiver storeString), ' ', message).
result := (Message new setSelector: message arguments: #()) sentTo: receiver.
"binary message"
receiver := 1.
message := '+' asSymbol.
argument := 2.
result := receiver perform: message withArguments: (Array with: argument).
result := Compiler evaluate: ((receiver storeString), ' ', message, ' ', (argument storeString)).
result := (Message new setSelector: message arguments: (Array with: argument)) sentTo: receiver.
"keyword messages"
receiver := 12.
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
arguments: (Array with: argument1 with: argument2))
sentTo: receiver.
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"
590
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"
Debuging:
| a b x |
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: '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"
Misc
| x |
"Smalltalk condenseChanges." "compress the change file"
x := FillInTheBlank request: 'Prompt Me'. "prompt user for input"
Utilities openCommandKeyHelp
591
• BYTE: A Special issue on Smalltalk
• Smalltalk, Objects, and Design
• Smalltalk: An Introduction to Application Development Using VisualWorks
• Smalltalk Programming Resources
Solidity
Solidity lets you program on Ethereum, a blockchain-based virtual machine that allows the creation and
execution of smart contracts, without requiring centralized or trusted parties.
Solidity is a statically typed, contract programming language that has similarities to Javascript and C. Like
objects in OOP, each contract contains state variables, functions, and common data types. Contract-specific
features include modifier (guard) clauses, event notifiers for listeners, and custom global variables.
Some Ethereum contract examples include crowdfunding, voting, and blind auctions.
There is a high risk and high cost of errors in Solidity code, so you must be very careful to test and slowly
rollout. WITH THE RAPID CHANGES IN ETHEREUM, THIS DOCUMENT IS UNLIKELY TO STAY
UP TO DATE, SO YOU SHOULD FOLLOW THE SOLIDITY CHAT ROOM AND ETHEREUM BLOG
FOR THE LATEST. ALL CODE HERE IS PROVIDED AS IS, WITH SUBSTANTIAL RISK OF ERRORS
OR DEPRECATED CODE PATTERNS.
Unlike other code, you may also need to add in design patterns like pausing, deprecation, and throttling usage
to reduce risk. This document primarily discusses syntax, and so excludes many popular design patterns.
As Solidity and Ethereum are under active development, experimental or beta features are typically marked,
and subject to change. Pull requests welcome.
// First, a simple Bank contract
// Allows deposits, withdrawals, and balance checks
592
event LogDepositMade(address accountAddress, uint amount);
// Constructor, can receive one or many variables here; only one allowed
function AcmeBank() {
// msg provides details about the message that's sent to the contract
// msg.sender is contract caller (address of contract creator)
owner = msg.sender;
}
return balances[msg.sender];
}
if (!msg.sender.send(withdrawAmount)) {
// increment back only on fail, as may be sending to contract that
// has overridden 'send' on the receipt end
balances[msg.sender] += withdrawAmount;
}
}
return balances[msg.sender];
}
593
// otherwise, the sender's money is transferred to contract
function () {
throw; // throw reverts state to before call
}
}
// ** END EXAMPLE **
// For int and uint, can explicitly set space in steps of 8 up to 256
// e.g., int8, int16, int24
uint8 b;
int64 c;
uint248 e;
// Be careful that you don't overflow, and protect against attacks that do
// Type casting
int x = int(b);
// Types of accounts:
// Contract account: address set on create (func of creator address, num transactions sent)
// External Account: (person/external entity): address created from public key
594
// can override send by defining your own
// same as bytes, but does not allow length or index access (for now)
string n = "hello"; // stored in UTF8, note double quotes, not single
// string utility functions to be added in future
// prefer bytes32/bytes, as UTF8 uses more storage
// Type inferrence
// var does inferred typing based on first assignment,
// can't be used in functions parameters
var a = true;
// use carefully, inference may provide wrong type
// e.g., an int8, when a counter needs to be int16
// Destructuring/Tuples
(x, y) = (2, 7); // assign/swap multiple 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)
595
// multidimensional array
uint x[][5]; // arr with 5 dynamic array elements (opp order of most languages)
// Nested mappings
mapping (address => mapping (address => uint)) public custodians;
// To delete
delete balances["John"];
delete balances; // sets all elements to 0
// Enums
enum State { Created, Locked, Inactive }; // often used for state machine
State public state; // Declare variable from enum
state = State.Created;
// enums can be explicitly converted to ints
uint createdState = uint(State.Created); // 0
// Data locations: Memory vs. storage vs. stack - 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
596
// for most types, can explicitly set which data location to use
// 3. Simple operators
// Comparisons, bit operators and arithmetic operators are provided
// exponentiation: **
// exclusive or: ^
// bitwise negation: ~
// ** tx - This transaction **
tx.origin; // address of sender of the transaction
tx.gasprice; // gas price of the transaction
597
uint (a,b) = increment(1,1);
function b() {
// B. Events
// Events are notify external parties; easy to search and
// access events from outside blockchain (with lightweight clients)
// typically declare after contract parameters
// Typically, capitalized - and add Log in front to be explicit and prevent confusion
// with a function call
// Declare
event LogSent(address indexed from, address indexed to, uint amount); // note capital first letter
// Call
Sent(from, to, amount);
598
"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)
// C. Modifiers
// Modifiers validate inputs to functions such as minimal balance or user auth;
// similar to guard clause in other languages
// All basic logic blocks work - including if/else, for, while, break, continue
// return - but no switch
// For loops that are determined by user behavior, be careful - as contracts have a maximal
// amount of gas for a block of code - and will fail if that is exceeded
// For example:
for(uint x = 0; x < refundAddressList.length; x++) {
if (!refundAddressList[x].send(SOME_AMOUNT)) {
throw;
}
599
}
// 7. OBJECTS/CONTRACTS
contract Consumer {
InfoFeed feed; // points to contract on blockchain
function callFeed() {
// final parentheses call contract, can optionally add
// custom ether value or gas
feed.info.value(10).gas(800)();
}
}
// B. Inheritance
// Order matters, last inherited contract (i.e., 'def') can override parts of
// previously inherited contracts
contract MyContract is abc, def("a custom argument to def") {
// Override function
function z() {
if (msg.sender == owner) {
def.z(); // call overridden function from def
super.z(); // call immediate parent overriden function
}
}
}
// abstract function
function someAbstractFunction(uint x);
600
// cannot be compiled, so used in base/abstract contracts
// that are then implemented
// C. Import
import "filename";
import "github.com/ethereum/dapp-bin/library/iterable_mapping.sol";
// 8. OTHER KEYWORDS
// A. Throwing
// Throwing
throw; // reverts unused money to sender, state is reverted
// Can't currently catch
// B. Selfdestruct
// selfdestruct current contract, sending funds to address (often creator)
selfdestruct(SOME_ADDRESS);
// Common pattern, lets owner end the contract and receive remaining funds
function remove() {
if(msg.sender == creator) { // Only let the contract creator do this
selfdestruct(creator); // Makes contract inactive, returns funds
}
}
// A. Obfuscation
// All variables are publicly viewable on blockchain, so anything
// that is private needs to be obfuscated (e.g., hashed w/secret)
601
// 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)
// 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
// 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
contract SomeOracle {
SomeOracleCallback[] callbacks; // array of all subscribers
// Register subscriber
function addSubscriber(SomeOracleCallback a) {
callbacks.push(a);
}
602
notify(_value, _time, _info);
}
}
// F. State machines
// see example below for State enum and inState modifier
// CrowdFunder.sol
// Data structures
enum State {
Fundraising,
ExpiredRefund,
Successful
}
struct Contribution {
uint amount;
address contributor;
}
// State variables
State public state = State.Fundraising; // initialize on create
uint public totalRaised;
uint public raiseBy;
uint public completeAt;
Contribution[] contributions;
modifier isCreator() {
if (msg.sender != creator) throw;
603
_
}
// Wait 6 months after final contract state before allowing contract destruction
modifier atEndOfLifecycle() {
if(!((state == State.ExpiredRefund || state == State.Successful) &&
completeAt + 6 months < now)) {
throw;
}
_
}
function CrowdFunder(
uint timeInHoursForFundraising,
string _campaignUrl,
address _fundRecipient,
uint _minimumToRaise)
{
creator = msg.sender;
fundRecipient = _fundRecipient;
campaignUrl = _campaignUrl;
minimumToRaise = _minimumToRaise;
raiseBy = now + (timeInHoursForFundraising * 1 hours);
}
function contribute()
public
inState(State.Fundraising)
{
contributions.push(
Contribution({
amount: msg.value,
contributor: msg.sender
}) // use array, so can iterate
);
totalRaised += msg.value;
checkIfFundingCompleteOrExpired();
return contributions.length - 1; // return id
}
function checkIfFundingCompleteOrExpired() {
if (totalRaised > minimumToRaise) {
state = State.Successful;
payOut();
604
function payOut()
public
inState(State.Successful)
{
if(!fundRecipient.send(this.balance)) {
throw;
}
LogWinnerPaid(fundRecipient);
}
function getRefund(id)
public
inState(State.ExpiredRefund)
{
if (contributions.length <= id || id < 0 || contributions[id].amount == 0 ) {
throw;
}
if(!contributions[id].contributor.send(amountToSend)) {
contributions[id].amount = amountToSend;
return false;
}
return true;
}
function removeContract()
public
isCreator()
atEndOfLifecycle()
{
selfdestruct(msg.sender);
// creator gets all money that hasn't be claimed
}
function () { throw; }
}
// ** END EXAMPLE **
// Currency units
// Currency is defined using wei, smallest unit of Ether
uint minAmount = 1 wei;
uint a = 1 finney; // 1 ether == 1000 finney
// Other units, see: http://ether.fund/tool/converter
// Time units
605
1 == 1 second
1 minutes == 60 seconds
// Can multiply a variable times unit, as units are not stored in a variable
uint x = 5;
(x * 1 days); // 5 days
// Cryptography
// All strings passed are concatenated before hash action
sha3("ab", "cd");
ripemd160("abc");
sha256("def");
// 11. SECURITY
// Bugs can be disastrous in Ethereum contracts - and even popular patterns in Solidity,
// may be found to be antipatterns
// 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
// Function natspec
/// @notice information about what function does; shown when function to execute
/// @dev Function documentation for developer
606
// Function parameter/return value natspec
/// @param someParam Some description of what the param does
/// @return Description of the return value
Additional resources
• Solidity Docs
• Solidity Style Guide: Ethereum’s style guide is heavily derived from Python’s pep8 style guide.
• Browser-based Solidity Editor
• Gitter Solidity Chat room
• Modular design strategies for Ethereum Contracts
Sample contracts
• Dapp Bin
• Solidity Baby Step Contracts
• ConsenSys Contracts
• State of Dapps
Security
• Thinking About Smart Contract Security
• Smart Contract Security
• Hacking Distributed Blog
Style
• Python’s PEP8 is used as the baseline style guide, including its general philosophy
Editors
• Vim Solidity
• Editor Snippets (Ultisnips format)
Future To Dos
• New keywords: protected, inheritable
• List of common design patterns (throttling, RNG, version upgrade)
• Common security anti patterns
Feel free to send a pull request with any edits - or email nemild -/at-/ gmail
607
Standard-Ml
Standard ML is a functional programming language with type inference and some side-effects. Some of the
hard parts of learning Standard ML are: Recursion, pattern matching, type inference (guessing the right
types but never allowing implicit type conversion). Standard ML is distinguished from Haskell by including
references, allowing variables to be updated.
(* Comments in Standard ML begin with (* and end with *). Comments can be
nested which means that all (* tags must end with a *) tag. This comment,
for example, contains two nested comments. *)
(* +, - and * are overloaded so they work for both int and real. *)
(* The same cannot be said for division which has separate operators: *)
val real_division = 14.0 / 4.0 (* gives 3.5 *)
val int_division = 14 div 4 (* gives 3, rounding down *)
val int_remainder = 14 mod 4 (* gives 2, since 3*4 = 12 *)
608
(* 'andalso' and 'orelse' are called && and || in many other languages. *)
(* Actually, most of the parentheses above are unnecessary. Here are some
different ways to say some of the things mentioned above: *)
fun is_large x = x > 37 (* The parens above were necessary because of ': int' *)
val is_sad = not has_something
val pays_same_rent = rent = 1300 (* Looks confusing, but works *)
val is_wrong_phone_no = phone_no <> 5551337
val negative_rent = ~rent (* ~ rent (notice the space) would also work *)
(* Besides booleans, ints and reals, Standard ML also has chars and strings: *)
val foo = "Hello, World!\n" (* The \n is the escape sequence for linebreaks *)
val one_letter = #"a" (* That funky syntax is just one character, a *)
val _ = print foo (* You can print things. We are not interested in the *)
val _ = print combined (* result of this computation, so we throw it away. *)
(* val _ = print one_letter *) (* Only strings can be printed this way *)
val bar = [ #"H", #"e", #"l", #"l", #"o" ] (* SML also has lists! *)
(* val _ = print bar *) (* Lists are unfortunately not the same as strings *)
(* Fortunately they can be converted. String is a library and implode and size
are functions available in that library that take strings as argument. *)
val bob = String.implode bar (* gives "Hello" *)
val bob_char_count = String.size bob (* gives 5 *)
val _ = print (bob ^ "\n") (* For good measure, add a linebreak *)
(* You can put single values in front of lists of the same kind using
the :: operator, called "the cons operator" (known from Lisp). *)
val more_numbers = 13 :: numbers (* gives [13, 1, 3, 3, 7, ...] *)
val more_groups = ["Batman","Superman"] :: groups
(* Lists of the same kind can be appended using the @ ("append") operator *)
val guest_list = [ "Mom", "Dad" ] @ [ "Aunt", "Uncle" ]
609
(* This could have been done with the "cons" operator. It is tricky because the
left-hand-side must be an element whereas the right-hand-side must be a list
of those elements. *)
val guest_list = "Mom" :: "Dad" :: [ "Aunt", "Uncle" ]
val guest_list = "Mom" :: ("Dad" :: ("Aunt" :: ("Uncle" :: [])))
(* If you have many lists of the same kind, you can concatenate them all *)
val everyone = List.concat groups (* [ "Alice", "Bob", "Huey", ... ] *)
(* Tuples, on the other hand, can contain a fixed number of different things *)
val person1 = ("Simon", 28, 3.14159) (* : string * int * real *)
(* You can even have tuples inside lists and lists inside tuples *)
val likes = [ ("Alice", "ice cream"),
("Bob", "hot dogs"),
("Bob", "Alice") ] (* : (string * string) list *)
val good_bad_stuff =
(["ice cream", "hot dogs", "chocolate"],
["liver", "paying the rent" ]) (* : string list * string list *)
(* You don't need to declare their slots ahead of time. Records with
different slot names are considered different types, even if their
slot value types match up. For instance... *)
(* Functions! *)
610
fun add_them (a, b) = a + b (* A simple function that adds two numbers *)
val test_it = add_them (3, 4) (* gives 7 *)
(* Larger functions are usually broken into several lines for readability *)
fun thermometer temp =
if temp < 37
then "Cold"
else if temp > 37
then "Warm"
else "Normal"
fibonacci 4
~> fibonacci (4 - 1) + fibonacci (4 - 2)
~> fibonacci 3 + fibonacci 2
~> (fibonacci (3 - 1) + fibonacci (3 - 2)) + fibonacci 2
~> (fibonacci 2 + fibonacci 1) + fibonacci 2
~> ((fibonacci (2 - 1) + fibonacci (2 - 2)) + fibonacci 1) + fibonacci 2
~> ((fibonacci 1 + fibonacci 0) + fibonacci 1) + fibonacci 2
~> ((1 + fibonacci 0) + fibonacci 1) + fibonacci 2
~> ((1 + 0) + fibonacci 1) + fibonacci 2
~> (1 + fibonacci 1) + fibonacci 2
~> (1 + 1) + fibonacci 2
~> 2 + fibonacci 2
~> 2 + (fibonacci (2 - 1) + fibonacci (2 - 2))
~> 2 + (fibonacci (2 - 1) + fibonacci (2 - 2))
~> 2 + (fibonacci 1 + fibonacci 0)
~> 2 + (1 + fibonacci 0)
~> 2 + (1 + 0)
~> 2 + 1
~> 3 which is the 4th Fibonacci number, according to this definition
*)
(* A function cannot change the variables it can refer to. It can only
temporarily shadow them with new variables that have the same names. In this
sense, variables are really constants and only behave like variables when
dealing with recursion. For this reason, variables are also called value
bindings. An example of this: *)
val x = 42
611
fun answer(question) =
if question = "What is the meaning of life, the universe and everything?"
then x
else raise Fail "I'm an exception. Also, I don't know what the answer is."
val x = 43
val hmm = answer "What is the meaning of life, the universe and everything?"
(* Now, hmm has the value 42. This is because the function answer refers to
the copy of x that was visible before its own function definition. *)
(* Sometimes, the same computation is carried out several times. It makes sense
to save and re-use the result the first time. We can use "let-bindings": *)
fun solve2 (a : real, b : real, c : real) =
let val discr = b * b - 4.0*a*c
val sqr = Math.sqrt discr
val denom = 2.0 * a
in ((~b + sqr) / denom,
(~b - sqr) / denom) end
(* Pattern matching is also possible on composite types like tuples, lists and
records. Writing "fun solve2 (a, b, c) = ..." is in fact a pattern match on
the one three-tuple solve2 takes as argument. Similarly, but less intuitively,
you can match on a list consisting of elements in it (from the beginning of
the list only). *)
fun first_elem (x::xs) = x
fun second_elem (x::y::xs) = y
fun evenly_positioned_elems (odd::even::xs) = even::evenly_positioned_elems xs
| evenly_positioned_elems [odd] = [] (* Base case: throw away *)
| evenly_positioned_elems [] = [] (* Base case *)
(* When matching on records, you must use their slot names, and you must bind
every slot in a record. The order of the slots doesn't matter though. *)
fun rgbToTup {r, g, b} = (r, g, b) (* fn : {b:'a, g:'b, r:'c} -> 'c * 'b * 'a *)
fun mixRgbToTup {g, b, r} = (r, g, b) (* fn : {b:'a, g:'b, r:'c} -> 'c * 'b * 'a *)
612
to exist. Functions without names are called "anonymous functions" or
lambda expressions or closures (since they also have a lexical scope). *)
val is_large = (fn x => x > 37)
val add_them = fn (a,b) => a + b
val thermometer =
fn temp => if temp < 37
then "Cold"
else if temp > 37
then "Warm"
else "Normal"
(* You can create your own higher-order functions, too. Functions can also take
several arguments by "currying" them. Syntax-wise this means adding spaces
between function arguments instead of commas and surrounding parentheses. *)
fun map f [] = []
| map f (x::xs) = f(x) :: map f xs
(* map has type ('a -> 'b) -> 'a list -> 'b list and is called polymorphic. *)
(* 'a is called a type variable. *)
(* 'op' is useful when combined with high order functions because they expect
functions and not operators as arguments. Most operators are really just
infix functions. *)
val sum_of_numbers = foldl op+ 0 [1,2,3,4,5]
(* Datatypes are useful for creating both simple and complex structures *)
datatype color = Red | Green | Blue
613
fun say(col) =
if col = Red then "You are red!" else
if col = Green then "You are green!" else
if col = Blue then "You are blue!" else
raise Fail "Unknown color"
8
/ \
leaf -> 9 5
/ \
leaf -> 3 7 <- leaf
*)
(* Exceptions! *)
(* Exceptions can be raised/thrown using the reserved word 'raise' *)
fun calculate_interest(n) = if n < 0.0
then raise Domain
else n * 1.04
614
(* We can pattern match in 'handle' to make sure
a specfic exception was raised, or grab the message *)
val err_msg = failing_function [1,2] handle Fail _ => "Fail was raised"
| Domain => "Domain was raised"
| Empty => "Empty was raised"
| _ => "Unknown exception"
(* err_msg now has the value "Unknown exception" because Overflow isn't
listed as one of the patterns -- thus, the catch-all pattern _ is used. *)
(* File I/O! *)
(* Write a nice poem to a file *)
fun writePoem(filename) =
let val file = TextIO.openOut(filename)
val _ = TextIO.output(file, "Roses are red,\nViolets are blue.\n")
val _ = TextIO.output(file, "I have a gun.\nGet in the van.\n")
in TextIO.closeOut(file) end
(* This returns the unit value (in practical terms, nothing, a 0-tuple) *)
615
(* To allow returning a value, we can use the semicolon to sequence evaluations *)
fun decrement_ret x y = (x := !x - 1; y)
Further learning
• Install an interactive compiler (REPL), for example Poly/ML, Moscow ML, SML/NJ.
• Follow the Coursera course Programming Languages.
• Get the book ML for the Working Programmer by Larry C. Paulson.
• Use StackOverflow’s sml tag.
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 book from Apple is now available via iBooks.
See also Apple’s getting started guide, which has a complete tutorial on Swift.
// import a module
import UIKit
//
// MARK: Basics
//
// Xcode supports landmarks to annotate your code and lists them in the jump bar
// MARK: Section mark
// MARK: - Section mark with a separator line
// 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
var myVariable = 42
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
616
#if false
print("Not printed")
let buildValue = 3
#else
let buildValue = 7
#endif
print("Build value: \(buildValue)") // Build value: 7
/*
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.
Because Swift requires every property to have a value, even nil must be
explicitly stored as an Optional 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"
if someOptionalString != nil {
// I am not nil
if someOptionalString!.hasPrefix("opt") {
print("has the prefix")
}
/*
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 let structure -
// If let is a special structure in Swift that allows you to check if an Optional rhs holds a value, and in cas
if let someOptionalStringConstant = someOptionalString {
// has `Some` value, non-nil
if !someOptionalStringConstant.hasPrefix("ok") {
// does not have the prefix
}
}
617
// Unlike Objective-C `id`, AnyObject works with any value (Class, Int, struct, etc.)
var anyObjectVar: AnyObject = 7
anyObjectVar = "Changed value to a string, not good practice, but possible."
/*
Comment here
/*
Nested comments are also supported
*/
*/
//
// MARK: Collections
//
/*
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
// 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
//
// MARK: Control Flow
//
618
// for loop (array)
let myArray = [1, 1, 2, 3, 5]
for value in myArray {
if value == 1 {
print("One!")
} else {
print("Not one!")
}
}
// while loop
var i = 1
while i < 1000 {
i *= 2
}
// repeat-while loop
repeat {
print("hello")
} while 1 == 2
// Switch
// Very powerful, think `if` statements with syntax candy
// They support String, object instances, and primitives (Int, Double, etc)
let vegetable = "red pepper"
switch vegetable {
case "celery":
let vegetableComment = "Add some raisins and make ants on a log."
case "cucumber", "watercress":
let vegetableComment = "That would make a good tea sandwich."
case let localScopeValue where localScopeValue.hasSuffix("pepper"):
let vegetableComment = "Is it a spicy \(localScopeValue)?"
default: // required (in order to cover all possible input)
let vegetableComment = "Everything tastes good in soup."
}
//
// MARK: Functions
//
619
// in functions and can be passed around
/**
A greet operation
- A bullet in docs
- Another bullet in the docs
// guard statements
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.
guard let aNumber = Optional<Int>(7) else {
return
}
620
print("number is \(aNumber)")
}
testGuard()
// Variadic Args
func setup(numbers: Int...) {
// its an array
let _ = numbers[0]
let _ = numbers.count
}
// pass by ref
func swapTwoInts(inout a: Int, inout b: Int) {
let tempA = a
a = b
b = tempA
}
var someIntA = 7
var someIntB = 3
swapTwoInts(&someIntA, b: &someIntB)
print(someIntB) // 7
//
// MARK: Closures
//
var numbers = [1, 2, 6]
// Closure example.
// `->` separates the arguments and return type
// `in` separates the closure header from the closure body
numbers.map({
(number: Int) -> Int in
let result = 3 * number
return result
})
621
print(numbers) // [3, 6, 18]
// Trailing closure
numbers = numbers.sort { $0 > $1 }
print(numbers) // [18, 6, 3]
//
// MARK: Structures
//
// Custom subscript
subscript(index: Int) -> String {
return names[index]
}
}
//
// MARK: Error Handling
//
return "test"
}
func testTryStuff() {
// assumes there will be no error thrown, otherwise a runtime exception is raised
let _ = try! fakeFetch(7)
do {
622
// normal try operation that provides error handling via `catch` block
try fakeFetch(1)
} catch MyError.BadValue(let msg) {
print("Error message: \(msg)")
} catch {
// must be exhaustive
}
}
testTryStuff()
//
// MARK: Classes
//
// Classes, structures and its members have three levels of access control
// They are: internal (default), public, private
// Computed properties must be declared as `var`, you know, cause' they can change
var smallestSideLength: Int {
return self.sideLength - 1
}
623
// the `willSet` arg will be the variable name for the new value
willSet(someIdentifier) {
print(someIdentifier)
}
}
init(sideLength: Int) {
self.sideLength = sideLength
// always super.init last when init custom properties
super.init()
}
func shrink() {
if sideLength > 0 {
--sideLength
}
}
// cast instance
let aShape = mySquare as Shape
// compare instances, not the same as == which compares objects (equal to)
if mySquare === mySquare {
print("Yep, it's mySquare")
}
// Optional init
class Circle: Shape {
var radius: Int
override func getArea() -> Int {
return 3 * radius * radius
}
624
super.init()
if radius <= 0 {
return nil
}
}
}
//
// MARK: Enums
//
enum Suit {
case Spades, Hearts, Diamonds, Clubs
func getIcon() -> String {
switch self {
case .Spades: return "�"
case .Hearts: return "�"
case .Diamonds: return "�"
case .Clubs: return "�"
}
}
}
// Enum values allow short hand syntax, no need to type the enum type
// when the variable is explicitly declared
var suitValue: Suit = .Hearts
625
// Associate with String and Int
case Chair(String, Int)
//
// MARK: Protocols
//
protocol ShapeGenerator {
var enabled: Bool { get set }
func buildShape() -> Shape
}
func grow() {
sideLength += 2
626
//
// MARK: Other
//
print("Square: \(mySquare)")
// Generics: Similar to Java and C#. Use the `where` keyword to specify the
// requirements of the generics.
// Operators:
// Custom operators can start with the characters:
// / = - + * % < > ! & | ^ . ~
// or
// Unicode math, symbol, arrow, dingbat, and line/box drawing characters.
prefix operator !!! {}
627
shape.sideLength *= 3
return shape
}
// current value
print(mySquare.sideLength) // 4
Tcl
Tcl was created by John Ousterhout as a reusable scripting language for chip design tools he was creating.
In 1997 he was awarded the ACM Software System Award for Tcl. Tcl can be used both as an embeddable
scripting language and as a general programming language. It can also be used as a portable C library, even
in cases where no scripting capability is needed, as it provides data structures such as dynamic strings, lists,
and hash tables. The C library also provides portable functionality for loading dynamic libraries, string
formatting and code conversion, filesystem operations, network operations, and more. Various features of
Tcl stand out:
• Convenient cross-platform networking API
• Fully virtualized filesystem
• Stackable I/O channels
• Asynchronous to the core
• Full coroutines
• A threading model recognized as robust and easy to use
If Lisp is a list processor, then Tcl is a string processor. All values are strings. A list is a string format. A
procedure definition is a string format. To achieve performance, Tcl internally caches structured representa-
tions of these values. The list commands, for example, operate on the internal cached representation, and Tcl
takes care of updating the string representation if it is ever actually needed in the script. The copy-on-write
design of Tcl allows script authors can pass around large data values without actually incurring additional
memory overhead. Procedures are automatically byte-compiled unless they use the more dynamic commands
such as “uplevel”, “upvar”, and “trace”.
Tcl is a pleasure to program in. It will appeal to hacker types who find Lisp, Forth, or Smalltalk interesting,
as well as to engineers and scientists who just want to get down to business with a tool that bends to their
628
will. Its discipline of exposing all programmatic functionality as commands, including things like loops and
mathematical operations that are usually baked into the syntax of other languages, allows it to fade into the
background of whatever domain-specific functionality a project needs. It’s syntax, which is even lighter that
that of Lisp, just gets out of the way.
#! /bin/env tclsh
################################################################################
## 1. Guidelines
################################################################################
# Tcl is not Bash or C! This needs to be said because standard shell quoting
# habits almost work in Tcl and it is common for people to pick up Tcl and try
# to get by with syntax they know from another language. It works at first,
# but soon leads to frustration with more complex scripts.
# Braces are just a quoting mechanism, not a code block constructor or a list
# constructor. Tcl doesn't have either of those things. Braces are used,
# though, to escape special characters in procedure bodies and in strings that
# are formatted as lists.
################################################################################
## 2. Syntax
################################################################################
# Every line is a command. The first word is the name of the command, and
# subsequent words are arguments to the command. Words are delimited by
# whitespace. Since every word is a string, in the simple case no special
# markup such as quotes, braces, or backslash, is necessary. Even when quotes
# are used, they are not a string constructor, but just another escaping
# character.
629
# "incr" command increments the value of a variable and returns its value.
set i 0
set greeting $greeting[
incr i
incr i
incr i
]
# i is now 3
# The brace form of variable substitution handles more complex variable names
set greeting "Hello, ${first name}"
# is equivalent to
set name Neo
630
set person(name) Neo
set person(gender) male
set greeting "Hello, $person(name)"
#The full name of a variable includes its enclosing namespace(s), delimited by two colons:
set greeting "Hello $people::person1::name"
################################################################################
## 3. A Few Notes
################################################################################
# All other functionality is implemented via commands. From this point on,
# there is no new syntax. Everything else there is to learn about Tcl is about
# the behaviour of individual commands, and what meaning they assign to their
# arguments.
# Because of name resolution behaviour, it's safer to use the "variable" command to
# declare or to assign a value to a namespace. If a variable called "name" already
# exists in the global namespace, using "set" here will assign a value to the global variable
# instead of creating a new variable in the local namespace.
namespace eval people {
namespace eval person1 {
variable name Neo
}
}
################################################################################
## 4. Commands
################################################################################
631
# Math can be done with the "expr" command.
set a 3
set b 4
set c [expr {$a + $b}]
# Since "expr" performs variable substitution on its own, brace the expression
# to prevent Tcl from performing variable substitution first. See
# "http://wiki.tcl.tk/Brace%20your%20#%20expr-essions" for details.
# As noted earlier, braces do not construct a code block. Every value, even
# the third argument of the "proc" command, is a string. The previous command
# rewritten to not use braces at all:
proc greet greeting\ name return\ \"\$greeting,\ \$name!\"
# When the last parameter is the literal value, "args", it collects all extra
# arguments when the command is invoked
proc fold {cmd args} {
set res 1
foreach arg $args {
set res [$cmd $res $arg]
}
return res
}
632
fold ::tcl::mathop::* 5 3 3 ;# -> 45
# A list is a specially-formatted string. In the simple case, whitespace is sufficient to delimit value
set amounts 10\ 33\ 18
set amount [lindex $amounts 1]
# Braces and backslash can be used to format more complex values in a list. A
# list looks exactly like a script, except that the newline character and the
# semicolon character lose their special meanings. This feature makes Tcl
# homoiconic. There are three items in the following list.
set values {
one\ two
{three four}
five\{six
633
# The sure-fire way to get a properly-formmated list is to use "list" commands
set values [list one \{ three four]
lappend values { } ;# add a single space as an item in the list
# The proper way is to format the substituted value using use the "list"
# command.
set replacement [list {Archibald Sorbisol}]
set command {set name $replacement}
set command [subst $command]
eval $command
634
set cmd {{greeting name} {
return "$greeting, $name!"
}}
apply $cmd Whaddup Neo
# Define a new while command with the "proc" command. More sophisticated error
# handling is left as an exercise.
proc while {condition script} {
if {[uplevel 1 [list expr $condition]]} {
uplevel 1 $script
tailcall [namespace which while] $condition $script
}
}
# The "coroutine" command creates a separate call stack, along with a command
# to enter that call stack. The "yield" command suspends execution in that
# stack.
proc countdown {} {
#send something back to the initial "coroutine" command
yield
set count 3
635
while {$count > 1} {
yield [incr count -1]
}
return 0
}
coroutine countdown1 countdown
coroutine countdown2 countdown
puts [countdown 1] ;# -> 2
puts [countdown 2] ;# -> 2
puts [countdown 1] ;# -> 1
puts [countdown 1] ;# -> 0
puts [coundown 1] ;# -> invalid command name "countdown1"
puts [countdown 2] ;# -> 1
Reference
Official Tcl Documentation
Tcl Wiki
Tcl Subreddit
Tmux
tmux is a terminal multiplexer: it enables a number of terminals to be created, accessed, and controlled from
a single screen. tmux may be detached from a screen and continue running in the background then later
reattached.
636
kill-window # Kill current window
-t "#" # Kill target window
-a # Kill all windows
-a -t "#" # Kill all windows but the target
Key Bindings
The method of controlling an attached tmux session is via key combinations called ‘Prefix’ keys.
----------------------------------------------------------------------
(C-b) = Ctrl + b # 'Prefix' combination required to use keybinds
637
C-Up, C-Down # Resize the current pane in steps of one cell
C-Left, C-Right
Configuring ~/.tmux.conf
tmux.conf can be used to set options automatically on start up, much like how .vimrc or init.el are used.
# Example tmux.conf
# 2014.10
### General
###########################################################################
# Scrollback/History limit
set -g history-limit 2048
# Index Start
set -g base-index 1
# Mouse
set-option -g mouse-select-pane on
### Keybinds
###########################################################################
# Keybind preference
setw -g mode-keys vi
set-option -g status-keys vi
638
bind h select-pane -L
bind j select-pane -D
bind k select-pane -U
bind l select-pane -R
# Window Cycle/Swap
bind e previous-window
bind f next-window
bind E swap-window -t -1
bind F swap-window -t +1
### Theme
###########################################################################
### UI
###########################################################################
639
# Notification
setw -g monitor-activity on
set -g visual-activity on
set-option -g bell-action any
set-option -g visual-bell off
# Statusbar Adjustments
set -g status-left "#[fg=red] #H#[fg=green]:#[fg=white]#S#[fg=green] |#[default]"
References
Tmux | Home
Tmux Manual page
Gentoo Wiki
Archlinux Wiki
Display CPU/MEM % in statusbar
tmuxinator - Manage complex tmux sessions
Typescript
TypeScript is a language that aims at easing development of large scale applications written in JavaScript.
TypeScript adds common concepts such as classes, modules, interfaces, generics and (optional) static typing
to JavaScript. It is a superset of JavaScript: all JavaScript code is valid TypeScript code so it can be added
seamlessly to any project. The TypeScript compiler emits JavaScript.
This article will focus only on TypeScript extra syntax, as opposed to JavaScript.
To test TypeScript’s compiler, head to the [Playground] (http://www.typescriptlang.org/Playground) where
you will be able to type code, have auto completion and directly see the emitted JavaScript.
// There are 3 basic types in TypeScript
var isDone: boolean = false;
var lines: number = 42;
var name: string = "Anders";
640
// Alternatively, using the generic array type
var list: Array<number> = [1, 2, 3];
// For enumerations:
enum Color {Red, Green, Blue};
var c: Color = Color.Green;
// Functions are first class citizens, support the lambda "fat arrow" syntax and
// use type inference
// The following are equivalent, the same signature will be infered by the
// compiler, and same JavaScript will be emitted
var f1 = function(i: number): number { return i * i; }
// Return type inferred
var f2 = function(i: number) { return i * i; }
var f3 = (i: number): number => { return i * i; }
// Return type inferred
var f4 = (i: number) => { return i * i; }
// Return type inferred, one-liner means no return keyword needed
var f5 = (i: number) => i * i;
// Interfaces are structural, anything that has the properties is compliant with
// the interface
interface Person {
name: string;
// Optional properties, marked with a "?"
age?: number;
// And of course functions
move(): void;
}
641
// Classes - members are public by default
class Point {
// Properties
x: number;
// Functions
dist() { return Math.sqrt(this.x * this.x + this.y * this.y); }
// Static members
static origin = new Point(0, 0);
}
// Inheritance
class Point3D extends Point {
constructor(x: number, y: number, public z: number = 0) {
super(x, y); // Explicit call to the super class constructor is mandatory
}
// Overwrite
dist() {
var d = super.dist();
return Math.sqrt(d * d + this.z * this.z);
}
}
642
var s2 = new G.Square(10);
// Generics
// Classes
class Tuple<T1, T2> {
constructor(public item1: T1, public item2: T2) {
}
}
// Interfaces
interface Pair<T> {
item1: T;
item2: T;
}
// And functions
var pairToTuple = function<T>(p: Pair<T>) {
return new Tuple(p.item1, p.item2);
};
Further Reading
• [TypeScript Official website] (http://www.typescriptlang.org/)
• [TypeScript language specifications] (https://github.com/Microsoft/TypeScript/blob/master/doc/spec.md)
• [Anders Hejlsberg - Introducing TypeScript on Channel 9] (http://channel9.msdn.com/posts/Anders-
Hejlsberg-Introducing-TypeScript)
• [Source Code on GitHub] (https://github.com/Microsoft/TypeScript)
• [Definitely Typed - repository for type definitions] (http://definitelytyped.org/)
Vim
Vim (Vi IMproved) is a clone of the popular vi editor for Unix. It is a a text editor designed for speed
and increased productivity, and is ubiquitous in most unix-based systems. It has numerous keybindings for
speedy navigation to specific points in the file, and for fast editing.
643
:q # Quit vim
:w # Save current file
:wq # Save file and quit vim
:q! # Quit vim without saving file
# ! *forces* :q to execute, hence quiting vim without saving
:x # Save file and quit vim, shorter version of :wq
u # Undo
CTRL+R # Redo
# Jumping to characters
# For example,
f< # Jump forward and land on <
t< # Jump forward and land right before <
# Moving by word
644
Modes:
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
i # Puts vim into insert mode, before the cursor position
a # Puts vim into insert mode, after the cursor position
v # Puts vim into visual mode
: # Puts vim into ex mode
<esc> # 'Escapes' from whichever mode you're in, into Command mode
d # Delete
c # Change
y # Yank (copy)
v # Visually select
# 'Modifiers'
i # Inside
a # Around
NUM # Number (NUM is any number)
f # Searches for something and lands on it
t # Searches for something and stops before it
/ # Finds a string from cursor onwards
? # Finds a string before cursor
# 'Nouns'
w # Word
s # Sentence
645
p # Paragraph
b # Block
Macros
Macros are basically recordable actions. When you start recording a macro, it records every action and
command you use, until you stop recording. On invoking a macro, it applies the exact same sequence of
actions and commands again on the text selection.
qa # Start recording a macro named 'a'
q # Stop recording
@a # Play back the macro
Configuring ~/.vimrc
646
" Use case insensitive search except when using capital letters
set ignorecase
set smartcase
" Number of spaces indented when reindent operations (>> and <<) are used
set shiftwidth=4
" Enable intelligent tabbing and spacing for indentation and alignment
set smarttab
References
Vim | Home
$ vimtutor
A vim Tutorial and Primer
What are the dark corners of Vim your mom never told you about? (Stack Overflow thread)
Arch Linux Wiki
Visualbasic
Module Module1
Sub Main()
'A Quick Overview of Visual Basic Console Applications before we dive
'in to the deep end.
'Apostrophe starts comments.
'To Navigate this tutorial within the Visual Basic Complier, I've put
'together a navigation system.
'This navigation system is explained however as we go deeper into this
'tutorial, you'll understand what it all means.
Console.Title = ("Learn X in Y Minutes")
Console.WriteLine("NAVIGATION") 'Display
647
Console.WriteLine("")
Console.ForegroundColor = ConsoleColor.Green
Console.WriteLine("1. Hello World Output")
Console.WriteLine("2. Hello World Input")
Console.WriteLine("3. Calculating Whole Numbers")
Console.WriteLine("4. Calculating Decimal Numbers")
Console.WriteLine("5. Working Calculator")
Console.WriteLine("6. Using Do While Loops")
Console.WriteLine("7. Using For While Loops")
Console.WriteLine("8. Conditional Statements")
Console.WriteLine("9. Select A Drink")
Console.WriteLine("50. About")
Console.WriteLine("Please Choose A Number From The Above List")
Dim selection As String = Console.ReadLine
'The "Case" in the Select statement is optional.
'For example, "Select selection" instead of "Select Case selection"
'will also work.
Select Case selection
Case "1" 'HelloWorld Output
Console.Clear() 'Clears the application and opens the private sub
HelloWorldOutput() 'Name Private Sub, Opens Private Sub
Case "2" 'Hello Input
Console.Clear()
HelloWorldInput()
Case "3" 'Calculating Whole Numbers
Console.Clear()
CalculatingWholeNumbers()
Case "4" 'Calculating Decimal Numbers
Console.Clear()
CalculatingDecimalNumbers()
Case "5" 'Working Calculator
Console.Clear()
WorkingCalculator()
Case "6" 'Using Do While Loops
Console.Clear()
UsingDoWhileLoops()
Case "7" 'Using For While Loops
Console.Clear()
UsingForLoops()
Case "8" 'Conditional Statements
Console.Clear()
ConditionalStatement()
Case "9" 'If/Else Statement
Console.Clear()
IfElseStatement() 'Select a drink
Case "50" 'About msg box
Console.Clear()
Console.Title = ("Learn X in Y Minutes :: About")
MsgBox("This tutorial is by Brian Martin (@BrianMartinn")
Console.Clear()
Main()
Console.ReadLine()
End Select
648
End Sub
'One - I'm using numbers to help with the above navigation when I come back
'later to build it.
'Two
Private Sub HelloWorldInput()
Console.Title = "Hello World YourName | Learn X in Y Minutes"
'Variables
'Data entered by a user needs to be stored.
'Variables also start with a Dim and end with an As VariableType.
'In this tutorial, we want to know what your name, and make the program
'respond to what is said.
Dim username As String
'We use string as string is a text based variable.
Console.WriteLine("Hello, What is your name? ") 'Ask the user their name.
username = Console.ReadLine() 'Stores the users name.
Console.WriteLine("Hello " + username) 'Output is Hello 'Their name'
Console.ReadLine() 'Outputs the above.
'The above will ask you a question followed by printing your answer.
'Other variables include Integer and we use Integer for whole numbers.
End Sub
'Three
Private Sub CalculatingWholeNumbers()
Console.Title = "Calculating Whole Numbers | Learn X in Y Minutes"
Console.Write("First number: ") 'Enter a whole number, 1, 2, 50, 104, etc
Dim a As Integer = Console.ReadLine()
Console.Write("Second number: ") 'Enter second whole number.
Dim b As Integer = Console.ReadLine()
Dim c As Integer = a + b
Console.WriteLine(c)
Console.ReadLine()
'The above is a simple calculator
End Sub
'Four
Private Sub CalculatingDecimalNumbers()
Console.Title = "Calculating with Double | Learn X in Y Minutes"
'Of course we would like to be able to add up decimals.
'Therefore we could change the above from Integer to Double.
649
'Enter a floating-point number, 1.2, 2.4, 50.1, 104.9, etc
Console.Write("First number: ")
Dim a As Double = Console.ReadLine
Console.Write("Second number: ") 'Enter second floating-point number.
Dim b As Double = Console.ReadLine
Dim c As Double = a + b
Console.WriteLine(c)
Console.ReadLine()
'Therefore the above program can add up 1.1 - 2.2
End Sub
'Five
Private Sub WorkingCalculator()
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.
Console.Write("First number: ")
Dim a As Double = Console.ReadLine
Console.Write("Second number: ") 'Enter second floating-point number.
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
'By adding the below lines we are able to calculate the subtract,
'multiply as well as divide the a and b values
Console.Write(a.ToString() + " + " + b.ToString())
'We want to pad the answers to the left by 3 spaces.
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
'Six
Private Sub UsingDoWhileLoops()
'Just as the previous private sub
'This Time We Ask If The User Wishes To Continue (Yes or No?)
'We're using Do While Loop as we're unsure if the user wants to use the
'program more than once.
Console.Title = "UsingDoWhileLoops | Learn X in Y Minutes"
Dim answer As String 'We use the variable "String" as the answer is text
Do 'We start the program with
Console.Write("First number: ")
Dim a As Double = Console.ReadLine
Console.Write("Second number: ")
Dim b As Double = Console.ReadLine
650
Dim c As Double = a + b
Dim d As Double = a * b
Dim e As Double = a - b
Dim f As Double = a / b
End Sub
'Seven
Private Sub UsingForLoops()
'Sometimes the program only needs to run once.
'In this program we'll be counting down from 10.
'Eight
Private Sub ConditionalStatement()
Console.Title = "Conditional Statements | Learn X in Y Minutes"
Dim userName As String
Console.WriteLine("Hello, What is your name? ") 'Ask the user their name.
userName = Console.ReadLine() 'Stores the users name.
If userName = "Adam" Then
Console.WriteLine("Hello Adam")
Console.WriteLine("Thanks for creating this useful site")
Console.ReadLine()
Else
Console.WriteLine("Hello " + userName)
Console.WriteLine("Have you checked out www.learnxinyminutes.com")
Console.ReadLine() 'Ends and prints the above statement.
End If
651
End Sub
'Nine
Private Sub IfElseStatement()
Console.Title = "If / Else Statement | Learn X in Y Minutes"
'Sometimes it is important to consider more than two alternatives.
'Sometimes there are a good few others.
'When this is the case, more than one if statement would be required.
'An if statement is great for vending machines. Where the user enters a code.
'A1, A2, A3, etc to select an item.
'All choices can be combined into a single if block.
End Sub
End Module
References
I learnt Visual Basic in the console application. It allowed me to understand the principles of computer
programming to go on to learn other programming languages easily.
I created a more indepth Visual Basic tutorial for those who would like to learn more.
The entire syntax is valid. Copy the and paste in to the Visual Basic compiler and run (F5) the program.
Whip
Whip is a LISP-dialect made for scripting and simplified concepts. It has also borrowed a lot of functions
and syntax from Haskell (a non-related language).
These docs were written by the creator of the language himself. So is this line.
652
; Comments are like LISP. Semi-colons...
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; 1. Numbers, Strings, and Operators
; Whip has one number type (which is a 64-bit IEEE 754 double, from JavaScript).
3 ; => 3
1.5 ; => 1.5
; For example, inequality would be combining the not and equal functions.
653
(! (= 2 1)) ; => true
; More comparisons
(< 1 10) ; => true
(> 1 10) ; => false
; and their word counterpart.
(lesser 1 10) ; => true
(greater 1 10) ; => false
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; 2. Variables, Lists, and Dicts
654
; Dictionary definitions can be accessed used the `at` function
; (like strings and lists.)
(@ "my other key" my_dict) ; => 4
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; 3. Logic and Control sequences
; The `if` function is pretty simple, though different than most imperative langs.
(if true "returned if first arg is true" "returned if first arg is false")
; => "returned if first arg is true"
;;;;;;;;;
; Lambdas
;;;;;;;;;;;;;;;;
; Comprehensions
655
; `map` applies its first arg (which should be a lambda/function)
; to each item in the following arg (which should be a list)
(map (-> (x) (+ x 1)) (1 2 3)) ; => (2 3 4)
; Reduce
(reduce + (.. 1 5))
; equivalent to
((+ (+ (+ 1 2) 3) 4) 5)
;;;;;;;;;;;;;;;
; Haskell fluff
656
; Join list of strings together.
(unwords ("foo" "bar")) ; => "foobar"
(pred 21) ; => 20
(succ 20) ; => 21
For more info, check out the repo
Wolfram
The Wolfram Language is the underlying language originally used in Mathematica, but now available for use
in multiple contexts.
Wolfram Language has several interfaces: * The command line kernel interface on Raspberry Pi (just called
The Wolfram Language) which runs interactively and can’t produce graphical input. * Mathematica which
is a rich text/maths editor with interactive Wolfram built in: pressing shift+Return on a “code cell” creates
an output cell with the result, which is not dynamic * Wolfram Workbench which is Eclipse interfaced to the
Wolfram Language backend
The code in this example can be typed in to any interface and edited with Wolfram Workbench. Loading
directly into Mathematica may be awkward because the file contains no cell formatting information (which
would make the file a huge mess to read as text) - it can be viewed/edited but may require some setting up.
(* This is a comment *)
(* In Mathematica instead of using these comments you can create a text cell
and annotate your code with nicely typeset text and images *)
(* Function Call *)
(* Note, function names (and everything else) are case sensitive *)
Sin[Pi/2] (* 1 *)
(* Using a variable for the first time defines it and makes it global *)
x = 5 (* 5 *)
x == 5 (* True, C-style assignment and equality testing *)
x (* 5 *)
x = x + 5 (* 10 *)
x (* 10 *)
Set[x, 20] (* I wasn't kidding when I said EVERYTHING has a function equivalent *)
x (* 20 *)
657
cow + 5 + 10 (* 15 + cow, it'll evaluate what it can *)
% (* 15 + cow, % fetches the last return *)
% - cow (* 15, undefined variable cow cancelled out *)
moo = cow + 5 (* Beware, moo now holds an expression, not a number! *)
(* Defining a function *)
Double[x_] := x * 2 (* Note := to prevent immediate evaluation of the RHS
And _ after x to indicate no pattern matching constraints *)
Double[10] (* 20 *)
Double[Sin[Pi/2]] (* 2 *)
Double @ Sin @ (Pi/2) (* 2, @-syntax avoids queues of close brackets *)
(Pi/2) // Sin // Double(* 2, //-syntax lists functions in execution order *)
(* While Loop *)
x = 0; While[x < 2, (Print@x; x++)] (* While loop with test and body *)
(* If and conditionals *)
x = 8; If[x==8, Print@"Yes", Print@"No"] (* Condition, true case, else case *)
Switch[x, 2, Print@"Two", 8, Print@"Yes"] (* Value match style switch *)
Which[x==2, Print@"No", x==8, Print@"Yes"] (* Elif style switch *)
(* Variables other than parameters are global by default, even inside functions *)
y = 10 (* 10, global variable y *)
PrintTo[5] (* 0 1 2 3 4 *)
y (* 5, global y clobbered by loop counter inside PrintTo *)
x = 20 (* 20, global variable x *)
PrintTo[5] (* 0 1 2 3 4 *)
x (* 20, x in PrintTo is a parameter and automatically local *)
658
count (* count - still no global variable by that name *)
(* Lists *)
myList = {1, 2, 3, 4} (* {1, 2, 3, 4} *)
myList[[1]] (* 1 - note list indexes start at 1, not 0 *)
Map[Double, myList] (* {2, 4, 6, 8} - functional style list map function *)
Double /@ myList (* {2, 4, 6, 8} - Abbreviated syntax for above *)
Scan[Print, myList] (* 1 2 3 4 - imperative style loop over list *)
Fold[Plus, 0, myList] (* 10 (0+1+2+3+4) *)
FoldList[Plus, 0, myList] (* {0, 1, 3, 6, 10} - fold storing intermediate results *)
Append[myList, 5] (* {1, 2, 3, 4, 5} - note myList is not updated *)
Prepend[myList, 5] (* {5, 1, 2, 3, 4} - add "myList = " if you want it to be *)
Join[myList, {3, 4}] (* {1, 2, 3, 4, 3, 4} *)
myList[[2]] = 5 (* {1, 5, 3, 4} - this does update myList *)
(* 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
and allows y to be adjusted between 0-20 with a slider.
Only works on graphical frontends *)
Xml
XML is a markup language designed to store and transport data. It is supposed to be both human readable
and machine readable.
Unlike HTML, XML does not specify how to display or to format data, it just carries it.
Distinctions are made between the content and the markup. In short, content could be anything, markup
is defined.
659
<!-- This is a comment. It must not contain two consecutive hyphens (-). -->
<!-- Comments can span
multiple lines -->
<empty /> <!-- An element either consists an empty element tag… -->
<!-- …which does not hold any content and is pure markup. -->
An XML document
This is what makes XML versatile. It is human readable too. The following document tells us that it defines
a bookstore which sells three books, one of which is Learning XML by Erik T. Ray. All this without having
used an XML Parser yet.
<?xml version="1.0" encoding="UTF-8"?>
<!-- This is called an XML prolog. Optional, but recommended. -->
660
<bookstore>
<book category="COOKING">
<title lang="en">Everyday Italian</title>
<author>Giada De Laurentiis</author>
<year>2005</year>
<price>30.00</price>
</book>
<book category="CHILDREN">
<title lang="en">Harry Potter</title>
<author>J K. Rowling</author>
<year>2005</year>
<price>29.99</price>
</book>
<book category="WEB">
<title lang="en">Learning XML</title>
<author>Erik T. Ray</author>
<year>2003</year>
<price>39.95</price>
</book>
</bookstore>
661
<!ELEMENT price (#PCDATA)>
]>
<!-- The DTD could be declared inside the XML file itself.-->
<!DOCTYPE bookstore [
<!ELEMENT bookstore (book+)>
<!ELEMENT book (title, price)>
<!ATTLIST book category CDATA "Literature">
<!ELEMENT title (#PCDATA)>
<!ELEMENT price (#PCDATA)>
]>
<bookstore>
<book category="COOKING">
<title>Everyday Italian</title>
<price>30.00</price>
</book>
</bookstore>
Resources
• Validate your XML
Further Reading
• XML Schema Definitions Tutorial
• DTD Tutorial
• XML Tutorial
• Using XPath queries to parse XML
Yaml
YAML is a data serialisation language designed to be directly writable and readable by humans.
It’s a strict superset of JSON, with the addition of syntactically significant newlines and indentation, like
Python. Unlike Python, however, YAML doesn’t allow literal tab characters at all.
# Comments in YAML look like this.
################
# SCALAR TYPES #
################
662
# Our root object (which continues for the entire document) will be a map,
# which is equivalent to a dictionary, hash or object in other languages.
key: value
another_key: Another value goes here.
a_number_value: 100
# If you want to use number 1 as a value, you have to enclose it in quotes,
# otherwise, YAML parser will assume that it is a boolean value of true.
scientific_notation: 1e+12
boolean: true
null_value: null
key with spaces: value
# Notice that strings don't need to be quoted. However, they can be.
however: "A string, enclosed in quotes."
"Keys can be quoted too.": "Useful if you want to put a ':' in your key."
Any lines that are 'more-indented' keep the rest of their indentation -
these lines will be indented by 4 spaces.
folded_style: >
This entire block of text will be the value of 'folded_style', but this
time, all newlines will be replaced with a single space.
####################
# COLLECTION TYPES #
####################
663
: and this is its value
# YAML also allows mapping between sequences with the complex key syntax
# Some language parsers might complain
# An example
? - Manchester United
- Real Madrid
: [ 2001-01-01, 2002-02-02 ]
# Since YAML is a superset of JSON, you can also write JSON-style maps and
# sequences:
json_map: {"key": "value"}
json_seq: [3, 2, 1, "takeoff"]
#######################
# EXTRA YAML FEATURES #
#######################
# YAML also has a handy feature called 'anchors', which let you easily duplicate
# content across your document. Both of these keys will have the same value:
anchored_content: &anchor_name This string will appear as the value of two keys.
other_anchor: *anchor_name
foo: &foo
<<: *base
age: 10
bar: &bar
<<: *base
age: 20
# foo and bar would also have name: Everyone has same name
# YAML also has tags, which you can use to explicitly declare types.
explicit_string: !!str 0.5
# Some parsers implement language specific tags, like this one for Python's
# complex number type.
python_complex_number: !!python/complex 1+2j
664
# We can also use yaml complex keys with language specific tags
? !!python/tuple [5, 7]
: Fifty Seven
# Would be {(5, 7): 'Fifty Seven'} in python
####################
# EXTRA YAML TYPES #
####################
# Strings and numbers aren't the only scalars that YAML can understand.
# ISO-formatted date and datetime literals are also parsed.
datetime: 2001-12-15T02:59:43.1Z
datetime_with_spaces: 2001-12-14 21:59:43.10 -5
date: 2002-12-14
# Like Python, sets are just maps with null values; the above is equivalent to:
set2:
item1: null
item2: null
item3: null
More Resources
Zfs
ZFS is a rethinking of the storage stack, combining traditional file systems as well as volume managers into
one cohesive tool. ZFS has some specific terminology that sets it apart from more traditional storage systems,
however it has a great set of features with a focus on usability for systems administrators.
665
ZFS Concepts
Virtual Devices
A VDEV is similar to a raid device presented by a RAID card, there are several different types of VDEV’s
that offer various advantages, including redundancy and speed. In general VDEV’s offer better reliability
and safety than a RAID card. It is discouraged to use a RAID setup with ZFS, as ZFS expects to directly
manage the underlying disks.
Types of VDEV’s * stripe (a single disk, no redundancy) * mirror (n-way mirrors supported) * raidz * raidz1
(1-disk parity, similar to RAID 5) * raidz2 (2-disk parity, similar to RAID 6) * raidz3 (3-disk parity, no
RAID analog) * disk * file (not recommended for production due to another filesystem adding unnecessary
layering)
Your data is striped across all the VDEV’s present in your Storage Pool, so more VDEV’s will increase your
IOPS.
Storage Pools
ZFS uses Storage Pools as an abstraction over the lower level storage provider (VDEV), allow you to separate
the user visible file system from the physical layout.
ZFS Dataset
ZFS datasets are analogous to traditional filesystems but with many more features. They provide many of
ZFS’s advantages. Datasets support Copy on Write snapshots, quota’s, compression and de-duplication.
Limits
One directory may contain up to 2ˆ48 files, up to 16 exabytes each. A single storage pool can contain up to
256 zettabytes (2ˆ78) of space, and can be striped across 2ˆ64 devices. A single host can have 2ˆ64 storage
pools. The limits are huge.
Commands
Storage Pools
## List ZPools
$ zpool list
NAME SIZE ALLOC FREE EXPANDSZ FRAG CAP DEDUP HEALTH ALTROOT
zroot 141G 106G 35.2G - 43% 75% 1.00x ONLINE -
666
Status of zpools
## Get status information about zpools
$ zpool status
pool: zroot
state: ONLINE
scan: scrub repaired 0 in 2h51m with 0 errors on Thu Oct 1 07:08:31 2015
config:
## Getting properties from the pool properties can be user set or system provided.
$ zpool get all zroot
NAME PROPERTY VALUE SOURCE
zroot size 141G -
zroot capacity 75% -
zroot altroot - default
zroot health ONLINE -
...
667
Datasets
## Create Volume
$ zfs create -V zroot/win_vm
$ zfs list zroot/win_vm
NAME USED AVAIL REFER MOUNTPOINT
tank/win_vm 4.13G 17.9G 64K -
List datasets
## List all datasets
$ zfs list
NAME USED AVAIL REFER MOUNTPOIN
zroot 106G 30.8G 144K none
zroot/ROOT 18.5G 30.8G 144K none
zroot/ROOT/10.1 8K 30.8G 9.63G /
zroot/ROOT/default 18.5G 30.8G 11.2G /
zroot/backup 5.23G 30.8G 144K none
zroot/home 288K 30.8G 144K none
...
## List snapshots
$ zfs list -t snapshot
zroot@daily-2015-10-15 0 - 144K
zroot/ROOT@daily-2015-10-15 0 - 144K
zroot/ROOT/default@daily-2015-10-15 0 - 24.2G
zroot/tmp@daily-2015-10-15 124K - 708M
zroot/usr@daily-2015-10-15 0 - 144K
zroot/home@daily-2015-10-15 0 - 11.9G
zroot/var@daily-2015-10-15 704K - 1.42G
zroot/var/log@daily-2015-10-15 192K - 828K
zroot/var/tmp@daily-2015-10-15 0 - 152K
Rename datasets
$ zfs rename tank/root/home tank/root/old_home
668
$ zfs rename tank/root/new_home tank/root/home
Delete dataset
## Datasets cannot be deleted if they have any snapshots
zfs destroy tank/root/home
Get / set properties of a dataset
## Get all properties
$ zfs get all zroot/usr/home
NAME PROPERTY VALUE SOURCE
zroot/home type filesystem -
zroot/home creation Mon Oct 20 14:44 2014 -
zroot/home used 11.9G -
zroot/home available 94.1G -
zroot/home referenced 11.9G -
zroot/home mounted yes -
...
Snapshots
ZFS snapshots are one of the things about zfs that are a really big deal
• The space they take up is equal to the difference in data between the filesystem and its snapshot
• Creation time is only seconds
• Recovery is as fast as you can write data.
• They are easy to automate.
Actions: * Create * Delete * Rename * Access snapshots * Send / Receive * Clone
Create snapshots
“‘bash ## Create a snapshot of a single dataset zfs snapshot tank/home/sarlalian@now
669
Create a snapshot of a dataset and its children
$ zfs snapshot -r tank/home@now $ zfs list -t snapshot NAME USED AVAIL REFER MOUNTPOINT
tank/home@now 0 - 26K - tank/home/sarlalian@now 0 - 259M - tank/home/alice@now 0 - 156M -
tank/home/bob@now 0 - 156M - …
Destroy snapshots
## How to destroy a snapshot
$ zfs destroy tank/home/sarlalian@now
This following a script utilizing FreeBSD, jails and ZFS to automate provisioning a clean copy of a mysql
staging database from a live replication slave.
#!/bin/sh
670
zfs destroy -r zroot/jails/staging
zfs destroy zroot/jails/slave@staging
echo "==== Cloning the slave snapshot to the staging server ===="
zfs clone zroot/jails/slave@staging zroot/jails/staging
echo "==== Makes the staging database not pull from the master ===="
echo "STOP SLAVE;" | /usr/local/bin/mysql -u root -pmyrootpassword -h staging
echo "RESET SLAVE;" | /usr/local/bin/mysql -u root -pmyrootpassword -h staging
Additional Reading
671