Based on / inspired by Hyperpolyglot.org; released under CC BY-SA 3.0. Work in progress!
general | |||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
python | ruby | javascript | coffeescript | perl | php | cpp | d | java | scala | ocaml | haskell | lua | |
versions used | 2.7; 3.3 | 1.9; 2.0 | ECMAScript 5 | 1.7.1 | 5.14; 5.16 | 5.4; 5.5 | g++ 4.6 with -std=c++0x flag | D 2.066.0 | java 1.7 | 2.10 | 4.0 | 7.4 | 5.1 |
show version | python -V python --version | ruby --version | node --version | coffee --version | perl --version | php --version | g++ --version | dmd -v | javac -version | scala -version | ocaml -version | ghc --version | lua -v |
implicit prologue | import os, re, sys | none | use strict; | #include <iostream> #include <string> using namespace std; | |||||||||
shebang | cat <<EOF > hello.scala #!/bin/sh exec scala $0 $@ !# println("hello") EOF chmod +x hello.scala ./hello.scala | cat <<EOF > hello.ml #!/usr/bin/env ocaml print_endline "hello";; EOF chmod +x hello.ml ./hello.ml | cat <<EOF > hello.hs #!/usr/bin/env runghc main = putStrLn "hello" EOF chmod +x hello.hs ./hello.hs | ||||||||||
grammar and invocation | |||||||||||||
python | ruby | javascript | coffeescript | perl | php | cpp | d | java | scala | ocaml | haskell | lua | |
hello world | (2.x:) print "Hello, world!" (3.x:) print("Hello, world!") | print "Hello, world!\n" | cat hello.cpp #include <iostream> using namespace std; int main(int argc, char** arg) { cout << "Hello, World!" << endl; } g++ -std=c++0x hello.cpp ./a.out | cat hello.d import std.stdio; void main() { writeln("Hello world!"); } | cat Hello.java public class Hello { public static void main(String[] args) { System.out.println("Hello, World!"); } } javac Hello.java java Hello | (script:) println("Hello, world!") (object:) object Hello { def main(args: Array[String]) { println("Hello, world!") } } (object, using App trait:) object Hello extends App { println("Hello, world!") } | main = putStrLn "hello" | ||||||
file suffixes / source, header, object file | .py (none) .pyc | .pl | foo.cpp foo.h foo.o | foo.d | Foo.java none Foo.class Foo.java must define a single top level class Foo | .scala (none) .class | .hs .lhs (none) .o | ||||||
bytecode compiler and interpreter | cat <<EOF > Hello.scala object Hello extends App { println("hello") } EOF scalac Hello.scala scala Hello | echo 'print_endline "hello";;' > hello.ml ocamlc -o hello hello.ml ocamlrun hello | |||||||||||
native compiler | echo 'print_endline "hello";;' > hello.ml ocamlopt hello.ml -o hello ./hello | echo 'main = putStrLn "hello"' > hello.hs ghc -o hello hello.hs ./hello | |||||||||||
interpreter | python foo.py | ruby foo.rb | node foo.js | coffee foo.coffee | perl foo.pl | php -f foo.php | (sort of) dmd -run foo.d | echo 'println("hello")' > hello.scala scala hello.scala | echo 'print_endline "hello"' > hello.ml ocaml hello.ml | echo 'main = putStrLn "hello"' > hello.hs runghc hello.hs | lua foo.lua | ||
repl | python | irb | node | coffee | perl -de 0 | php -a | scala | lua | |||||
command line program | python -c 'print("hi")' | ruby -e 'puts "hi"' | node -e 'var sys = require("sys"); sys.puts("hi world!");' | coffee -e 'var sys = require("sys"); sys.puts("hi world!");' | perl -e 'print("hi\n")' | php -r 'echo "hi\n";' | lua -e 'print("hi world!")' | ||||||
library which is always imported | java.lang scala | Pervasives | Prelude | ||||||||||
block delimiters | : and offside rule | {} do end | {} | indentation | {} | {} | { } | { } | { } | { } | ( expr ; … ) begin expr ; … end | offside rule or { } | do end |
statement separator | newline or ; newlines not separators inside (), [], {}, triple quote literals, or after backslash: \ | newline or ; newlines not separators inside (), [], {}, ``, '', "", or after binary operator or backslash: \ | ; or newline newline not separator inside (), [], {}, "", '', or after binary operator newline sometimes not separator when following line would not parse as a valid statement | ; | ; statements must be semicolon terminated inside {} | ; | ; | ; | ; or sometimes newline | ;; | next line has equal or less indentation, or ; | newline or ; newline not separator inside {}, (), or after binary operator. newline can be put in "" or '' if preceded by backslash | |
top level statements | A source file will normally have #include directives at the top, followed by declarations, definitions, and namespaces containing declarations and definitions. After the preprocessor has finished processing a source file, the compilation unit will only contain declarations, definitions, and namespaces at the top level. | each file contains the following elements in order: (1) optional package directive (2) zero or more import directives (3) one public class definition and zero or more private class definitions | |||||||||||
source code encoding | (Python 3 source is UTF-8 by default) # -*- coding: utf-8 -*- | Ruby 2.0 source is UTF-8 by default # -*- coding: utf-8 -*- | use utf8; | ||||||||||
end-of-line comment | # comment | # comment | // comment | # comment | # comment | // comment # comment | // comment | // comment | // comment | // comment | -- comment | -- comment | |
multiple line comment | (use triple quote string literal:) '''comment line another line''' | =begin comment line another line =end | /* comment another comment */ | ### comment another comment (will be preserved in generated JavaScript) ### | =for comment line another line =cut | /* comment line another line */ | /* comment another comment */ | /* comment another comment */ | /* comment another comment */ | /* comment another comment */ | (* comment another comment *) | {- comment another comment -} | --[[ commented out also commented out ]] |
variables and expressions | |||||||||||||
python | ruby | javascript | coffeescript | perl | php | cpp | d | java | scala | ocaml | haskell | lua | |
local, modifiable variable | (in function body:) v = None a, d = [], {} x = 1 y, z = 2, 3 | v = nil a, d = [], {} x = 1 y, z = 2, 3 | var x = 1; | x = 1 | my $v; my (@a, %d); my $x = 1; my ($y, $z) = (2, 3); | (in function body:) $v = NULL; $a = []; $d = []; $x = 1; list($y, $z) = [2, 3]; | int i; int j = 3; int k(7); | int i; int j = 3; | int i; int j = 3; | var n = 3 n = 4 n + 7 | let n = ref 3;; n := 4;; !n + 7;; | (Haskell is purely functional and all normal variables are immutable. A maximally functional version of mutable variables may be simulated with Control.Monad.Trans.State, of the transformers package:) import Control.Monad.Trans.State evalState (do set 4 modify (+1) fmap (+7) get) 3 (runState returns (result, state); evalState returns result; execState returns state) (A more destructive version uses STRefs in a STRef monad or IORefs in the IO monad:) import Data.IORef do n <- newIORef 3 writeIORef n 4 fmap (+7) $ readIORef n import Data.STRef import Control.Monad.ST runST $ do n <- newSTRef 3 writeSTRef n 4 fmap (+7) $ readSTRef n | local x = 1 |
uninitialized local variable (when accessed) | raises NameError | raises NameError | undefined | error under use strict | NULL | The behavior is undefined. Most implementations do not zero-initialize stack variables, so the value will be whatever happened to be in memory. | zero initialized | nil | |||||
regions which define lexical scope | nestable (read only): function or method body | top level: file class block module block method body nestable: anonymous function body anonymous block | top level: file nestable: function body anonymous function body anonymous block | top level: function or method body nestable (with use clause): anonymous function body | |||||||||
global variable | g1, g2 = 7, 8 def swap_globals(): global g1, g2 g1, g2 = g2, g1 | $g1, $g2 = 7, 8 def swap_globals $g1, $g2 = $g2, $g1 end | (assign without using var) g = 1; function incr_global () { g++; } | our ($g1, $g2) = (7, 8); sub swap_globals { ($g1, $g2) = ($g2, $g1); } | list($g1, $g2) = [7, 8]; function swap_globals() { global $g1, $g2; list($g1, $g2) = [$g2, $g1]; } | (in foo.cpp and outside of any function or class definition:) int foo = 7; (in bar.cpp and outside of any function or class definition:) extern int foo; | foo/Foo.java: package foo; (globals must be declared inside a class:) public class Foo { public static int bar; } UseFoo.java: import foo.Foo; public class UseFoo { public static void main(String[] args) { System.out.println(Foo.bar); } } | (assign without using local) g = 1 function incr_global() g = g + 1 end | |||||
uninitialized global variable (when accessed) | raises NameError | raises NameError | undefined | error under use strict otherwise undef | NULL | Zero initialized: numeric types and pointers are set to zero. Classes, structs, and arrays have all of their members or elements zero-initialized recursively. | Zero initialized. | nil | |||||
constant | (uppercase identifiers constant by convention) PI = 3.14 | (warning if capitalized identifier is reassigned) PI = 3.14 | use constant PI => 3.14; | define("PI", 3.14); | const int i = 7; | (compile-time/manifest constant:) enum int i = 7; (must be constant in the entire program:) immutable int j = 7; (not changeable through this pointer:) const int k = 7; | final int i = 7; | (evaluates 1 + 2 once:) val n = 1 + 2 (evaluates 1 + 2 each time n is used:) def n = 1 + 2 | let n = 1 + 2;; | n = 3 | |||
unit type and value | Unit () | unit () | () () | ||||||||||
assignment | (assignments can be chained but otherwise don't return values:) v = 1 | v = 1 | x = 1; | x = 1 | $v = 1; | $v = 1; | int n; n = 3; | int n; n = 3; | int n; n = 3; | val v = 1 var w = 0 w = 1 (returns Unit) (assigns the same value to multiple variables; only works when variables are first defined:) val v1, v2 = 0 var v3, v4 = 0 | x = 1 | ||
parallel assignment | x, y, z = 1, 2, 3 raises ValueError: x, y = 1, 2, 3 raises ValueError: x, y, z = 1, 2 | x, y, z = 1, 2, 3 (3 is discarded:) x, y = 1, 2, 3 (z set to nil:) x, y, z = 1, 2 | ($x, $y, $z) = (1, 2, 3); # 3 is discarded: ($x, $y) = (1, 2, 3); # $z set to undef: ($x, $y, $z) = (1, 2); | list($x, $y, $z) = [1 ,2, 3]; (3 is discarded:) list($x, $y) = [1, 2, 3]; ($z set to NULL:) list($x, $y, $z) = [1, 2]; | (only works when variables are first defined:) val (x, y, z) = (1, 2, 3) | x, y, z = 1, 2, 3 (3 is discarded:) x, y = 1, 2, 3 (z is set to nil:) x, y, z = 1, 2 | |||||||
swap | x, y = y, x | x, y = y, x | var tmp = x; x = y; y = tmp; | [x, y] = [y, x] | ($x, $y) = ($y, $x); | list($x, $y) = [$y, $x]; | x, y = y, x | ||||||
compound assignment / arithmetic, string, logical, bit | (do not return values:) += -= *= /= //= %= **= += *= &= |= ^= <<= >>= &= |= ^= | += -= *= /= (none) %= **= += *= &&= ||= ^= <<= >>= &= |= ^= | += -= *= (none) /= %= **= .= x= &&= ||= ^= <<= >>= &= |= ^= | += -= *= (none) /= %= **= .= (none) &= |= (none) <<= >>= &= |= ^= | += -= *= /= %= <<= >>= &= ^= |= | += -= *= /= %= ^^= <<= >>= &= ^= |= | += -= *= /= %= <<= >>= &= ^= |= >>= is arithmetic right shift, >>>= is logical right shift | += -= *= /= (none) %= (none) += *= &= |= ^= <<= >>= &= |= ^= | |||||
increment and decrement | (just use x += 1 and x -= 1) | x = 1 (x and y not mutated:) y = x.succ z = y.pred | my $x = 1; my $y = ++$x; my $z = --$y; | $x = 1; $y = ++$x; $z = --$y; | int n = 1; int one = n++; int three = ++n; int two = --n; | int n = 1; int one = n++; int three = ++n; int two = --n; | int n = 1; int one = n++; int three = ++n; int two = --n; | ||||||
address | int i(3); int* ip = &i; | none | |||||||||||
dereference | int i(3); int* ip = &i; int i2 = *ip + 1; | none | |||||||||||
type size | cout << sizeof(int) << endl; cout << sizeof(int*) << endl; | (int*).sizeof | none | ||||||||||
address arithmetic | none | ||||||||||||
unique pointer | none | ||||||||||||
reference count pointer | none | ||||||||||||
weak pointer | none | ||||||||||||
allocate heap | int* ip = new int; | (Primitive types are stack allocated. Use a wrapper class to store on the heap:) Integer i = new Integer(0); | |||||||||||
uninitialized heap | Memory allocated by the new operator is zero-initialized. | zero-initialized | |||||||||||
free heap | delete[] a; | garbage collected | |||||||||||
null | None | nil | null | undef | NULL (case insensitive) | NULL | test v is null (Nullable!T:) v.isNull | null | None (type Option[T]) null (generally discouraged, but needed for Java interop) | None (type 'a option) | Nothing (type Maybe a) | nil | |
nullable type | import std.typecons; Nullable!T (usage:) Nullable!int a; a = 5; a.nullify(); (set to null) | val list = List(Some(3), None, Some(-4)) | type list_option_int = int option list;; let list = [Some 3; None; Some (-4)];; | list = [Just 3, Nothing, Just (-4)] | |||||||||
null test | v is None (slightly preferable to ==, as the latter can be overridden) | v == nil v.nil? | typeof v === "undefined" && v === null | v? | ! defined $v | is_null($v) ! isset($v) | v.isDefined (Option[T]) v eq null (Java null) | match foo with | None -> true | _ -> false;; | import Data.Maybe isJust v | v == nil | |||
coalesce | foo = undefined foo ? 4 | string s1 = s2 || "was null"; | String s1 = s2 == null ? "was null" : s2; | throws Predef.NoSuchElementException if v is None: v.get (0 if v is None:) v.getOrElse(0) | match foo with | None -> 0 | Some n -> n;; | import Data.Maybe let foo = Just 3 let intId x = x raises exception if Nothing: fromJust foo evaluates to 0 if Nothing: maybe 0 intId foo fromMaybe 0 foo | |||||||
nullif | match foo with | -999 -> None | n -> Some n;; | ||||||||||||
conditional expression | x if x > 0 else -x | x > 0 ? x : -x | x > 0 ? x : -x | if x > 0 then x else -x | $x > 0 ? $x : -$x | $x > 0 ? $x : -$x | x > 0 ? x : -x | val n = -3 if (n < 0) -n else n | let n = -3;; let absn = if n < 0 then -n else n;; | n = -3 let absn = if n < 0 then -n else n | none | ||
branch type mismatch | (expression has type Any:) if (true) { "hello" } else { 3 } | compilation error: if true then "hello" else 3;; | compilation error: if True then "hello" else 3 | ||||||||||
expression type declaration | 1: Double | float 1 | 1 :: Double | ||||||||||
let ... in ... | val z = { val x = 3.0 val y = 2.0 * x x * y } | let z = let x = 3.0 in let y = 2.0 *. x in x *. y;; | z = let x = 3.0 y = 2.0 * x in x * y | ||||||||||
where | none | z = x * y where x = 3.0 y = 2.0 * x | |||||||||||
arithmetic and logic | |||||||||||||
python | ruby | javascript | coffeescript | perl | php | cpp | d | java | scala | ocaml | haskell | lua | |
boolean type | bool | bool | bool | boolean | Boolean | bool | Bool | ||||||
true and false | True False | true false | true false | true on yes false off no | 1 "" | TRUE FALSE (case insensitive) | true false | true false | true false | true false | true false | True False | true false |
falsehoods | False None 0 0.0 '' [] {} | false nil | false null undefined "" 0 NaN | undef 0 0.0 "" "0" () | FALSE NULL 0 0.0 "" "0" [] | false 0 0.0 NULL | false 0 0.0 NULL | false | false | False | false nil | ||
logical operators | and or not | && || ! (lower precedence:) and or not | && || ! | && and || or ! not | && || ! (lower precedence:) and or xor not | && || ! (lower precedence:) and or xor | && || ! and or not | && || ! | && || ! | && || ! | && || not | && || not | and or not |
relational expression | x > 3 | x > 3 | |||||||||||
relational operators | (relational operators are chainable:) == != > < >= <= | == != > < >= <= | === !== < > >= <= (perform type coercion:) == != | (numbers only:) == != > < >= <= | == != or <> > < >= <= (no conversion:) === !== | == != < > <= >= | == != < > <= >= !<>= <> <>= !<= !< !>= !> !<> (handles NaN differently) is !is | == != < > <= >= | == != < > <= >= | = <> < > <= >= [== !=] (warning: == and != test for "physical equality") | == /= < > <= >= | == ~= < > >= <= | |
compare strings | (relational operators are chainable:) == != > < >= <= | == != > < >= <= | eq ne gt lt ge le | == != or <> > < >= <= (no conversion:) === !== | string s1("hello"); string s2("world"); (negative if s1 lexically before s2; zero if s1 and s2 are equal:) int result1 = s1.compare(s2); bool result2 = s1 == s2; | == != < > <= >= | "hello".compareTo("world") | == != < > <= >= | == /= < > <= >= | ||||
min and max | min(1, 2, 3) max(1, 2, 3) min([1, 2, 3]) max([1, 2, 3]) | [1, 2, 3].min [1, 2, 3].max | Math.min(1, 2, 3) Math.max(1, 2, 3) Math.min.apply(Math, [1, 2, 3]) Math.max.apply(Math, [1, 2, 3]) | use List::Util qw(min max); min(1, 2, 3); max(1, 2, 3); @a = (1, 2, 3); min(@a); max(@a); | min(1, 2, 3) max(1, 2, 3) $a = [1, 2, 3] min($a) max($a) | math.min 1 2 (or) 1 min 2 math.max 1 2 (or) 1 max 2 List(1, 2, 3).min List(1, 2, 3).max | min 1 2 max 1 2 | min 1 2 max 1 2 | math.min(1, 2, 3) math.max(1, 2, 3) math.min(unpack({1 ,2 ,3})) math.max(unpack({1, 2, 3})) | ||||
three value comparison | (removed from Python 3:) cmp(0, 1) cmp('do', 're') | 0 <=> 1 "do" <=> "re" | 0 <=> 1 "do" cmp "re" | (defined in scala.math.Ordered[A]:) 0 compare 1 "do" compare "re" | 0 `compare` 1 (returns value of type Ordering, one of LT, EQ, or GT) | ||||||||
integer type | int | (all numbers are floats, unless Math::BigInt is used) | signed char n1; (1+ bytes) short int n2; (2+ bytes) int n3; (2+ bytes) long int n4; (4+ bytes) long long int n5; (4+ bytes) | byte n1; (1 byte) short n2; (2 bytes) int n3; (4 bytes) long n4; (8 bytes) | byte n1; (1 byte) short n2; (2 bytes) int n3; (4 bytes) long n4; (8 bytes) | Int (type of integer literals) Byte Short Long (other modular types) BigInt (arbitrary precision type) | int (other integer types:) int32 int64 nativeint | Int (fixed-width) Integer (arbitrary length) | |||||
integer literal | -4 | -4 | -4 | int, int64, and nativeint literals: 12 12L 12n (literals can contain underscores:) 1_000_000 (this parses as an expression:) -4 | an expression, not a literal: -4 | ||||||||
unsigned type | unsigned char n1; (1+ bytes) unsigned short int n2; (2+ bytes) unsigned int n3; (2+ bytes) unsigned long int n4; (4+ bytes) unsigned long long int n5; (4+ bytes) | ubyte n1; (1 byte) ushort n2; (2 bytes) uint n3; (4 bytes) ulong n4; (8 bytes) | char n1; (2 bytes) | ||||||||||
float type | float | scalar | float x1; (4 bytes) double x2; (8 bytes) long double x3; (16 bytes) | float x1; (4 bytes) double x2; (8 bytes) real x3; (largest in hardware) | float x1; (4 bytes) double x2; (8 bytes) | (type of float literals:) Double (other types:) Float | float | Double | |||||
fixed type | (none) | (none) | none | ||||||||||
arithmetic expression | 1 + 3 | 1 + 3 | |||||||||||
arithmetic operators / addition, subtraction, multiplication, float division, quotient, remainder | + - * (see note) // % (Python 2 does not have an operator which performs float division on integers. In Python 3 / always performs float division.) | + - * x.fdiv(y) / % | + - * / (none) % | + - * / (none) % | + - * / (none) % | + - * / % | + - * / % ^^ | + - * / % | + - * / (none) % | + - * / (none) % ^ | |||
integer operators | (as above) | + - * / % | + - * / mod (mod is an infix operator, and is signed like % or rem in other languages) | + - * `quot` `rem` `div` `mod` (the last four are functions, not infix operators, although they are often used as infix operators by surrounding with backquotes. quot truncates towards 0 and rem's value has the same sign as the dividend; div truncates down and mod returns a nonnegative result.) | |||||||||
float operators | (as above) | (as above) | + - * / | +. -. *. /. | + - * / | ||||||||
add integer and float | (automatically coerced) | 3 + 7.0 | float 3 +. 7.0 | (integer literals are parsed as floats in such contexts:) 3 + 7.0 (integers can be converted with fromIntegral:) x = 3 :: Int fromIntegral x + 7.0 | |||||||||
integer division | 13 // 5 | 13 / 5 | Math.floor(x / y) | int(13 / 5) | (int)(13 / 5) | (evaluates to 2:) 7 / 3 | (evaluates to 2:) 7 / 3 | (evaluates to 2:) 7 / 3 | 13 / 5 | math.floor(x / y) | |||
divmod | q, r = divmod(13, 5) | q, r = 13.divmod(5) | 7 / 3 7 % 3 (BigInts only:) BigInt(7) /% BigInt(3) | 7 / 3 7 mod 3 | 7 `quotRem` 3 7 `divMod` 3 | ||||||||
integer division by zero | raises ZeroDivisionError | raises ZeroDivisionError | returns assignable value Infinity, NaN, or -Infinity depending upon whether dividend is positive, zero, or negative. There are literals for Infinity and NaN. | error | returns FALSE with warning | process sent a SIGFPE signal | throws java.lang.ArithmeticException | java.lang.ArithmeticException | raises Division_by_zero | Exception: divide by zero | returns assignable value inf, nan, or -inf depending upon whether dividend is positive, zero, or negative. There are no literals for any of these values. | ||
float division | float(13) / 5 (Python 3:) 13 / 5 | 13.to_f / 5 (or) 13.fdiv(5) | x / y | 13 / 5 | 13 / 5 | 7 / static_cast<float>(3) | 7 / (float)3 | 7.toDouble / 3 (type coercion built into Int) (7: Double) / 3 (type ascription, fueled by implicits) | float 7 /. float 3 | 7 / 3 | x / y | ||
float division by zero | raises ZeroDivisionError | returns -Infinity, NaN, or Infinity | (same behavior as for integers) | error | returns FALSE with warning | positive dividend: inf zero dividend: nan negative dividend: -inf There are no portably defined literals or constants for the above values. | positive dividend: double.infinity zero dividend: double.nan negative dividend: -double.infinity | positive dividend: Float.POSITIVE_INFINITY zero dividend: Float.NaN negative dividend: Float.NEGATIVE_INFINITY (constants with same names defined in Double) | evaluates to Infinity, NaN, or -Infinity, values which do not have literals | infinity nan or neg_infinity | evaluates to Infinity, NaN, or -Infinity, values which do not have literals | same behavior as for integers | |
power | 2**32 | 2**32 | Math.pow(2, 32) | 2**32 | pow(2, 32) | #include <cmath> double x = pow(2.0, 32.0); | 2 ^^ 20 2.0 ^^ 32.0 | Math.pow(2.0, 32.0); | math.pow(2, 32) | 2.0 ** 32.0 | 2 ^ 32 (integer powers only) 2 ^^ 32 (fractional base, integer powers only) 2 ** 32 (same-type floating base and exponent) | 2 ^ 32 math.pow(2, 32) | |
sqrt | import math math.sqrt(2) | include Math sqrt(2) | Math.sqrt(2) | sqrt(2) | sqrt(2) | #include <cmath> double x = sqrt(2); | Math.sqrt(2) | math.sqrt(2) | sqrt 2.0 | sqrt 2 | math.sqrt(2) | ||
sqrt -1 | raises ValueError: import math math.sqrt(-1) returns complex float: import cmath cmath.sqrt(-1) | raises Math::DomainError | NaN | error unless use Math::Complex in effect | NaN | nan | nan | Double.NaN | math.sqrt(-1) evaluates to NaN, a value which has no literal | sqrt (-1.0): nan | sqrt (-1) (evaluates to NaN, a value which has no literal) | nan | |
transcendental functions | from math import exp, log, sin, cos, tan, asin, acos, atan, atan2 | include Math exp log sin cos tan asin acos atan atan2 | Math.exp Math.log Math.sin Math.cos Math.tan Math.asin Math.acos Math.atan Math.atan2 | use Math::Trig qw( tan asin acos atan); exp log sin cos tan asin acos atan atan2 | exp log sin cos tan asin acos atan atan2 | #include <cmath> exp log log2 log10 sin cos tan asin acos atan atan2 | import std.math; exp log log2 log10 sin cos tan asin acos atan atan2 | Math.exp Math.log none Math.log10 Math.sin Math.cos Math.tan Math.asin Math.acos Math.atan Math.atan2 | math.exp math.log math.sin math.cos math.tan math.asin math.acos math.atan math.atan2 | exp log sin cos tan asin acos atan atan2 | exp log sin cos tan asin acos atan atan2 | math.exp math.log math.sin math.cos math.tan math.asin math.acos math.atan math.atan2 | |
transcendental constants / π and e | import math math.pi math.e | include Math PI E | Math.PI Math.E | M_PI M_E | #include <cmath> double e = M_E; double pi = M_PI; | import std.math; E PI | Math.E Math.PI | math.Pi math.E | 4.0 *. atan 1.0 exp 1.0 | pi exp 1 | math.pi math.exp(1) | ||
float truncation | import math int(x) int(round(x)) math.ceil(x) math.floor(x) | x.to_i x.round x.ceil x.floor | (none) Math.round(3.1) Math.floor(3.1) Math.ceil(3.1) | # cpan -i Number::Format use Number::Format 'round'; use POSIX qw(ceil floor); int($x) round($x, 0) ceil($x) floor($x) | (int)$x round($x) ceil($x) floor($x) | #include <cmath> double x = 3.7; long trnc = static_cast<long>(x); long rnd = round(x); long flr = floorl(x); long cl = ceill(x); | double x = 3.7; long trnc = cast(long)(x); | (long)3.77 Math.round(3.77) (long)Math.floor(3.77) (long)Math.ceil(3.77) | 3.14.toInt (or) 3.14.toLong 3.14.round 3.14.floor (returns Double) 3.14.ceil (returns Double) | truncate 3.14 (none) floor 3.14 (returns float) ceil 3.14 (returns float) | truncate 3.14 round 3.14 floor 3.14 ceiling 3.14 | none none math.floor(3.1) math.ceil(3.1) | |
absolute value / and signum | abs(x) import math math.copysign(1, x) (returns 1.0 or -1.0 for positive or negative floating zero; int zero is coerced to positive zero) | x.abs | Math.abs(-3) | abs($x) | abs($x) | #include <cmath> (fabs()) #include <cstdlib> (abs()) int n = -7; int absn = abs(n); double x = -7.77; double absx = fabs(x); | Math.abs(-7) Math.abs(-7.77) | math.abs(-7) math.signum(-7) | abs (-7) abs_float (-7.0) no signum | abs (-7) signum (-7) | math.abs(-3) | ||
arbitrary length integer | (automatically promoted) | use Math::BigInt; my $n = Math::BigInt->new("7"); my $m = Math::BigInt->new("12"); ("magically" makes almost all integers arbitrary-length:) use bigint; | val n = BigInt(7) val m = BigInt(12) | open Big_int;; let n = big_int_of_int 7;; let m = big_int_of_int 12;; | (Integer is arbitrary length type, and assumed by default for numbers in contexts where no other type restrictions can be inferred.) let n = 7 :: Integer (Note that an integer literal is polymorphic, as is a function defined as a single integer literal.) let m = 12 | ||||||||
arbitrary length integer operators | (as above) | (under use Math::BigInt without use bigint:) (destructive on left operand:) $n->badd($m); $n->bsub($m); $n->bmul($m); $n->bdiv($m); $n->bmod($m); $n->bcmp($m); (returns -1, 0, 1) | n + m n - m n * m n / m n % m n == m n < m n < m n <= m n >= m | add_big_int n m sub_big_int n m mult_big_int n m div_big_int n m (* quotient *) mod_big_int n m eq_big_int n m lt_big_int n m gt_big_int n m le_big_int n m ge_big_int n m | n + m n - m n * m quot n m (or) div n m rem n m (or) mod n m n == m n < m n > m n <= m n >= m | ||||||||
integer overflow | (becomes arbitrary length integer of type long) | (becomes arbitrary length integer of type Bignum) | (all numbers are floats) | converted to float; use Math::BigInt to create arbitrary length integers | converted to float | modular arithmetic The C standard does not define behavior for signed integers, however. | modular arithmetic, see http://dlang.org/expression.html#AddExpression | modular arithmetic | modular arithmetic for all types except BigInt | modular arithmetic | Int wraps; Integer is arbitrary length | all numbers are floats | |
float overflow | raises OverflowError | Infinity | Infinity | inf | INF | no behavior defined by standard; many implementations return inf | IEEE 754 | Float.POSITIVE_INFINITY | evaluates to Infinity, a value which has no literal | infinity | evaluates to Infinity, a value which has no literal | inf | |
float limits / largest finite float, smallest positive float | #include <cfloat> FLT_MAX FLT_MIN DBL_MAX DBL_MIN LDBL_MAX LDBL_MIN | float.max float.min_normal double.max double.min_normal real.max real.min_normal | Float.MAX_VALUE Float.MIN_VALUE Double.MAX_VALUE Double.MIN_VALUE | ||||||||||
rational type | fractions.Fraction | Ratio Integer | |||||||||||
rational construction | from fractions import Fraction x = Fraction(22, 7) | require 'rational' x = Rational(22, 7) | use Math::BigRat; my $x = Math::BigRat->new("22/7"); | import Data.Ratio 1 % 7 (1 / 7) :: Rational | |||||||||
rational decomposition | x.numerator x.denominator | x.numerator x.denominator | $x->numerator(); $x->denominator(); | import Data.Ratio numerator (1 % 7) denominator (1 % 7) | |||||||||
complex type | complex | Complex.t | Complex Double | ||||||||||
complex constants | Complex.zero Complex.one Complex.i | ||||||||||||
complex construction | z = 1 + 1.414j | require 'complex' z = 1 + 1.414.im | use Math::Complex; my $z = 1 + 1.414 * i; | #include <complex> complex<double> z(1.0, 2.0); | (built-in (deprecated)) cfloat c = 1 + 3.14 * 1.0i; cdouble z = 1 + 3.14 * 1.0i; (modern) import std.complex; auto c = complex(2.0); auto z = complex(1, 3.14L); | {Complex.re=1.0; Complex.im=2.0} | import Data.Complex 1 :+ 2.0 | ||||||
complex decomposition / real and imaginary component, argument, absolute value, conjugate | import cmath z.real z.imag cmath.phase(z) abs(z) z.conjugate() | z.real z.imag z.arg z.abs z.conj | Re($z); Im($z); arg($z); abs($z); ~$z; | z.real() z.imag() arg(z) abs(z) conj(z) | (built-in (deprecated)) (modern) z.re z.im | let z = {Complex.re=1.0; Complex.im=2.0};; z.Complex.re;; z.Complex.im;; Complex.arg z;; Complex.norm z;; Complex.conj z;; | import Data.Complex realPart (1 :+ 2) imagPart (1 :+ 2) phase (1 :+ 2) magnitude (1 :+ 2) conjugate (1 :+ 2) | ||||||
complex operators | (as above) | Complex.add z w;; Complex.sub z w;; Complex.mul z w;; Complex.div z w;; | |||||||||||
random number / uniform integer, uniform float, normal float | import random random.randint(0, 99) random.random() random.gauss(0, 1) | rand(100) rand (none) | Math.floor(Math.random() * 100) Math.random() (none) | int(rand() * 100) rand() (none) | rand(0,99) lcg_value() (none) | #include <random> default_random_engine dre; uniform_int_distribution<int> uid(0, 99); uniform_real_distribution<double> urd(0.0, 1.0); normal_distribution<double> nd(0.0, 1.0); int i = uid(dre); double x = urd(dre); double y = nd(dre); | import java.util.Random; Random rnd = new Random(); int i = rnd.nextInt(100); double x = rnd.nextDouble(); double y = rnd.nextGaussian(); | import scala.util.Random val rnd = Random rnd.nextInt(100) rnd.nextDouble rnd.nextGaussian | Random.int 100 Random.float 1.0 (none) | cabal install random import System.Random getStdRandom (randomR (0, 99)) getStdRandom (randomR (0.0, 1.0)) none | math.random(100) - 1 math.random() none | ||
random seed / set, get, restore | import random random.seed(17) seed = random.getstate() random.setstate(seed) | srand(17) seed = srand srand(seed) | srand 17; my $seed = srand; srand($seed); | srand(17); (none) | #include <random> (set seed in constructor:) default_random_engine dre(17); (set seed of existing engine:) dre.seed(17); | import java.util.Random; Random rnd = new Random(); rnd.setSeed(17); (seed can also be passed to constructor) | import scala.util.Random val rnd = Random rnd.setSeed(17) (none) (none) | Random.init 17;; let seed = Random.get_state();; Random.set_state seed;; | cabal install random import System.Random setStdGen $ mkStdGen 17 seed <- getStdGen setStdGen seed | math.randomseed(17) | |||
bit operators | << >> & | ^ ~ | << >> & | ^ ~ | << >> & | ^ ~ | << >> & | ^ ~ | << >> & | ^ ~ | << >> & | ^ ~ bitand bitor compl >> is arithmetic right shift on signed integers and logical right shift on unsigned integers | << >> & | ^ ~ | << >> & | ^ ~ >> is arithmetic right shift, >>> is logical right shift | 1 << 4 1 >> 4 1 & 3 1 | 3 1 ^ 3 ~ 1 | 1 lsl 4 1 lsr 4 1 land 3 1 lor 3 1 lxor 3 lnot 1 | import Data.Bits x = 1 :: Integer y = 3 :: Integer shiftL x 4 shiftR x 4 x .&. y x .|. y xor x y complement x | none | |
binary, octal, and hex literals | 0b101010 052 0x2a | 0b101010 052 0x2a | (none) 052 0x2a | 0b101010 052 0x2a | 0b101010 052 0x2a | 0b0101010 052 0x2a | 0b0101010 052 0x2a | none in Java 1.6 052 0x2a | (none) 052 0x2a | 0b101010 0o52 0x2a | (none) 052 0x2a | ||
radix / convert integer to and from string with radix | (none) int("60", 7) | 42.to_s(7) "60".to_i(7) | # cpan -i Math::BaseCalc use Math::BaseCalc; $c = new Math::BaseCalc( digits => [0..6]); $c->to_base(42); $c->from_base("60"); | base_convert("42", 10, 7); base_convert("60", 7, 10); | Integer.toString(42, 7) Integer.parseInt("60", 7) | Integer.toString(42, 7) Integer.parseInt("60", 7) | import Data.Char import Numeric showIntAtBase 7 intToDigit 42 "" case readInt 7 isDigit digitToInt "60" of [(n, "")] -> n _ -> error "Parse failed" | ||||||
strings | |||||||||||||
python | ruby | javascript | coffeescript | perl | php | cpp | d | java | scala | ocaml | haskell | lua | |
string type | str | String | SCALAR which is also used for numeric types and references | string | string s("lorem ipsum"); (convert to C string:) const char* s2 = s.c_str(); | char[] s = "lorem ipsum"; | java.lang.String | java.lang.String (frequently implicitly converted to StringOps or WrappedString) | string | String (alias for [Char]) | |||
string literal | 'don\'t say "no"' "don't say \"no\"" "don't " 'say "no"' '''don't say "no"''' """don't say "no\"""" | "don't say \"no\"" 'don\'t say "no"' "don't " 'say "no"' | "don't say \"no\"" 'don\'t say "no"' | "don't say \"no\"" 'don\'t say "no"' | "don't say \"no\"" 'don\'t say "no"' | (const char*:) "don't say \"no\"" | (string, aka immutable char[]:) "don't say \"no\"" | "don't say\"no\"" | "Hello, World!" """Hello, World!""" | "Hello, World!" | "Hello, World!" | "don't say \"no\"" 'don\'t say "no"' | |
newline in literal | (triple quote literals only:) '''first line second line''' """first line second line""" | 'first line second line' "first line second line" | yes | 'first line second line' "first line second line" | 'first line second line' "first line second line" | Newlines in string literals are ignored. | no | (in triple quote literal only) """first line second line""" | no | no | yes, if preceded by backslash | ||
literal escapes | (single and double quoted:) \newline \\ \' \" \a \b \f \n \r \t \v \ooo \xhh (Python 3:) \uhhhh \Uhhhhhhhh | (double quoted:) \a \b \cx \e \f \n \r \s \t \v \xhh \ooo \uhhhh \u{hhhhh} (single quoted:) \' \\ | (single and double quotes:) \b \f \n \r \t \v \uhhhh \xhh \" \' \\ | double quoted: \a \b \cx \e \f \n \r \t \xhh \x{hhhh} \ooo \o{ooo} single quoted: \' \\ | double quoted: \f \n \r \t \v \xhh \$ \" \\ \ooo single quoted: \' \\ | \a \b \f \n \r \t \v \\ \" \' \xhh \o \oo \ooo | \a \b \f \n \r \t \v \\ \" \' \xhh \o \oo \ooo | \b \f \n \r \t \\ \" \' \uhhhh \o \oo \ooo | \b \f \n \r \t \" \' \uhhhh \o \oo \ooo | \b \n \r \t \" \' \\ \ooo \xhh | \a \b \f \n \r \t \v \" \& \' \\ \oo... \d... \xh... Octal, decimal, and hex escapes denote Unicode characters and can contain anywhere from 1 to 7 digits. The max values are \o4177777, \1114111, and \x10ffff. The \& escape does not represent a character, but can separate a numeric backslash escape sequence from a following digit. | single and double quotes: \a \b \f \n \r \t \v \" \' \\ \ddd | |
allocate string | string* s = new string("hello"); | string s = "hello"; | String s = "hello"; String t = new String(s); | ||||||||||
are strings mutable? | no | s = "bar" s2 = s (sets s and s2 to "baz":) s[2] = "z" | $s = "bar"; $s2 = $s; (sets s to "baz"; s2 is unchanged:) $s =~ s/r/z/; | $s = "bar"; $s2 = $s; (sets s to "baz"; s2 is unchanged:) $s[2] = "z"; | string s("bar"); s[2] = 'z'; | (no, but char[]s are:) char[] s = "bar".dup; s[2] = 'z'; | String objects are immutable. StringBuffer has append(), delete(), deleteCharAt(), insert(), replace(), setCharAt(). | no | no | ||||
custom delimiters | s1 = %q(lorem ipsum) s2 = %Q(#{s1} dolor sit amet) | my $s1 = q(lorem ipsum); my $s2 = qq($s1 dolor sit amet); | |||||||||||
here document | word = "amet" s = <<EOF lorem ipsum dolor sit #{word} EOF | $word = "amet"; $s = <<EOF; lorem ipsum dolor sit $word EOF | $word = "amet"; $s = <<<EOF lorem ipsum dolor sit $word EOF; | ||||||||||
variable interpolation | count = 3 item = 'ball' print('{count} {item}s'.format( **locals())) | count = 3 item = "ball" puts "#{count} #{item}s" | count = 3 item = ball alert "#{count} #{item}s" (double-quoted strings only) | my $count = 3; my $item = "ball"; print "$count ${item}s\n"; | $count = 3; $item = "ball"; echo "$count ${item}s\n"; | none | |||||||
expression interpolation | '1 + 1 = {}'.format(1 + 1) | "1 + 1 = #{1 + 1}" | none | none | |||||||||
format | (old-style) 'lorem %s %d %f' % ('ipsum', 13, 3.7) (new-style) fmt = 'lorem {0} {1} {2}' fmt.format('ipsum', 13, 3.7) | "lorem %s %d %f" % ["ipsum", 13, 3.7] | my $fmt = "lorem %s %d %f"; sprintf($fmt, "ipsum", 13, 3.7) | $fmt = "lorem %s %d %f"; sprintf($fmt, "ipsum", 13, 3.7); | #include <sstream> ostringstream oss; oss << "Spain: " << 7; string s(oss.str()); | String.format("%s: %d", "Spain", 7) | "foo %s %d %.2f".format("bar", 7, 3.1415) | import Text.Printf printf "foo %s %d %.2f" "bar" 7 3.1415 | string.format("lorem %s %d %.2f", "ipsum", 13, 3.7) | ||||
compare strings | (relational operators are chainable:) == != > < >= <= | == != > < >= <= | eq ne gt lt ge le | == != or <> > < >= <= (no conversion:) === !== | string s1("hello"); string s2("world"); (negative if s1 lexically before s2; zero if s1 and s2 are equal:) int result1 = s1.compare(s2); bool result2 = s1 == s2; | == != < > <= >= | "hello".compareTo("world") | == != < > <= >= | == /= < > <= >= | ||||
copy string | (not necessary) | s = "bar" s2 = s.clone (s2 is not altered:) s[2] = "z" | $s2 = $s; | $s2 = $s; | string s("bar"); (use assignment or copy constructor:) string s2 = s; string s3(s); (s contains "baz"; s2 and s3 contain "bar":) s[2] = 'z'; | (not necessary for strings since they're immutable, but) const char[] s = "bar"; char[] s2 = s.dup; char[] s3 = s; (s contains "baz"; s2 and s3 contain "bar":) s[2] = 'z'; | String s = "bar"; StringBuffer sb = new StringBuffer(s); sb.setCharAt(2, 'z'); (s contains "bar"; s2 contains "baz":) String s2 = sb.toString(); | ||||||
concatenate strings / and append | s = 'Hello, ' s2 = s + 'World!' (juxtaposition can be used to concatenate literals:) s2 = 'Hello, ' "World!" | s = "Hello, " s2 = s + "World!" (juxtaposition can be used to concatenate literals:) s2 = "Hello, " 'World!' | s = "Hello, " + "World!"; | my $s = "Hello, "; my $s2 = $s . "World!"; | $s = "Hello, "; $s2 = $s . "World!"; | string s("hello"); string s2 = s + " world"; s += " world"; | (same as arrays:) string s = "hello"; string s2 = s ~ " world"; s ~= " world"; | "Hello" + ", " + "World!" "Hello" ++ ", " ++ "World!" | "Hello" ^ ", " ^ "World!" | "Hello" ++ ", " ++ "World!" | s = "Hello, " .. "World!" | ||
replicate string | hbar = '-' * 80 | hbar = "-" * 80 | my $hbar = "-" x 80; | $hbar = str_repeat("-", 80); | string hbar(80, '-'); | import java.util.Arrays; char[] a = new char[80]; Arrays.fill(a, '-'); String s = new String(a); | val hbar = "-" * 80 | String.make 80 '-' | concat $ replicate 80 "-" replicate 80 '-' | ||||
translate case / to upper, to lower | 'lorem'.upper() 'LOREM'.lower() | "lorem".upcase "LOREM".downcase | "lorem".toUpperCase() "LOREM".toLowerCase() (none) | uc("lorem") lc("LOREM") | strtoupper("lorem") strtolower("LOREM") | #include <algorithm> string s("foo"); (in place:) transform(s.begin(), s.end(), s.begin(), ::toupper); transform(s.begin(), s.end(), s.begin(), ::tolower); (non-destructive:) string s2; s2.resize(s.size(); transform(s.begin(), s.end(), s2.begin(), ::toupper); | "hello".toUpperCase() "HELLO".toLowerCase() | "hello".toUpperCase "HELLO".toLowerCase | String.uppercase "hello" String.lowercase "HELLO" | import Data.Char map toUpper "hello" map toLower "HELLO" | string.upper("lorem") string.lower("LOREM") none | ||
capitalize / string, words | import string 'lorem'.capitalize() string.capwords('lorem ipsum') | "lorem".capitalize (none) | # cpan -i Text::Autoformat use Text::Autoformat; ucfirst("lorem") autoformat("lorem ipsum", {case => 'title'}) | ucfirst("lorem") ucwords("lorem ipsum") | "hello".capitalize | String.capitalize "hello" | |||||||
trim / both sides, left, right | ' lorem '.strip() ' lorem'.lstrip() 'lorem '.rstrip() | " lorem ".strip " lorem".lstrip "lorem ".rstrip | " lorem ".trim() (some browsers:) " lorem".trimLeft() "lorem ".trimRight() | # cpan -i Text::Trim use Text::Trim; trim " lorem " ltrim " lorem" rtrim "lorem " | trim(" lorem ") ltrim(" lorem") rtrim("lorem ") | #include <algorithm> string s(" hello "); (trim in place on left:) s.erase( s.begin(), find_if( s.begin(), s.end(), not1(ptr_fun<int, int>(isspace)) ) ); (trim in place on right:) s.erase( find_if( s.rbegin(), s.rend(), not1(ptr_fun<int, int>(isspace)) ).base(), s.end() ); | " hello ".trim() | " hello ".trim | String.trim " hello " | ||||
pad / on right, on left, centered | 'lorem'.ljust(10) 'lorem'.rjust(10) 'lorem'.center(10) | "lorem".ljust(10) "lorem".rjust(10) "lorem".center(10) | # cpan -i Text::Format use Text::Format; sprintf("%-10s", "lorem") sprintf("%10s", "lorem") $text = Text::Format->new(columns => 10); $text->center("lorem"); | str_pad("lorem", 10) str_pad("lorem", 10, " ", STR_PAD_LEFT) str_pad("lorem", 10, " ", STR_PAD_BOTH) | #include <iomanip> #include <sstream> string s("hello"); string rpad(s); rpad += string(10 - s.length(), ' '); ostringstream oss; oss << setw(10) << s; string lpad(oss.str()); | ?? "hello".padTo(10, " ").mkString | none | ||||||
number to string | 'value: ' + str(8) | "value: " + 8.to_s | "value: " + 8 | "value: " . 8 | "value: " . 8 | import std.conv; to!string(14) | Integer.toString(14) Long.toString(14) Double.toString(14.7) | "two: " + 2.toString "pi: " + 3.14.toString | "two: " ^ string_of_int 2 "pi: " ^ float_of_string 3.14 | "two: " ++ (show 2) "pi: " ++ (show 3.14) | "value: " .. 8 | ||
string to number | 7 + int('12') 73.9 + float('.037') raises ValueError: int('12A') raises ValueError: int('A') | 7 + "12".to_i 73.9 + ".037".to_f (# 12:) "12A".to_i (# 0:) "A".to_i | 7 + parseInt("12", 10) 73.9 + parseFloat(".037") | 7 + "12" 73.9 + ".037" | 7 + "12" 73.9 + ".037" | #include <sstream> stringstream ss("7 14.3 12"); int n1; double x; long n2; ss >> n1 >> x >> n2; | import std.conv; to!int(14) | Byte.parseByte("14") Short.parseShort("14") Integer.parseInt("14") Long.parseLong("14") Float.parseFloat("14.7") Double.parseDouble("14.7") | 7 + "12".toInt 73.9 + ".037".toFloat raises NumberFormatException if string doesn't completely parse | 7 + int_of_string "12" 73.9 +. float_of_string ".037" | raises exception if string doesn't completely parse: 7 + (read "12")::Integer 73.9 + (read "0.037")::Double (reads returns a list of (parsed value, remaining string) pairs, or an empty list if parsing fails:) reads "12" :: [(Int, String)] case reads "12" of [(x, "")] -> 7 + x _ -> error "Parse failed" (GHC 7.6:) import Text.Read fmap (7 +) $ readMaybe "12" fmap (73.9 +) $ readEither "0.037" | 7 + tonumber("12") 73.9 + tonumber(".037") arithmetic operators attempt numeric conversion of string operands | |
join | ' '.join(['do', 're', 'mi', 'fa']) raises TypeError: ' '.join([1, 2, 3]) | %w(do re mi fa).join(' ') (implicitly converted to strings:) [1, 2, 3].join(' ') | ["do", "re", "mi"].join(" ") | join(" ", qw(do re mi fa)]) | $a = ["do", "re", "mi", "fa"]; implode(" ", $a) | List("do", "re", "mi").mkString(" ") | unwords ["do", "re", "mi", "fa"] (join by spaces) import Data.List intercalate " " ["do", "re", "mi", "fa"] | table.concat({"do","re","mi"}, " ") | |||||
split | 'do re mi fa'.split() | "do re mi fa".split | "do re mi".split(" ") | split(/\s+/, "do re mi fa") | explode(" ", "do re mi fa") | "Bob Ned Amy".split(" ") | "do re mi".split(" ") | (on whitespace:) words "do re mi fa" | none | ||||
split in two | 'do re mi fa'.split(None, 1) | "do re mi fa".split(/\s+/, 2) | split(/\s+/, "do re mi fa", 2) | preg_split('/\s+/', "do re mi fa", 2) | |||||||||
split and keep delimiters | re.split('(\s+)', 'do re mi fa') | "do re mi fa".split(/(\s+)/) | split(/(\s+)/, "do re mi fa") | preg_split('/(\s+)/', "do re mi fa", NULL, PREG_SPLIT_DELIM_CAPTURE) | |||||||||
prefix and suffix test | 'foobar'.startswith('foo') 'foobar'.endswith('bar') | 'foobar'.start_with?('foo') 'foobar'.end_with?('bar') | |||||||||||
serialize | |||||||||||||
string-length | len('lorem') | "lorem".length "lorem".size | "lorem".length | length("lorem") | strlen("lorem") | string s("hello"); size_t len = s.length(); | const char[] s = "hello"; int len = s.length; | s.length() | "hello".length | List.length [1; 2; 3] | length "hello" (type Int) | string.len("lorem") | |
index of substring / first, last | raises ValueError if not found: 'do re re'.index('re') 'do re re'.rindex('re') (returns -1 if not found:) 'do re re'.find('re') 'do re re'.rfind('re') | (returns nil if not found:) "do re re".index("re") "do re re".rindex("re") | "lorem ipsum".indexOf("ipsum") | (returns -1 if not found:) index("lorem ipsum", "ipsum") rindex("do re re", "re") | (returns FALSE if not found, which must be tested for with === since it coerces to 0:) strpos("do re re", "re") strrpos("do re re", "re") | string("hello").find("ll") | "hello".indexOf("ll") | "hello".indexOf("hell") | string.find("lorem ipsum", "ipsum") | ||||
extract substring / by start and length, by start and end, by successive starts | (none) (none) 'lorem ipsum'[6:11] | "lorem ipsum"[6, 5] "lorem ipsum"[6..10] "lorem ipsum"[6...11] | "lorem ipsum".substr(6, 5) "lorem ipsum".substring(6, 11) | substr("lorem ipsum", 6, 5) none none | substr("lorem ipsum", 6, 5) (none) (none) | string("hello").substr(2, 2) | "hello".substring(2,4) | "hello".substring(0, 4) | String.sub "hello" 0 4 | drop 0 (take 4 "hello") | string.sub("lorem ipsum", 7, 11) | ||
extract character | 'lorem ipsum'[6] | "lorem ipsum"[6] | "lorem ipsum".charAt(6) "lorem ipsum".charCodeAt(6) | (can't use index notation with strings:) substr("lorem ipsum", 6, 1) | (syntax error to use index notation directly on string literal:) $s = "lorem ipsum"; $s[6]; | "hello"(0) | "hello".[0] | "hello" !! 0 | |||||
character type | (essentially length-1 str) | char wchar_t | char wchar dchar | char Character | Char | char | Char | ||||||
character literal | (same as string) | char n = 'X'; | char n = 'X'; | char n = 'X'; | 'h' | 'h' | 'h' | ||||||
test character / letter, digit, whitespace, uppercase letter, lowercase letter | (operate on any strings, testing if all characters satisfy:) 'c'.isalpha() 'c'.isdigit() 'c'.isspace() 'c'.isupper() 'c'.islower() | (use regexes, somehow) /^[a-zA-Z]$/.test('c') /^\d$/.test('c') /^\s$/.test('c') /^[A-Z]$/.test('c') /^[a-z]$/.test('c') (for speed, use charCode comparisons) | (functions have this signature:) int (*)(int) isalpha isdigit isspace isupper islower | 'c'.isLetter 'c'.isDigit 'c'.isSpaceChar 'c'.isUpper 'c'.isLower | |||||||||
chr and ord | chr(65) ord('A') | 65.chr "A".ord | String.fromCharCode(65) "A".charCodeAt(0) | chr(65) ord("A") | chr(65) ord("A") | 'a'.toInt 97.toChar | Char.code 'a' Char.chr 97 | Char.ord 'a' Char.chr 97 | string.char(65) string.byte("A") | ||||
to array of characters | list('abcd') | "abcd".split("") | split(//, "abcd") | str_split("abcd") | (implicit --- via Predef.augmentString, to StringOps, or Predef.wrapString, to WrappedString) | (strings are exactly the same as lists of characters) | |||||||
translate characters | from string import lowercase as ins from string import maketrans outs = ins[13:] + ins[:13] 'hello'.translate(maketrans(ins,outs)) | "hello".tr("a-z", "n-za-m") | $s = "hello"; $s =~ tr/a-z/n-za-m/; | $ins = implode(range("a", "z")); $outs = substr($ins, 13, 13) . substr($ins, 0, 13); strtr("hello", $ins, $outs) | |||||||||
delete characters | "disemvowel me".translate(None, "aeiou") | "disemvowel me".delete("aeiou") | $s = "disemvowel me"; $s =~ tr/aeiou//d; | $vowels = str_split("aeiou"); $s = "disemvowel me"; $s = str_replace($vowels, "", $s); | |||||||||
squeeze characters | re.sub('(\s)+', r'\1', 'too much space') | "too much space".squeeze(" ") | $s = "too much space"; $s =~ tr/ //s; | $s = "too much space"; $s = = preg_replace('/(\s)+/', '\1', $s); | |||||||||
regular expressions | |||||||||||||
python | ruby | javascript | coffeescript | perl | php | cpp | d | java | scala | ocaml | haskell | lua | |
regex type | regex wregex | scala.util.matching.Regex | |||||||||||
literal, custom delimited literal | re.compile('lorem|ipsum') (none) | /lorem|ipsum/ %r(/etc/hosts) | /lorem|ipsum/ qr(/etc/hosts) | '/lorem|ipsum/' '(/etc/hosts)' | val r = "lorem|ipsum".r (none) | ||||||||
character class abbreviations | . \d \D \s \S \w \W | . \d \D \h \H \s \S \w \W | . \d \D \h \H \s \S \v \V \w \W | . \d \D \h \H \s \S \v \V \w \W | . \d \D \s \S \w \W | . \d \D \s \S \w \W | . \c \s \S \d \D \w \W \x \O [:upper:] [:lower:] [:alpha:] [:alnum:] [:digit:] [:xdigit:] [:punct:] [:blank:] [:space:] [:cntrl:] [:graph:] [:print:] [:word:] | . %a %c %d %l %p %s %u %w %x %z | |||||
anchors | ^ $ \A \b \B \Z | ^ $ \A \b \B \z \Z | ^ $ \A \b \B \z \Z | ^ $ \A \b \B \z \Z | ^ $ \b \B | ^ $ \b \B | ^ $ \A \b \B \< \> \Z | ^ $ | |||||
lookahead / positive, negative | (?=subpattern) (?!subpattern) | (?= (...) ) (?! (...) ) (?<= (...) ) (?<! (...) ) | |||||||||||
match test | if re.search('1999', s): print('party!') | if /1999/.match(s) puts "party!" end | if (s.match(/1999/)) { alert("party!"); } | if ($s =~ /1999/) { print "party!\n"; } | if (preg_match('/1999/', $s)) { echo "party!\n"; } | #include <regex> regex rx(".*ll.*"); bool match = regex_match("hello", rx); | boolean isMatch = "hello".matches(".*ll.*"); | if ("1999".r.findFirstIn(s).isDefined) println("party!") | if string.match(s, "1999") then print("party!") end | ||||
case insensitive match test | re.search('lorem', 'Lorem', re.I) | /lorem/i.match("Lorem") | "Lorem".match(/lorem/i) | "Lorem" =~ /lorem/i | preg_match('/lorem/i', "Lorem") | #include <regex> regex rx("lorem", icase); bool match = regex_match("Lorem", rx); | "(?i)lorem".r.findFirstIn("Lorem") | none | |||||
modifiers | re.I re.M re.S re.X | i o m x | g i m | i m s p x | e i m s x | (?idmsux-idmsux) | none | ||||||
substitution | s = 'do re mi mi mi' s = re.compile('mi').sub('ma', s) | s = "do re mi mi mi" s.gsub!(/mi/, "ma") | s = "do re mi mi mi"; s.replace(/mi/g, "ma"); | my $s = "do re mi mi mi"; $s =~ s/mi/ma/g; | $s = "do re mi mi mi"; $s = preg_replace('/mi/', "ma", $s); | String s1 = "hello".replace("ll","LL"); String s2 = "hello".replaceAll("l","L"); | val s = "do re mi mi mi" val t = "mi".r.replaceAllIn(s, "ma") | s = "do re mi mi mi" s = string.gsub(s, "mi", "ma") | |||||
match, prematch, postmatch | m = re.search('\d{4}', s) if m: match = m.group() prematch = s[0:m.start(0)] postmatch = s[m.end(0):len(s)] | m = /\d{4}/.match(s) if m match = m[0] prematch = m.pre_match postmatch = m.post_match end | if ($s =~ /\d{4}/p) { $match = ${^MATCH}; $prematch = ${^PREMATCH}; $postmatch = ${^POSTMATCH}; } | none | val fm = "\\d{4}".r.findFirstMatchIn(s) fm match { case Some(m) => { m.matched m.before m.after } case None => ... (no match) } | ||||||||
group capture | rx = '(\d{4})-(\d{2})-(\d{2})' m = re.search(rx, '2010-06-03') yr, mo, dy = m.groups() | rx = /(\d{4})-(\d{2})-(\d{2})/ m = rx.match("2010-06-03") yr, mo, dy = m[1..3] | rx = /^(\d{4})-(\d{2})-(\d{2})$/; m = rx.exec('2009-06-03'); yr = m[1]; mo = m[2]; dy = m[3]; | $rx = qr/(\d{4})-(\d{2})-(\d{2})/; "2010-06-03" =~ $rx; ($yr, $mo, $dy) = ($1, $2, $3); | $s = "2010-06-03"; $rx = '/(\d{4})-(\d{2})-(\d{2})/'; preg_match($rx, $s, $m); list($_, $yr, $mo, $dy) = $m; | val rx = """(\d{4})-(\d{2})-(\d{2})""".r m = rx.findFirstMatchIn("2010-06-03") val List(yr, mo, dy) = m.get.subgroups (only full match:) val rx(yr, mo, dy) = "2010-06-03" | s = "2010-06-03" rx = "(%d+)-(%d+)-(%d+)" yr, mo, dy = string.match(s, rx) | ||||||
named group capture | rx = '^(?P<file>.+)\.(?P<suffix>.+)$' m = re.search(rx, 'foo.txt') m.groupdict()['file'] m.groupdict()['suffix'] | rx = /^(?<file>.+)\.(?<suffix>.+)$/ m = rx.match('foo.txt') m["file"] m["suffix"] | $s = "foo.txt"; $s =~ /^(?<file>.+)\.(?<suffix>.+)$/; $+{"file"} $+{"suffix"} | $s = "foo.txt"; $rx = '/^(?P<file>.+)\.(?P<suffix>.+)$/'; preg_match($rx, $s, $m); $m["file"] $m["suffix"] | val rx = "^(.+)\\.(.+)$".r("file", "suffix") val m = rx.findFirstMatchIn("foo.txt").get m.group("file") m.group("suffix") | ||||||||
scan | s = 'dolor sit amet' a = re.findall('\w+', s) | a = "dolor sit amet".scan(/\w+/) | my $s = "dolor sit amet"; @a = $s =~ m/\w+/g; | $s = "dolor sit amet"; preg_match_all('/\w+/', $s, $m); $a = $m[0]; | val s = "dolor sit amet" val ss: Iterator[String] = "\\w+".r.findAllIn('\w+', s) val ms: Iterator[Match] = "\\w+".r.findAllMatchIn('\w+', s) | ||||||||
backreference in match and substitution | (none) rx = re.compile('(\w+) (\w+)') rx.sub(r'\2 \1', 'do re') | /(\w+) \1/.match("do do") "do re".sub(/(\w+) (\w+)/, '\2 \1') | /(w+) \1/.exec("do do") "do re".replace(/(\w+) (\w+)/, '$2 $1') | "do do" =~ /(\w+) \1/ my $s = "do re"; $s =~ s/(\w+) (\w+)/$2 $1/; | preg_match('/(\w+) \1/', "do do") $s = "do re"; $rx = '/(\w+) (\w+)/'; $s = preg_replace($rx, '\2 \1', $s); | string.match("do do", "(%w+) %1") rx = "(%w+) (%w+)" string.gsub("do re", rx, "%2 %1") | |||||||
recursive regex | none | /(?<foo>\(([^()]*|\g<foo>)*\))/ | /\(([^()]*|(?R))\)/ | '/\(([^()]*|($R))\)/' | |||||||||
dates and time | |||||||||||||
python | ruby | javascript | coffeescript | perl | php | cpp | d | java | scala | ocaml | haskell | lua | |
date/time type | datetime.datetime | Time | Time::Piece if use Time::Piece in effect, otherwise tm array | DateTime | java.util.Date | ClockTime CalendarTime TimeDiff | |||||||
current date/time | import datetime t = datetime.datetime.now() utc = datetime.datetime.utcnow() | t = Time.now utc = Time.now.utc | var t = new Date(); | use Time::Piece; my $t = localtime(time); my $utc = gmtime(time); | $t = new DateTime("now"); $utc_tmz = new DateTimeZone("UTC"); $utc = new DateTime("now", $utc_tmz); | import java.util.Date; long millis = System.currentTimeMillis(); Date dt = new Date(millis); | import Time t <- getClockTime | t = os.time() | |||||
to unix epoch, from unix epoch | from datetime import datetime as dt epoch = int(t.strftime("%s")) t2 = dt.fromtimestamp(1304442000) | epoch = t.to_i t2 = Time.at(1304442000) | Math.round(t.getTime() / 1000) var epoch = 1315716177; var t2 = new Date(epoch * 1000); | use Time::Local; use Time::Piece; my $epoch = timelocal($t); my $t2 = localtime(1304442000); | $epoch = $t->getTimestamp(); $t2 = new DateTime(); $t2->setTimestamp(1304442000); | long epoch = dt.getTime() / 1000; Date dt2 = new Date(epoch * 1000); | t t2 = 1315716177 | ||||||
current unix epoch | import datetime t = datetime.datetime.now() epoch = int(t.strftime("%s")) | epoch = Time.now.to_i | $epoch = time; | $epoch = time(); | open Unix;; (* float: *) time();; | import System.Time getClockTime >>= (\(TOD sec _) -> return sec) | |||||||
date and time to string | dt.toString() | ||||||||||||
format date | String s = "yyyy-MM-dd HH:mm:ss"; DateFormat fmt = new SimpleDateFormat(s); String s2 = fmt.format(dt); | ||||||||||||
strftime | t.strftime('%Y-%m-%d %H:%M:%S') | t.strftime("%Y-%m-%d %H:%M:%S") | use Time::Piece; $t = localtime(time); $fmt = "%Y-%m-%d %H:%M:%S"; print $t->strftime($fmt); | strftime("%Y-%m-%d %H:%M:%S", $epoch); date("Y-m-d H:i:s", $epoch); $t->format("Y-m-d H:i:s"); | os.date("%Y-%m-%d %H:%M:%S", t) | ||||||||
default format example | 2011-08-23 19:35:59.411135 | 2011-08-23 17:44:53 -0700 | Tue Aug 23 19:35:19 2011 | no default string representation | |||||||||
strptime | from datetime import datetime s = '2011-05-03 10:00:00' fmt = '%Y-%m-%d %H:%M:%S' t = datetime.strptime(s, fmt) | require 'date' s = "2011-05-03 10:00:00" fmt = "%Y-%m-%d %H:%M:%S" t = Date.strptime(s, fmt).to_time | use Time::Local; use Time::Piece; $s = "2011-05-03 10:00:00"; $fmt = "%Y-%m-%d %H:%M:%S"; $t = Time::Piece->strptime($s,$fmt); | $fmt = "Y-m-d H:i:s"; $s = "2011-05-03 10:00:00"; $t = DateTime::createFromFormat($fmt, $s); | none | ||||||||
parse date | String s = "2011-05-03 17:00:00"; Date dt2 = fmt.parse(s); | ||||||||||||
parse date w/o format | # pip install python-dateutil import dateutil.parser s = 'July 7, 1999' t = dateutil.parser.parse(s) | require 'date' s = "July 7, 1999" t = Date.parse(s).to_time | var t = new Date("July 7, 1999"); | # cpan -i Date::Parse use Date::Parse; $epoch = str2time("July 7, 1999"); | $epoch = strtotime("July 7, 1999"); | none | |||||||
result of date subtraction | datetime.timedelta object use total_seconds() method to convert to float representing difference in seconds | Float containing time difference in seconds | Time::Seconds object if use Time::Piece in effect; not meaningful to subtract tm arrays | DateInterval object if diff method used: $fmt = "Y-m-d H:i:s"; $s = "2011-05-03 10:00:00"; $then = DateTime::createFromFormat($fmt, $s); $now = new DateTime("now"); $interval = $now->diff($then); | (difference in milliseconds as a long:) dt2.getTime() - dt.getTime() | ||||||||
add duration | import datetime delta = datetime.timedelta( minutes=10, seconds=3) t = datetime.datetime.now() + delta | require 'date/delta' s = "10 min, 3 s" delta = Date::Delta.parse(s).in_secs t = Time.now + delta | use Time::Seconds; $now = localtime(time); $now += 10 * ONE_MINUTE() + 3; | $now = new DateTime("now"); $now->add(new DateInterval("PT10M3S"); | long day_ms = 24 * 3600 * 1000; Date dt = new Date(dt.getTime() + day_ms)); | ||||||||
date parts | t.getFullYear() t.getMonth() + 1 t.getDate() (getDay() is day of week) | $t->year $t->mon $t->mday | none | ||||||||||
time parts | t.getHours() t.getMinutes() t.getSeconds() | $t->hour $t->min $t->sec | none | ||||||||||
build date/time from parts | var yr = 1999; var mo = 9; var dy = 10; var hr = 23; var mi = 30; var ss = 0; var t = new Date(yr,mo-1,dy,hr,mi,ss); | $dt = DateTime->new( year=>2014, month=>4, day=>1, hour=>10, minute=>3, second=>56); | none | ||||||||||
local timezone | a datetime object has no timezone information unless a tzinfo object is provided when it is created | (if no timezone is specified the local timezone is used) | Time::Piece has local timezone if created with localtime and UTC timezone if created with gmtime; tm arrays have no timezone or offset info | DateTime objects can be instantiated without specifying the timezone if a default is set: $s = "America/Los_Angeles"; date_default_timezone_set($s); | |||||||||
arbitrary timezone | # pip install pytz import pytz import datetime tmz = pytz.timezone('Asia/Tokyo') utc = datetime.datetime.utcnow() utc_dt = datetime.datetime( *utc.timetuple()[0:5], tzinfo=pytz.utc) jp_dt = utc_dt.astimezone(tmz) | # gem install tzinfo require 'tzinfo' tmz = TZInfo::Timezone.get("Asia/Tokyo") jp_time = tmz.utc_to_local(Time.now.utc) | |||||||||||
timezone name; offset from UTC; is daylight savings? | import time tm = time.localtime() time.tzname[tm.tm_isdst] (time.timezone / -3600) + tm.tm_isdst tm.tm_isdst | t.zone t.utc_offset / 3600 t.dst? | # cpan -i DateTime use DateTime; use DateTime::TimeZone; $dt = DateTime->now(); $tz = DateTime::TimeZone->new( name=>"local"); $tz->name; $tz->offset_for_datetime($dt) / 3600; $tz->is_dst_for_datetime($dt); | $tmz = date_timezone_get($t); timezone_name_get($tmz); date_offset_get($t) / 3600; $t->format("I"); | |||||||||
microseconds | t.microsecond | t.usec | use Time::HiRes qw(gettimeofday); ($sec, $usec) = gettimeofday; | list($frac, $sec) = explode(" ", microtime()); $usec = $frac * 1000 * 1000; | |||||||||
sleep | import time time.sleep(0.5) | sleep(0.5) | (a float argument will be truncated to an integer:) sleep 1; | (a float argument will be truncated to an integer:) sleep(1); | none | ||||||||
timeout | import signal, time class Timeout(Exception): pass def timeout_handler(signo, fm): raise Timeout() signal.signal(signal.SIGALRM, timeout_handler) try: signal.alarm(5) time.sleep(10) except Timeout: pass signal.alarm(0) | require 'timeout' begin Timeout.timeout(5) do sleep(10) end rescue Timeout::Error end | eval { $SIG{ALRM}= sub {die "timeout!";}; alarm 5; sleep 10; }; alarm 0; | use set_time_limit to limit execution time of the entire script; use stream_set_timeout to limit time spent reading from a stream opened with fopen or fsockopen | |||||||||
fixed-length arrays | |||||||||||||
python | ruby | javascript | coffeescript | perl | php | cpp | d | java | scala | ocaml | haskell | lua | |
declare on stack | int a[10]; | int[10] a; | arrays must be allocated on heap | ||||||||||
declare on heap | int* a = new int[10]; | int[] a; a.length = 10; | int[] a = new int[10]; | val a: Array[Int] = new Array(10) val b = Array.fill(10)(0) | |||||||||
free heap | delete[] a; | garbage collected | |||||||||||
initialization list | int a[] = {1, 2, 3}; | int a[3] = [1, 2, 3]; | int[] a = {1,2,3}; | val a = Array(1, 2, 3) | import Data.Array a = listArray (0, 2) [1, 2, 3] | ||||||||
size | int a[10]; (stack arrays only:) size_t len = sizeof(a) / sizeof(a[0]); | int a[10]; a.length; | a.length | a.length a.size (via implicit conversion to ArrayOps) | (returns smallest and largest valid index:) bounds a | ||||||||
lookup | int first = a[0]; | int first = a[0]; | a[0] | val n = a(0) | n = a ! 0 | ||||||||
update | a[0] = 7; | a[0] = 7; | a(2) = 4 | (returns updated copy:) a // [(2, 4)] | |||||||||
out-of-bounds behavior | No defined behavior An out-of-bounds lookup may return the value the memory location contains; an out-of-bounds update may cause memory corruption. The system may detect an invalid address and send the process a SIGSEGV. | RangeError if detected | ArrayIndexOutOfBoundsException | raises java.lang.ArrayIndexOutOfBounds | exception | ||||||||
array-copy | const size_t LEN(4); int src[LEN] = {3, 2, 4, 1}; int dest[LEN]; (3rd arg is number of bytes to copy:) memcpy(dest, src, LEN * sizeof(src[0])); | a.clone() | |||||||||||
as function argument | void reverse(int* a, size_t len) { for (int i = 0; i < len / 2; ++i) { int tmp = a[len - i - 1]; a[len - i - 1] = a[i]; a[i] = tmp; } } const size_t LEN(4); int a[LEN] = {3, 2, 4, 1}; reverse(a, LEN); | ||||||||||||
iterate | const size_t LEN(4); int a[LEN] = {3, 2, 4, 1}; for (int i = 0; i < LEN; ++i) { cout << "value at " << i << " is " << a[i] << endl; } | int a[] = [ 3, 2, 4, 1 ]; foreach (i, e; a) { writeln("value at ", i, " is ", e); } | for (String name : names) { | for (v <- a) { (code) } a.foreach(v => (code) ) | (purely functional map:) fmap (function) a (for monadic iteration, first convert to list with elems or assocs:) mapM_ (\e -> print e) $ elems a mapM_ (\(i,e) -> printf "%d at index %d\n" e i) $ assocs a | ||||||||
sort | import std.algorithm; bool comp(int a, int b) @safe pure nothrow { return a < b ? -1 : (a == b ? 0 : 1); } int[] arr = [3, 2, 1, 4]; sort!("a > b")(arr); (first pair of parens optional) sort!(comp)(arr); (first pair of parens optional) | Array(3, 2, 1, 4).sorted | |||||||||||
lists (or most common variable-size sequential data structure) | |||||||||||||
python | ruby | javascript | coffeescript | perl | php | cpp | d | java | scala | ocaml | haskell | lua | |
name | list | Array | array | variable: array ephemeral value: list | array | vector<T> (supports efficient random access and manipulation of end; STL also provides deque<T> and list<T>) | T[] | java.util.ArrayList<T> (The Java Collections API also provides LinkedList<T> and a few others; Vector<T> is older and slower because it is synchronized.) | Seq (generic trait) List (immutable, preferred) ArrayBuffer, ListBuffer (mutable) | [] | |||
declare | #include <vector> vector <int> a; | int[] a; | java.util.ArrayList<String> list = new java.util.ArrayList<String>(); | ||||||||||
head and tail of empty list | NoSuchElementException: Nil.head UnsupportedOperationException: Nil.tail | exceptions | exceptions | ||||||||||
literal or initialization list | a = [1, 2, 3, 4] | a = [1, 2, 3, 4] | a = [1, 2, 3, 4] | @a = (1, 2, 3, 4); | $a = [1, 2, 3, 4]; (older syntax:) $a = array(1, 2, 3, 4); | #include <vector> vector<int> a = {1, 2, 3}; vector<int> a2({7, 8, 9}); | [1, 2, 3] | (none; use constructor:) List(1, 2, 3) | [1; 2; 3] | [1, 2, 3] | a = { 1, 2, 3, 4 } | ||
quote words | a = %w(do re mi) | @a = qw(do re mi); | |||||||||||
size | len(a) | a.size a.length (same as size) | a.length | $#a + 1 (or) scalar(@a) | count($a) | size_t len = a.size(); | a.length | list.size() | List(1, 2, 3).length List(1, 2, 3).size | length [1, 2, 3] | -- not well-defined if array -- contains nil values: # a | ||
capacity / get, increase | size_t cap = a.capacity(); (will not decrease capacity:) a.reserve(10); | a.capacity a.capacity = 10; | (none) a.sizeHint(10) (ArrayBuffer, ListBuffer, or other Builder[Elem, To]) | ||||||||||
empty list | [] | [] | Nil List() | [] | [] | ||||||||
empty test | not a | NoMethodError if a is nil: a.empty? | a.length === 0 | !@a | !$a | val list = List(1, 2, 3) list == Nil list.isEmpty | let list = [1; 2; 3];; list == [] | let list = [1, 2, 3] list == [] null list (pattern matching can often be used to avoid these constructions:) case list of (x:xs) = x + 1 [] = error "empty list" | |||||
empty test / and clear | bool is_empty = a.empty(); a.clear(); | bool isEmpty = a.empty; a.length = 0; | |||||||||||
head | a[0] | a[0] | List(1, 2, 3).head | List.hd [1; 2; 3] | head [1, 2, 3] | ||||||||
tail | List(1, 2, 3).tail | List.tl [1; 2; 3] | tail [1, 2, 3] | ||||||||||
lookup | a[0] (negative indices count from end:) a[-1] (last element) | a[0] (returns last element:) a[-1] | a[0] | $a[0] (returns last element:) $a[-1] | $a[0] (PHP uses the same type for arrays and dictionaries; indices can be negative integers or strings) | int n = a[0]; (can raise out_of_range:) int n2 = a.at(0); | a[0] | list.elementAt(0) | List(1, 2, 3)(0) | List.nth [1; 2; 3] 0 | [1, 2, 3] !! 0 | a[1] | |
update | a[0] = 'lorem' | a[0] = "lorem" | a[0] = "lorem" | $a[0] = "lorem"; | $a[0] = "lorem"; | a[2] = 4; | a[2] = 4; | (evaluates to List(1, 4, 3):) List(1, 2, 3).updated(1, 4) | a[1] = "lorem" | ||||
out-of-bounds behavior | a = [] raises IndexError: a[10] raises IndexError: a[10] = 'lorem' | a = [] (evaluates as nil:) a[10] (increases array size to 11:) a[10] = "lorem" | returns undefined | @a = (); (evaluates as undef:) $a[10]; (increases array size to 11:) $a[10] = "lorem"; | $a = []; (evaluates as NULL:) $a[10]; (increases array size to one:) $a[10] = "lorem"; | using [] with out-of-bounds index has undefined behavior | throws ArrayIndexOutOfBoundsException | raises java.lang.IndexOutOfBoundsException | returns nil | ||||
index of element | a = ['x', 'y', 'y', 'z'] i = a.index('y') | a = %w(x y z w) i = a.index("y") (return nil if not found:) a.index('y') a.rindex('y') | [6, 7, 7, 8].indexOf(7) [6, 7, 7, 8].lastIndexOf(7) (returns -1 if not found) | use List::Util 'first'; @a = qw(x y z w); $i = first {$a[$_] eq "y"} (0..$#a); | $a = ["x", "y", "z", "w"]; $i = array_search("y", $a); | #include <vector> vector<int> a({6, 7, 8, 9}); auto iter = find(a.cbegin(), a.cend(), 8); if (iter != a.cend()) { size_t pos = *iter; } | (evaluates to 1:) List(7, 8, 9).indexOf(8) (evaluates to -1:) List(7, 8, 9).indexOf(10) | import Data.list (Just 1:) elemIndex 8 [7, 8, 9] (Nothing:) elemIndex 10 [7, 8, 9] | none; use for and ipairs | ||||
cons | 1 :: List(2, 3) | 1 :: [2; 3] | 1 : [2, 3] | ||||||||||
slice / by endpoints, by length | (select 3rd and 4th elements:) a[2:4] a[2:2 + 2] | (select 3rd and 4th elements:) a[2..3] a[2, 2] | ["a", "b", "c", "d"].slice(1,3) | # select 3rd and 4th elements: @a[2..3] splice(@a, 2, 2) | (select 3rd and 4th elements:) (none) array_slice($a, 2, 2) | #include <vector> vector<int> a({6, 7, 8, 9}); (a2 contains {7, 8}:) vector<int> a2(a.cbegin() + 1, a.cbegin() + 3); | a.slice(2, 4) | none | |||||
slice from start, or take | List(1, 2, 3).take(2) | take 2 [1, 2, 3] | |||||||||||
slice to end, or drop | a[2:] | a[1..-1] | ["a", "b", "c", "d"].slice(1) | @a[1..$#a] | array_slice($a, 1) | #include <vector> vector<int> a({6, 7, 8, 9}); (a2 contains {7, 8, 9}:) vector<int> a2(a.cbegin() + 1, a.cend()); | List(1, 2, 3).drop(2) | drop 2 [1, 2, 3] | none | ||||
last / and butlast | a[-1] a[:-1] | List(1, 2, 3).last List(1, 2, 3).init | last [1, 2, 3] init [1, 2, 3] | ||||||||||
manipulate back | a = [6, 7, 8] a.append(9) a.pop() | a = [6, 7, 8] a.push(9) a << 9 (same as push) a.pop | a = [6, 7, 8]; a.push(9); i = a.pop(); | @a = (6, 7, 8); push @a, 9; pop @a; | $a = [6, 7, 8]; array_push($a, 9); $a[] = 9; (same as array_push) array_pop($a); | #include <vector> vector<int> a({6, 7, 8}); a.push_back(9); int elem = a.pop_back(); | list.add("hello"); (or) list.add(list.size(), "hello"); vec.removeElementAt(vec.size()-1); | val a = ListBuffer(6, 7, 8) a.append(9) (or) a += 9 a.remove(a.size - 1) (returns removed value) a.trimEnd(1) (does not return value) | a = {6, 7, 8} table.insert(a, 9) i = table.remove(a) | ||||
manipulate front | a = [6, 7, 8] a.insert(0, 5) a.pop(0) | a = [6, 7, 8] a.unshift(5) a.shift | a = [6, 7, 8]; a.unshift(5); i = a.shift(); | @a = (6, 7, 8); unshift @a, 5; shift @a; | $a = [6, 7, 8]; array_unshift($a, 5); array_shift($a); | #include <vector> vector<int> a({6, 7, 8}); (slower than manipulating back:) a.insert(a.cbegin(), 5); int elem = a[0]; a.erase(a.cbegin()); | val a = ListBuffer(6, 7, 8) a.prepend(5) (or) 5 +=: a a.head a.remove(0) (returns removed value) a.trimStart(1) (does not return value) | a = {6, 7, 8} table.insert(a, 1, 5) i = table.remove(a, 1) | |||||
concatenate | a = [1, 2, 3] a2 = a + [4, 5, 6] a.extend([4, 5, 6]) | a = [1, 2, 3] a2 = a + [4, 5, 6] a.concat([4, 5, 6]) | a = [1, 2, 3].concat([4, 5, 6]); | @a = (1, 2, 3); @a2 = (@a, (4, 5, 6)); push @a, (4,5,6); | $a = [1, 2, 3]; $a2 = array_merge($a, [4, 5, 6]); $a = array_merge($a, [4, 5, 6]); | #include <vector> vector<int> a1({1, 2, 3}); vector<int> a2({4, 5, 6}); a1.insert(a1.cend(), a2.cbegin(), a2.cend()); | int[] a = [1, 2, 3]; int[] b = [4, 5, 6]; int[] c = a1 ~ a2; a1 ~= a2; | "hello" + " world" | [1, 2] ++ [3, 4] | none | |||
concatenate / two lists, list of lists | List(1, 2) ::: List(3, 4) List(1, 2) ++ List(3, 4) List(List(1, 2), List(3, 4)).flatten | [1; 2] @ [3; 4] List.append [1; 2] [3; 4] List.concat [[1; 2]; [3; 4]] | [1, 2] ++ [3, 4] concat [[1, 2], [3, 4]] | ||||||||||
list-replicate | a = [None] * 10 a = [None for i in range(0, 10)] | a = [nil] * 10 a = Array.new(10, nil) | @a = (undef) x 10; | #include <vector> (array of 10 zeros:) vector<int> a(10, 0); | val a = List.fill(10)(None) | a = replicate 10 Nothing | none | ||||||
copy / address copy, shallow copy, deep copy | import copy a = [1,2,[3,4]] a2 = a a3 = list(a) a4 = copy.deepcopy(a) | a = [1,2,[3,4]] a2 = a a3 = a.dup a4 = Marshal.load(Marshal.dump(a)) | use Storable 'dclone' my @a = (1,2,[3,4]); my $a2 = \@a; my @a3 = @a; my @a4 = @{dclone(\@a)}; | $a = [1, 2, [3, 4]]; $a2 =& $a; (none) $a4 = $a; | #include <vector> vector<int> a({1, 2, 3}); (copy constructor:) vector<int> a2(a); vector<int> a3; (assignment performs copy:) a3 = a; | ||||||||
array as function arguments | |||||||||||||
arrays as function arguments | parameter contains address copy | parameter contains address copy | each element passed as separate argument; use reference to pass array as single argument | parameter contains deep copy | |||||||||
iterate over elements | for i in [1,2,3]: print(i) | [1, 2, 3].each { |i| puts i } | var len = a.length; for (var i = 0; i < len; i++ ) { alert(a[i]); } | for $i (1, 2, 3) { print "$i\n" } | foreach ([1, 2, 3] as $i) { echo "$i\n"; } | #include <vector> int sum(0); vector<int> a({1, 2, 3}); for (const auto& n: a) { sum += n; } | int sum = 0; int[3] a = [1, 2, 3]; foreach (n; a) { sum += n; } | for ( String s : vec ) { do something with s } | List(1, 2, 3).foreach(i => println(i)) | let f i = print_endline (string_of_int i);; List.iter f [1; 2; 3];; | mapM_ print [1, 2, 3] forM_ [1, 2, 3] print | for k,v in ipairs(a) do print(v) end | |
iterate over indices and elements | a = ['do', 're', 'mi', 'fa'] for i, s in enumerate(a): print('%s at index %d' % (s, i)) | a = %w(do re mi fa) a.each_with_index do |s, i| puts "#{s} at index #{i}" end | none; use range iteration from 0 to $#a and use index to look up value in the loop body | $a = ["do", "re", "mi" "fa"]; foreach ($a as $i => $s) { echo "$s at index $i\n"; } | #include <vector> vector<int> a({6, 7, 8}); for (auto iter = a.cbegin(); iter != a.cend(); ++iter) { cout << "value at " << iter - a.cbegin() << " is " << *iter << endl; } | int[3] a = [6, 7, 8]; foreach (i, n; a) { writeln("value at ", i, " is ", n); } | val a = List("do", "re", "mi", "fa") for ((s, i) <- a.zipWithIndex) println("%s at index %d".format(s, i)) | mapM_ (uncurry $ printf "%s at index %d\n") $ zip ["do", "re", "mi", "fa"] [0..] | |||||
iterate over range | (use range() in Python 3:) for i in xrange(1, 1000001): code | (1..1_000_000).each do |i| (code) end | for $i (1..1_000_000) { code } | not space efficient; use C-style for loop | foreach (i; 1..1000001) { (code) } | (includes 1000000:) for (i <- 1 to 1000000) { (code) } (excludes 1000000:) for (i <- 0 to 1000000) { (code) } | forM_ [1..1000000] (IO monad expression) | ||||||
instantiate range as list | a = range(1, 11) (Python 3:) a = list(range(1, 11)) | a = (1..10).to_a | @a = 1..10; | $a = range(1, 10); | import std.range; auto a = iota(1, 11).array; (1, 2, ..., 10) iota(11) (0, 1, 2, ..., 10) iota(1, 11, 2) (1, 3, 5, 7, 9) | List.range(1, 11) | [1..1000000] (sugar for:) enumFromTo 1 1000000 | ||||||
reverse / non-destructive, in-place | a = [1, 2, 3] a[::-1] reversed(a) (iterator) a.reverse() | a = [1, 2, 3] a.reverse a.reverse! | var a = [1, 2, 3]; a.reverse(); | @a = (1, 2, 3); reverse @a; @a = reverse @a; | $a = [1, 2, 3]; array_reverse($a); $a = array_reverse($a); | #include <vector> vector<int> a({1, 2, 3}); vector<int> a2(a.crbegin(), a.crend()); | List(1, 2, 3).reverse | List.rev [1; 2; 3] | reverse [1, 2, 3] | none | |||
sort / non-destructive / in-place / custom comparision | a = ['b', 'A', 'a', 'B'] sorted(a) a.sort() (custom binary comparision removed from Python 3:) a.sort(key=str.lower) | a = %w(b A a B) a.sort a.sort! a.sort do |x, y| x.downcase <=> y.downcase end | var a = [3, 1, 4, 2]; a.sort(); | @a = qw(b A a B); sort @a; @a = sort @a; sort { lc($a) cmp lc($b) } @a; | $a = ["b", "A", "a", "B"]; (none) sort($a); (none, but usort sorts in place) | #include <vector> vector<int> a({3, 2, 4, 1}); sort(a.begin(), a.end()); | List(1, 3, 2, 4).sortWith((x, y) => x < y) List(1, 3, 2, 4).sortWith(_ < _) List(1, 3, 2, 4).sortWith((x, y) => x > y) List(1, 3, 2, 4).sortWith(_ > _) | List.sort min [1; 3; 2; 4] List.sort max [1; 3; 2; 4] | import Data.List sort [1, 3, 2, 4] sortBy (\x y -> x `compare` y) [1, 3, 2, 4] sortBy (\x y -> y `compare` x) [1, 3, 2, 4] import Data.Ord sortBy (comparing id) [1, 3, 2, 4] sortBy (comparing Down) [1, 3, 2, 4] (Down is newtype that reverses orderings) | a = {3, 1, 4, 2} table.sort(a) | |||
dedupe / non-destructive, in-place | a = [1, 2, 2, 3] a2 = list(set(a)) a = list(set(a)) | a = [1, 2, 2, 3] a2 = a.uniq a.uniq! | use List::MoreUtils 'uniq'; my @a = (1, 2, 2, 3); my @a2 = uniq @a; @a = uniq @a; | $a = [1, 2, 2, 3]; $a2 = array_unique($a); $a = array_unique($a); | #include <set> #include <vector> vector<int> a({1, 1, 2, 2, 3}); set<int> tmp(a.cbegin(), a.cend()); (often unnecessary since sets provide many of the same methods as vectors:) vector<int> a2(tmp.cbegin(), tmp.cend()); | import Data.List a = [1, 2, 2, 3] nub a | none | ||||||
membership | 7 in a | a.include?(7) | 7 ~~ @a | in_array(7, $a) | #include <vector> vector<int> a({1, 2, 3}); if (find(a.cbegin(), a.cend(), 7) != a.cend()) { cout << "contains 7" << endl; } | List(1, 2, 3).contains(3) | elem 3 [1, 2, 3] | none | |||||
map | map(lambda x: x * x, [1,2,3]) (or use list comprehension:) [x * x for x in [1,2,3]] | [1, 2, 3].map { |o| o * o } [1, 2, 3].map &:to_s | (callback gets 3 args: value, index, array) a.map(function(x) { return x * x }) | map { $_ * $_ } (1,2,3) | array_map(function ($x) { return $x * $x; }, [1, 2, 3]) | import std.algorithm; map!(x => x * x)([1, 2, 3]) (same as) [1, 2, 3].map!(x => x * x) map!"a * a"([1, 2, 3]) (same as) [1, 2, 3].map!"a * a" (these are lazy ranges; call .array to get an array) | List(1, 2, 3).map(x => 2 * x) List(1, 2, 3).map(2 * _) for (x <- List(1, 2, 3)) yield 2 * x | List.map (( * ) 2) [1; 2; 3] | map (\x -> x * x) [1, 2, 3] (or use list comprehension:) [x * x | x <- [1, 2, 3]] | none | |||
filter | filter(lambda x: x > 1, [1,2,3]) (or use list comprehension:) [x for x in [1,2,3] if x > 1] | [1, 2, 3].select { |o| o > 1 } | a.filter(function(x) { return x > 1 }) | grep { $_ > 1 } (1,2,3) | array_filter([1, 2, 3], function ($x) { return $x>1; }) | import std.algorithm; filter!(x => x > 1)([1, 2, 3]) (same as) [1, 2, 3].filter!(x => x > 1) filter!"a > 1"([1, 2, 3]) (same as) [1, 2, 3].filter!"a > 1" | List(1, 2, 3).filter(x => x > 2) for (x <- List(1, 2, 3); if x > 2) yield x | List.filter ((<) 2) [1; 2; 3] | filter (\x -> x > 2) [1, 2, 3] (or use list comprehension:) [x | x <- [1, 2, 3], x > 2] | none | |||
fold from left (reduce) | (import needed in Python 3 only) from functools import reduce reduce(lambda x, y: x+y, [1,2,3], 0) | [1, 2, 3].inject(0) { |m,o| m+o } | a.reduce(function(m, o) { return m + o; }, 0) | use List::Util 'reduce'; reduce { $x + $y } 0, (1,2,3) | array_reduce([1, 2, 3], function($x,$y) { return $x + $y; }, 0) | List(1, 2, 3).foldLeft(0)(_ + _) List(1, 2, 3).foldLeft(0)((x, y) => x + y) (0 /: List(1,2,3))(_ + _) | List.fold_left (+) 0 [1; 2; 3] | foldl (+) 0 [1, 2, 3] foldl' (+) 0 [1, 2, 3] (strict variant) | none | ||||
fold from right | List(1, 2, 3).foldRight(0)(_ - _) (List(1,2,3) :\ 0)(_ + _) | List.fold_right (-) [1; 2; 3] 0 | foldr (-) 0 [1, 2, 3] | ||||||||||
universal test | all(i % 2 == 0 for i in [1,2,3,4]) | [1, 2, 3, 4].all? { |i| i.even? } | var a = [1, 2, 3, 4]; var even = function(x) { return x % 2 == 0; }; a.every(even) | # cpan -i List::MoreUtils use List::MoreUtils qw(all any); all { $_ % 2 == 0 } (1,2,3,4) | (use array_filter) | List(1, 2, 3).forall(_ > 2) | List.for_all (fun x -> x > 2) [1; 2; 3];; | all (\x -> x > 2) [1, 2, 3] | |||||
existential test | any(i % 2 == 0 for i in [1,2,3,4]) | [1, 2, 3, 4].any? { |i| i.even? } | a.some(even) | # cpan -i List::MoreUtils use List::MoreUtils qw(all any); any { $_ % 2 == 0 } (1,2,3,4) | (use array_filter) | List(1, 2, 3).exists(_ > 2) | List.exists (fun x -> x > 2) [1; 2; 3];; | any (\x -> x > 2) [1, 2, 3] | |||||
intersection | {1,2} & {2,3,4} | [1,2] & [2,3,4] | $a = [1, 2]; $b = [2, 3, 4] array_intersect($a, $b) | List(1, 2) intersect List(2, 3, 4) (Sets also allow &) | import Data.List intersect [1, 2] [2, 3, 4] | none | |||||||
union | {1,2} | {2,3,4} | [1,2] | [2,3,4] | $a1 = [1, 2]; $a2 = [2, 3, 4]; array_unique(array_merge($a1, $a2)) | List(1, 2) union List(2, 3, 4) (Sets also allow |) | import Data.List union [1, 2] [2, 3, 4] | none | |||||||
relative complement, symmetric difference | {1,2,3} - {2} {1,2} ^ {2,3,4} | require 'set' [1, 2, 3] - [2] Set[1,2] ^ Set[2,3,4] | $a1 = [1, 2, 3]; $a2 = [2]; array_values(array_diff($a1, $a2)) (none) | List(1, 2) diff List(2, 3, 4) (Sets also allow &~) (only BitSets:) import scala.collection.BitSet BitSet(1, 2) ^ BitSet(2, 3, 4) | import Data.List [1, 2] \\ [2, 3, 4] | none | |||||||
min and max element | min([1,2,3]) max([1,2,3]) | List(1,2,3).min List(1,2,3).max | import Data.List minimum [1, 2, 3] maximum [1, 2, 3] | ||||||||||
shuffle and sample | from random import shuffle, sample a = [1, 2, 3, 4] shuffle(a) sample(a, 2) | [1, 2, 3, 4].shuffle [1, 2, 3, 4].sample(2) | use List::Util 'shuffle'; @a = (1, 2, 3, 4); shuffle(@a); (none) | $a = [1, 2, 3, 4]; shuffle($a); array_rand($a, 2) | import scala.util.Random Random.shuffle(List(1, 2, 3, 4)) new Random().shuffle(List(1, 2, 3, 4)) (none) | none | |||||||
zip | (array of 3 pairs:) a = zip([1,2,3], ['a', 'b', 'c']) | (array of 3 pairs:) a = [1, 2, 3].zip(["a", "b", "c"]) | # cpan -i List::MoreUtils use List::MoreUtils 'zip'; @nums = (1, 2, 3); @lets = qw(a b c); # flat array of 6 elements: @a = zip @nums, @lets; | (array of 3 pairs:) $a = array_map(NULL, [1, 2, 3], ["a", "b", "c"]); | List(1,2,3) zip List("a","b","c") (List(1,2,3), List("a","b","c")).zipped (allows mapping etc. with functions taking 2 arguments rather than a 2-tuple) | none | |||||||
zip lists | -- list of tuples: zip [1, 2, 3] ['a', 'b', 'c'] | ||||||||||||
tuples | |||||||||||||
python | ruby | javascript | coffeescript | perl | php | cpp | d | java | scala | ocaml | haskell | lua | |
declare pair | pair <string, int> p1; pair <string, int> p2("foo", 7); auto p3 = make_pair("foo", 7); | import std.typecons; Tuple!(string, int) p1; Tuple!(string, int) p2 = tuple("foo", 7); | |||||||||||
lookup pair elements | auto p = make_pair("foo", 7); cout << "first: " << p.first << endl; cout << "second: " << p.second << endl; | auto p = tuple("foo", 7); p[0] p[1] | |||||||||||
update pair elements | p.first = "bar"; p.second = 8; | p[0] = "bar"; p[1] = 8; | |||||||||||
pair element access | (12, "December")._1 (12, "December")._2 | fst (12, "December") snd (12, "December") | fst (12, "December") snd (12, "December") | ||||||||||
tuple | (1, "hello", true) | (1, "hello", true) | (1, "hello", True) | ||||||||||
declare tuple | tuple<string, int, float> tup1; tuple<string, int, float> tup2( "foo", 1, 3.7); auto tup3 = make_tuple("foo", 1, 3.7); | Tuple!(string, int, float) tup1; Tuple!(string, int, float) tup2 = tuple("foo", 1, 3.7); auto tup3 = tuple("foo", 1, 3.7); | |||||||||||
tuple element access | (1, "hello", true)._1 | match (1, "hello", true) with _, x, _ -> x | (\(a, _, _) -> a) (1, "hello", True) | ||||||||||
lookup tuple elements | tup3[0] tup3[1] tup3[2] | ||||||||||||
update tuple elements | tup3[0] = "bar"; | ||||||||||||
tuple size | |||||||||||||
create references for tuple elements | |||||||||||||
maps or dictionaries | |||||||||||||
python | ruby | javascript | coffeescript | perl | php | cpp | d | java | scala | ocaml | haskell | lua | |
map declaration | #include <map> map<string, int> m; | int[string] m; | java.util.TreeMap<String, Integer> m = new java.util.TreeMap<String, Integer>(); | ||||||||||
map access | d["t"] = 2; d.t = 2; | m["hello"] = 5; cout << m["hello"] << endl; | m["hello"] = 5; writeln(m["hello"]); | m.put("hello", 5); m.get("hello") | import qualified Data.Map as M m M.! k | ||||||||
map size | len(d) | d.size d.length (same as size) | var size = 0; for (var k in d) { if (d.hasOwnProperty(k)) size++; } | scalar(keys %d) | count($d) | m.size() | m.length | m.size() | M.length m | size = 0 for k, v in pairs(d) do size = size + 1 end | |||
map remove element | delete d["t"]; delete d.t; | m.erase(m.find("hello")); | m.remove("hello"); | M.delete k m (returns new map) | |||||||||
map element not found result | returns element created by default constructor of value type | null | |||||||||||
map iterate | map<string,int>::iterator mi; for (mi = m.begin(); mi != m.end(); ++mi) { printf("%s %d", mi->first, mi->second) } | foreach (k, v; m) { writeln(k, " ", v); } | for ( java.util.Map.Entry<String, Integer> e : m.entrySet() ) { use e.getKey() or e.getValue() } | ||||||||||
literal | d = { 't':1, 'f':0 } | d = { "t" => 1, "f" => 0 } | d = { "t":1, "f":0 }; (keys do not need to be quoted if they are a legal JavaScript variable name and not a reserved word) | %d = ( "t" => 1, "f" => 0 ); (barewords permitted in front of => under 'use strict') | $d = ["t" => 1, "f" => 0]; (older syntax:) $d = array("t" => 1, "f" => 0); | (none, use fromList:) M.fromList [('t', 1), ('f', 0)] | d = { t=1, f=0 } | ||||||
lookup | d['t'] | d["t"] | d.t d["t"] | $d{"t"} (barewords permitted inside { } under 'use strict') | $d["t"] | d.t d["t"] | |||||||
out-of-bounds behavior | d = {} raises KeyError: d['lorem'] (adds key/value pair:) d['lorem'] = 'ipsum' | d = {} (evaluates as nil:) d["lorem"] (adds key/value pair:) d["lorem"] = "ipsum" | returns undefined | %d = (); (evaluates as undef:) $d{"lorem"}; (adds key/value pair:) $d{"lorem"} = "ipsum"; | $d = []; evaluates as NULL: $d["lorem"]; adds key/value pair: $d["lorem"] = "ipsum"; | returns nil | |||||||
is key present | 'y' in d | d.has_key?("y") | d.hasOwnProperty("t"); | exists $d{"y"} | array_key_exists("y", $d); | M.delete k m (returns new map) | d["t"] ~= nil | ||||||
delete entry | d = {1: True, 0: False} del d[1] | d = {1 => true, 0 => false} d.delete(1) | %d = ( 1 => "t", 0 => "f" ); delete $d{1}; | $d = [1 => "t", 0 => "f"]; unset($d[1]); | d.t = nil d["t"] = nil | ||||||||
from array of pairs, from even length array | a = [['a', 1], ['b', 2], ['c', 3]] d = dict(a) a = ['a', 1, 'b', 2, 'c', 3] d = dict(zip(a[::2], a[1::2])) | a = [['a', 1], ['b', 2], ['c', 3]] d = Hash[a] a = ['a', 1, 'b', 2, 'c', 3] d = Hash[*a] | @a = (1,"a",2,"b",3,"c"); %d = @a; | ||||||||||
merge | d1 = {'a': 1, 'b': 2} d2 = {'b': 3, 'c': 4} d1.update(d2) | d1 = {'a' => 1, 'b' => 2} d2 = {'b' => 3, 'c' => 4} d1.merge!(d2) | %d1 = (a=>1, b=>2); %d2 = (b=>3, c=>4); %d1 = (%d1, %d2); | $d1 = ["a"=>1, "b"=>2]; $d2 = ["b"=>3, "c"=>4]; $d1 = array_merge($d1, $d2); | |||||||||
invert | to_num = {'t':1, 'f':0} (dict comprehensions added in 2.7:) to_let = {v:k for k, v in to_num.items()} | to_num = {'t' => 1, 'f' => 0} to_let = to_num.invert | %to_num = (t=>1, f=>0); %to_let = reverse %to_num; | $to_num = ["t"=>1, "f"=>0]; $to_let = array_flip($to_num); | |||||||||
iteration | for k, v in d.iteritems(): (code) (Python 3:) for k, v in d.items(): (code) | d.each do |k,v| (code) end | for (var k in d) { (use k or d[k]) } | while (($k, $v) = each %d) { (code) } | foreach ($d as $k => $v) { (code) } | for k,v in pairs(d) do use k or v end | |||||||
keys and values as arrays | d.keys() d.values() (Python 3:) list(d.keys()) list(d.values()) | d.keys d.values | keys %d values %d | array_keys($d) array_values($d) | |||||||||
sort by values | from operator import itemgetter pairs = sorted(d.iteritems(), key=itemgetter(1)) for k, v in pairs: print('{}: {}'.format(k, v)) | d.sort_by {|k, v| v}.each do |k, v| puts "#{k}: #{v}" end | foreach $k (sort { $d{$a} <=> $d{$b} } keys %d) { print "$k: $d{$k}\n"; } | asort($d); foreach ($d as $k => $v) { print "$k: $v\n"; } | |||||||||
default value, computed value | from collections import defaultdict counts = defaultdict(lambda: 0) counts['foo'] += 1 class Factorial(dict): def __missing__(self, k): if k > 1: return k * self[k-1] else: return 1 factorial = Factorial() | counts = Hash.new(0) counts['foo'] += 1 factorial = Hash.new do |h,k| k > 1 ? k * h[k-1] : 1 end | my %counts; $counts{'foo'} += 1 define a tied hash for computed values and defaults other than zero or empty string | $counts = []; $counts['foo'] += 1; extend ArrayObject for computed values and defaults other than zero or empty string. | |||||||||
functions | |||||||||||||
python | ruby | javascript | coffeescript | perl | php | cpp | d | java | scala | ocaml | haskell | lua | |
declare function | function add(x, y) { return x+y; } | (parameter names are optional:) int add(int m, int n); | function add(x, y) return x + y end | ||||||||||
define function | def add3(x1, x2, x3): return x1 + x2 + x3 | def add3(x1, x2, x3) x1 + x2 + x3 end (parens are optional and customarily omitted when defining functions with no parameters) | sub add3 { $_[0] + $_[1] + $_[2] } sub add3 { my ($x1, $x2, $x3) = @_; $x1 + $x2 + $x3; } | function add3($x1, $x2, $x3) { return $x1 + $x2 + $x3; } | int add(int m, int n) { return m + n; } | int add(int m, int n) { return m + n; } | (argument types must be declared:) def add3(x1: Int, x2: Int, x3: Int) = x1 + x2 + x3 def average(a: Double, b: Double) = (a + b) / 2.0 (return value type must be declared if function is recursive:) def factorial(n: Int): Int = if (n < 1) 1 else n * factorial(n - 1) | let average a b = ( a +. b ) /. 2.0;; | average a b = (a + b) / 2.0 | ||||
define function with block body | (braces must be used if body not an expression:) def print_numbers() = { println("one") println("two") } | ||||||||||||
invoke function | add3(1, 2, 3) | add3(1, 2, 3) (parens are optional:) add3 1, 2, 3 | add(1, 2) | add(1, 2) add 1, 2 | add3(1, 2, 3); (parens are optional:) add3 1, 2, 3; | add3(1, 2, 3); (function names are case insensitive:) ADD3(1, 2, 3); | int sum = add(3, 7); | int sum = add(3, 7); | (3.0:) average(1, 2 + 3) (4.5:) average(1, 2) + 3 (parens can be omitted when a function takes no arguments, mainly for Java interopability; by convention parens are omitted when the function has no side effects) | (* 4.5: *) average 1.0 2.0 +. 3.0;; (* 3.0: *) average 1.0 (2.0 +. 3.0);; | (4.5, as function application has highest precedence:) average 1 2 + 3 (3.0:) average 1 (2 + 3) average 1 $ 2 + 3 | add(1, 2) | |
apply function to array | a = [2, 3] add3(1, *a) (splat operator can only be used once, and must appear after other unnamed arguments) | a = [2, 3] add3(1, *a) (splat operator can be used multiple times and can appear before regular arguments) | @a = (2, 3); add3(1, @a); (arrays are always expanded when used as arguments) | $a = [1, 2, 3]; call_user_func_array("add3", $a); | (only for functions defined with variable number of arguments:) def firstAndLast(a: Int*) = { (...) } val a = List(1, 2, 3) firstAndLast(a:_*) | ||||||||
define static class method | (Ops.h:) class Ops { public: static int add(int m, int n); }; (Ops.cpp:) int Ops::add(int m, int n) { return m + n; } | ||||||||||||
invoke static class method | int sum = Ops::add(3, 7); (class name not needed inside class namespace:) int sum = add(3, 7); | ||||||||||||
overload function | int add(int m, int n) { return m + n; } float add(float x, float y) { return x + y; } | yes | |||||||||||
missing argument behavior | raises TypeError if number of arguments doesn't match function arity | raises ArgumentError if number of arguments doesn't match function arity | undefined | set to undef | set to NULL with warning | nil | |||||||
extra arguments | available in arguments | ignored | |||||||||||
default argument | import math def my_log(x, base=10): return math.log(x) / math.log(base) my_log(42) my_log(42, math.e) | def my_log(x, base=10) Math.log(x) / Math.log(base) end my_log(42) my_log(42, Math::E) | myLog = (x, base = 10) -> Math.log(x) / Math.log(base) | sub my_log { my $x = shift; my $base = shift // 10; log($x) / log($base); } my_log(42); my_log(42, exp(1)); | function my_log($x, $base=10) { return log($x) / log($base); } my_log(42); my_log(42, M_E); | #include <cmath> float logarithm(float x, float base = 10.0) { return log(x) / log(base); } | use method overloading | ||||||
variable number of arguments | def first_and_last(*a): if len(a) >= 1: print('first: ' + str(a[0])) if len(a) >= 2: print('last: ' + str(a[-1])) | def first_and_last(*a) if a.size >= 1 puts "first: #{a[0]}" end if a.size >= 2 puts "last: #{a[-1]}" end end | args in arguments[0], arguments[1], … with number of args in arguments.length | sub first_and_last { if ( @_ >= 1 ) { print "first: $_[0]\n"; } if ( @_ >= 2 ) { print "last: $_[-1]\n"; } } | function first_and_last() { $arg_cnt = func_num_args(); if ($arg_cnt >= 1) { $n = func_get_arg(0); echo "first: " . $n . "\n"; } if ($arg_cnt >= 2) { $a = func_get_args(); $n = $a[$arg_cnt-1]; echo "last: " . $n . "\n"; } } | public static String concat(String first, String… rest) { StringBuilder sb = new StringBuilder(first); for (String arg: rest) { sb.append(arg); } return sb.toString(); } String s = Concat.concat("Hello", ", ", "World", "!"); | def firstAndLast(a: Int*) = { if (a.length >= 1) println("first: " + a.head) if (a.length >= 2) println("last: " + a.last) } | declare function with ellipsis: function foo(...) local arg = {...} | |||||
named parameters | def fequal(x, y, eps=0.01): return abs(x - y) < eps fequal(1.0, 1.001) fequal(1.0, 1.001, eps=0.1**10) | def fequal(x, y, opts={}) eps = opts[:eps] || 0.01 (x - y).abs < eps end fequal(1.0, 1.001) fequal(1.0, 1.001, :eps=>0.1**10) (Ruby 2.0:) def fequals(x, y, eps: 0.01) (x - y).abs < eps end fequals(1.0, 1.001) fequals(1.0, 1.001, eps: 0.1**10) | none | none | def subtract(m: Int, s: Int) = m - s subtract(s = 3, m = 7) | let subtract ~m ~s = m - s;; subtract ~s: 3 ~m: 7;; | |||||||
named parameter default value | def logarithm(x: Double, base: Double = math.exp(1)) = math.log(x) / math.log(base) logarithm(2.718) logarithm(10, base = 2) | let logarithm ?(base = (exp 1.0)) x = log x /. (log base);; logarithm 2.718;; logarithm ~base: 2.0 10.0;; | |||||||||||
pass by value | int add1(int n) { return ++n; } int i(7); (set i2 to 8 w/o modifying i:) int i2 = add1(i); | int add1(int n) { return ++n; } int i = 7; int i2 = add1(i); | primitive types are always passed by value | ||||||||||
pass by reference | int add1(int& n) { return ++n; } int i(7); (set i and i2 to 8:) int i2 = add1(i); | int add1(ref int n) { return ++n; } int i = 7; int i2 = add1(i); | objects and arrays are always passed by reference | ||||||||||
pass by address | int add1(int* n) { return ++*n; } int i(7); (set i and i2 to 8:) int i2 = add1(&i); | int add1(int* n) { return ++*n; } int i = 7; int i2 = add1(&i); | none | ||||||||||
pass number or string by reference | not possible | not possible | sub foo { $_[0] += 1; $_[1] .= "ly"; } my $n = 7; my $s = "hard"; foo($n, $s); | function foo(&$x, &$y) { $x += 1; $y .= "ly"; } $n = 7; $s = "hard"; foo($n, $s); | |||||||||
pass array or dictionary by reference | def foo(x, y): x[2] = 5 y['f'] = -1 a = [1,2,3] d = {'t':1, 'f':0} foo(a, d) | def foo(x, y) x[2] = 5 y["f"] = -1 end a = [1,2,3] d = {"t"=> 1, "f" => 0 } foo(a, d) | sub foo { $_[0][2] = 5; $_[1]{"f"} = -1; } my @a = (1,2,3); my %d = ("t"=> 1, "f" => 0); foo(\@a, \%d); | function foo(&$x, &$y) { $x[2] = 5; $y["f"] = -1; } $a = [1, 2, 3]; $d = ["t"=>1, "f"=>0]; foo($a, $d); | |||||||||
return value | return arg (or None, if not specified) | return arg or last expression evaluated | return arg or undefined. If invoked with new and return value not an object, returns this | return arg or last expression evaluated | return arg or NULL | argument of return; type must be declared | return arg or nil | ||||||
no return value | void message(const string& msg) { cout << msg << endl; } | ||||||||||||
multiple return values | def first_and_second(a): return a[0], a[1] x, y = first_and_second([1,2,3]) | def first_and_second(a) return a[0], a[1] end x, y = first_and_second([1,2,3]) | none | sub first_and_second { return ($_[0], $_[1]); } @a = (1,2,3); ($x, $y) = first_and_second(@a); | function first_and_second(&$a) { return [$a[0], $a[1]]; } $a = [1, 2, 3]; list($x, $y) = first_and_second($a); | function roots(x) r = math.sqrt(x) return r, -r end r1,r2 = roots(4) | |||||||
piecewise defined function | let to_s = function Red -> "red" | Green -> "green" | Blue -> "blue";; | to_s Red = "red" to_s Green = "green" to_s Blue = "blue" | |||||||||||
recursive function | int factorial(int n) { if (n <= 1) { return 1; } return n * factorial(n - 1); } | int factorial(int n) { if (n <= 1) { return 1; } return n * factorial(n - 1); } | def range(a:Int, b:Int): List[Int] = if (a > b) List() else a :: range(a + 1, b) | let rec range a b = if a > b then [] else a :: range (a+1) b;; | range a b = if a > b then [] else a : range (a+1) b | ||||||||
mutually recursive functions | let rec even n = if n = 0 then true else odd (n-1) and odd n = if n = 0 then false else even (n-1);; | ||||||||||||
anonymous function | |||||||||||||
invoke anonymous function | (on variable holding anon. function:) int sum = add(3, 7); (on lambda expression:) int sum2 = [](int n, int m) { return n + m; }(3, 7); | ||||||||||||
lambda (anonymous function) declaration | (body must be an expression:) sqr = lambda x: x * x | sqr = lambda { |x| x * x } | sqr = function(x) { return x*x; } | square = (x) -> x * x | $sqr = sub { $_[0] * $_[0] } | $sqr = function ($x) { return $x * $x; }; | auto add = [](int n, int m) { return n + m; }; (with explicit type annotation and capture-by-reference:) #include <functional> std::function<int(int)> fibo = [&](int x){ return x <= 1 ? x : fibo(x-1) + fibo(x-2); }; | (x: Double, y: Double) => (x + y) / 2.0 | fun x -> fun y -> (x +. y) /. 2.0 | \x y -> (x+y) / 2.0 | sqr = function(x) return x*x end | ||
lambda (anonymous function) invocation | sqr(2) | sqr.call(2) (or) sqr[2] | sqr(2) | $sqr->(2) | $sqr(2) | sqr(2) | |||||||
closure | (Python 3:) def make_counter(): i = 0 def counter(): nonlocal i i += 1 return i return counter nays = make_counter() | def make_counter i = 0 return lambda { i +=1; i } end nays = make_counter puts nays.call | sub make_counter { my $i = 0; return sub { ++$i }; } my $nays = make_counter; print $nays->() . "\n"; | function make_counter() { $i = 0; return function () use (&$i) { return ++$i; }; } $nays = make_counter(); echo $nays(); | |||||||||
function as value | func = add | func = lambda {|*args| add(*args)} | my $func = \&add; | $func = "add"; | |||||||||
function with private state | (state not private:) def counter(): counter.i += 1 return counter.i counter.i = 0 print(counter()) | none | use feature state; sub counter { state $i = 0; ++$i; } print counter() . "\n"; | function counter() { static $i = 0; return ++$i; } echo counter(); | int counter() { static int i = 0; return ++i; } | ||||||||
generator | (The itertools library contains standard generators. c.f. itertools.count()) def make_counter(): i = 0 while True: i += 1 yield i nays = make_counter() print(nays.next()) | def make_counter return Fiber.new do i = 0 while true i += 1 Fiber.yield i end end end nays = make_counter puts nays.resume | (PHP 5.5:) function make_counter() { $i = 0; while (1) { yield ++$i; } } $nays = make_counter(); (does not return a value:) $nays->next(); (runs generator if generator has not yet yielded:) echo $nays->current(); | crt = coroutine.create( function (n) while (true) do coroutine.yield(n % 2) n = n + 1 end end ) status, retval = coroutine.resume(crt, 1) if status then print("parity: " .. retval) else print("couldn't resume crt") end _, retval = coroutine.resume(crt) print("parity: " .. retval) | |||||||||
decorator | def logcall(f): def wrapper(*a, **opts): print('calling ' + f.__name__) f(*a, **opts) print('called ' + f.__name__) return wrapper @logcall def square(x): return x * x | ||||||||||||
operator as function | import operator operator.mul(3, 7) a = ['foo', 'bar', 'baz'] operator.itemgetter(2)(a) | 3.*(7) a = ['foo', 'bar', 'baz'] a.[](2) | ((_:Int) * (_:w.Int))(3, 7) (implicit Numeric[T] make many math operations implicitly available) (Seqs are automatically functions sending an index to its corresponding element) | ||||||||||
overload operator | class Rational: (...) def __add__(self, o): return Rational(self.num * o.denom + o.num * self.denom, self.denom * o.denom) (use special method names) | class Fixnum def /(n) self.fdiv(n) end end | Rational Rational::operator+(Rational& o) { return Rational(this->num * o.denom + o.num * this->denom, this->denom * o.denom); } | ref Rational opBinary(string op)(in Rational o) if (op == "+") { (compile-time test) return Rational(this.num * o.denom + o.num * this.denom, this.denom * o.denom); } | none | (almost all operators in Scala are just methods with symbolic names:) class Rational(val num: Int, val denom: Int) { (...) def +(o: Rational) = new Rational(num * o.denom + o.num * denom, denom * o.denom) } | |||||||
default scope | global unless declared with var | global unless declared with local | |||||||||||
default value | none | ||||||||||||
nested function visibility | not visible outside containing function | visible outside containing function | |||||||||||
infix operator in prefix position | ( * ) 3 4;; | ( * ) 3 4 | |||||||||||
function in infix position | unary methods can be used as binary operators | none | add x y = x + y 3 `add` 4 | ||||||||||
currying | def plus(x: Int)(y: Int) = x + y plus(3)(7) (must follow with underscore for partial application:) def plus2 = plus(2) _ plus2(7) | let plus2 = (+) 2;; | plus2 = add 2 plus2 = (+) 2 (infix operators allow partial application by supplying one operand on either side:) half = (/ 2) twoOver = (2 /) | ||||||||||
composition | val f = (x: Int) => x + 2 val g = (x: Int) => x * 3 (f compose g)(4) | f x = x + 2 g x = x * 3 (f . g) 4 | |||||||||||
function composition operator | val double = (x: Int) => 2 * x val quadruple = double compose double | none | double x = 2 * x quadruple x = double . double | ||||||||||
lazy evaluation | def arg1(x: => Int, y: => Int): Int = x arg1(7, 1 / 0) | let arg1 x y = x;; arg1 7 (lazy (1/0) );; | (lazy evaluation is default:) arg1 x y = x arg1 7 (error "bam!") | ||||||||||
strict evaluation | (default behavior) | default behavior | arg1 x y = seq y x arg1 7 (error "bam!") | ||||||||||
execution control | |||||||||||||
python | ruby | javascript | coffeescript | perl | php | cpp | d | java | scala | ocaml | haskell | lua | |
if | if 0 == n: print('no hits') elif 1 == n: print('one hit') else: print(str(n) + ' hits') | if n == 0 puts "no hits" elsif 1 == n puts "one hit" else puts "#{n} hits" end | if (0 == n) { alert("no hits"); } else if (1 == n) { alert("1 hit"); } else { alert(n + " hits"); } | if 0 == n alert "no hits" else if 1 == n alert "1 hit" else alert n + "hits" | if ( 0 == $n ) { print "no hits\n" } elsif ( 1 == $n ) { print "one hit\n" } else { print "$n hits\n" } | if ( 0 == $n ) { echo "no hits\n"; } elseif ( 1 == $n ) { echo "one hit\n"; } else { echo "$n hits\n"; } | int signum; if (n > 0) { signum = 1; } else if (n == 0) { signum = 0; } else { signum = -1; } | int signum; if (n > 0) { signum = 1; } else if (n == 0) { signum = 0; } else { signum = -1; } | if (i>0) { signum = 1; } else if (i==0) { signum = 0; } else { signum = -1; } | if ( x > 0 ) println("pos") | if x > 0 then print_endline "pos";; | if x > 0 then putStrLn "pos" else return () | if n == 0 then print("no hits") elseif n == 1 then print("one hit") else print(n .. " hits") end |
dangling else | if (n == 0) if (m == 0) cout << "n and m are zero" << endl; else cout << "n is zero; m isn't" << endl; | ||||||||||||
sequencing | println("one") println("two") println("three") | print_endline "one"; print_endline "two"; print_endline "three";; | do putStrLn "one" putStrLn "two" putStrLn "three" (sugar for:) putStrLn "one" >> putStrLn "two" >> putStrLn "three" | ||||||||||
switch | (none) | case n when 0 puts "no hits" when 1 puts "one hit" else puts "#{n} hits" end | switch n when 0 then "no hits" when 1 then "one hit" else "#{n} hits" | use feature 'switch'; given ($n) { when (0) { print "no hits\n"; } when (1) { print "one hit\n"; } default { print "$n hits\n"; } } | switch ($n) { case 0: echo "no hits\n"; break; case 1: echo "one hit\n"; break; default: echo "$n hits\n"; } | const int INVALID_BINARY_DIGIT(-1); int bin_digit; switch(n) { case 0: case 1: bin_digit = n; break; default: bin_digit = INVALID_BINARY_DIGIT; break; } | const int INVALID_BINARY_DIGIT = -1; int bin_digit; switch(n) { case 0, 1: bin_digit = n; break; default: bin_digit = INVALID_BINARY_DIGIT; break; } | switch(i) { case 0: 0; break; case 1: 1; break; default: -1; break; } | |||||
while | while i < 100: i += 1 | while i < 100 do i += 1 end | while ( i < 100 ) { i += 1; } | while i < 100 i += 1 (when used as an expression, returns array containing result of each iteration) (alternate) i += 1 while i < 100 | while ( $i < 100 ) { $i++ } | while ( $i < 100 ) { $i++; } | int i(1), fact(1), n(10); while (i < n) { fact *= i; ++i; } | int i = 1, fact = 1, n = 10; while (i < n) { fact *= i; ++i; } | int i = 0; while (i<10) { … i++; } | var i = 0 while (i < 10) { printf("%d\n", i) i = i+1 } | let i = ref 0;; while !i < 10 do print_endline (string_of_int !i); i := !i + 1 done;; | while i < 100 do i = i + 1 end | |
for | for i in range(10): print(i) | for i in [0...10] alert i name for name of window (iterate over properties) | int fact, n(10); for (int i = 1, fact = 1; i <= n; ++i) { fact *= i; } | int fact; for (i; 1 .. 11) { (half-open) fact *= i; } | int n = 1; for (int i=1; i<=10; i++) { n *= i; } | for (i <- 1 to 10) println(i) | for i = 1 to 10 do let s = string_of_int i in print_endline s done;; | for i = 0, 9 do print(i) end | |||||
for in reverse | for i = 10 downto 1 do let s = string_of_int i in print_endline s done;; | ||||||||||||
c-style for | none | for (var i=0; i<10; i++) { alert(i); } | for ( $i=0; $i <= 10; $i++ ) { print "$i\n"; } | for ($i = 1; $i <= 10; $i++) { echo "$i\n"; } | |||||||||
break | break | break | int data[4] = {3, 2, 0, 1}; int i; bool has_zero(false); for (i = 0; i < 4; ++i) { if (data[i] == 0) { has_zero = true; break; } } | ||||||||||
break out of nested loops | int data[2][2] = {{3, 2}, {0, 1}}; int i, j; bool has_zero(false); for (i = 0; i < 2; ++i) { for (j = 0; j < 2; ++j) { if (data[i][j] == 0) { has_zero = true; goto end_of_loops; } } } :end_of_loops | ||||||||||||
continue | continue | continue | int a[4] = {3, 2, 0, 1}; for (int i = 0; i < 4; ++i) { if (a[i] == 0) { continue; } cout << 1.0 / a[i] << endl; } | ||||||||||
goto | |||||||||||||
break, continue, redo | break continue (none) | break next redo | break continue | last next redo | break continue none | break none | |||||||
control structure keywords | elif else for if while | case do else elsif end for loop when while unless until | do else elsif for foreach goto if unless until while | case default do else elseif for foreach goto if switch while | if (x > 0) println("pos") else if (x < 0) println("neg") else println("zero") | if x > 0 then print_endline "pos" else if x < 0 then print_endline "neg" else print_endline "zero";; | if x > 0 then putStrLn "pos" else if x < 0 then putStrLn "neg" else putStrLn "zero" | ||||||
what do does | raises NameError unless a value was assigned to it | starts an anonymous block. Also starts the body of a loop, while, or until loop | immediately invokes a function, forwarding arguments (useful for forcing closure) | executes following block and returns value of last statement executed | starts body of a do-while loop, a loop which checks the condition after the body is executed | ||||||||
statement modifiers | (none) | puts "positive" if i > 0 puts "nonzero" unless i == 0 | print "positive\n" if $i > 0; print "nonzero\n" unless $i == 0; | none | |||||||||
generator | (The itertools library contains standard generators. c.f. itertools.count()) def make_counter(): i = 0 while True: i += 1 yield i nays = make_counter() print(nays.next()) | def make_counter return Fiber.new do i = 0 while true i += 1 Fiber.yield i end end end nays = make_counter puts nays.resume | (PHP 5.5:) function make_counter() { $i = 0; while (1) { yield ++$i; } } $nays = make_counter(); (does not return a value:) $nays->next(); (runs generator if generator has not yet yielded:) echo $nays->current(); | crt = coroutine.create( function (n) while (true) do coroutine.yield(n % 2) n = n + 1 end end ) status, retval = coroutine.resume(crt, 1) if status then print("parity: " .. retval) else print("couldn't resume crt") end _, retval = coroutine.resume(crt) print("parity: " .. retval) | |||||||||
list iteration | for (i <- List.range(1, 11).reverse) println(i) | none | |||||||||||
exceptions | |||||||||||||
python | ruby | javascript | coffeescript | perl | php | cpp | d | java | scala | ocaml | haskell | lua | |
base exception | BaseException (User-defined exceptions should subclass Exception.) (In Python 2 old-style classes can be thrown.) | Exception (User-defined exceptions should subclass StandardError.) | Any type can be thrown. All exceptions thrown by the language or the standard library derive from exception, defined in <exception>. | Any type which implements the interface java.lang.Throwable can be thrown. Exceptions thrown by the language and the standard libraries derive from java.lang.Errror or java.lang.Exception. | |||||||||
type of exceptions | exn | IOError | |||||||||||
predefined exceptions | BaseException SystemExit KeyboardInterrupt GeneratorExit Exception StopIteration StandardError BufferError ArithmeticError FloatingPointError OverflowError ZeroDivisionError AssertionError AttributeError EnvironmentError EOFError ImportError LookupError IndexError KeyError MemoryError NameError ReferenceError RuntimeError NotImplementedError SyntaxError SystemError TypeError ValueError UnicodeError (Python 3 has a different tree) | Exception NoMemoryError ScriptError LoadError NotImplementedError SyntaxError SignalException StandardError ArgumentError IOError EOFError IndexError LocalJumpError NameError RangeError RegexpError RuntimeError SecurityError SocketError SystemCallError Errno::* SystemStackError ThreadError TypeError ZeroDivisionError SystemExit fatal | #include <exception> #include <stdexcept> #include <system_error> #include <typeinfo> exception logic_error domain_error invalid_argument length_error out_of_range runtime_error system_error ios_base::failure bad_cast bad_exception bad_alloc | java.lang.Throwable java.lang.Error java.lang.Exception java.lang.IOException java.lang.RuntimeException java.lang.ArithmeticException java.lang.IllegalArgumentException java.lang.IndexOutOfBoundsException java.lang.NullPointerException | |||||||||
standard exceptions | Division_by_zero Failure string Not_found Invalid_argument string Match_failure (string, int, int) Assert_failure (string, int, int) Out_of_memory Stack_overflow | ||||||||||||
define exception | class Bam(Exception): def __init__(self): super(Bam, self).__init__('bam!') | class Bam < Exception def initialize super("bam!") end end | class Bam extends Exception { function __construct() { parent::__construct("bam!"); } } | #include <stdexcept> class Bam : public runtime_error { public: Bam() : runtime_error("bam!") {} }; throw Bam(); | |||||||||
user defined exception | exception Foo of string;; raise (Foo "invalid input");; | ||||||||||||
raise exception | raise Exception('bad arg') | raises RuntimeError raise "bad arg" | throw "bad arg"; | die "bad arg"; | throw new Exception("bad arg"); | #include <cstdlib> #include <stdexcept> void risky() { if (rand() < 10) { throw runtime_error("bam!"); } } | throw new Exception("failed"); | throw new Exception("bam!") | error "bad arg" | ||||
re-raise exception | try: raise Exception('bam!') except: print('re-raising...') raise | begin raise "bam!" rescue puts "re-raising…" raise end | #include <stdexcept> try { risky(); } catch (const exception& e) { cout << "an error occurred..." << endl; throw; } | ||||||||||
handle exception | #include <stdexcept> try { risky(); } catch (const exception &e) { cout << e.what() << endl; } | try { throw new Exception("failed"); } catch (Exception e) { System.out.println(e.getMessage()); } | import java.lang._ val x = try { 1 / 0 } catch { case e: ArithmeticException => 0 } | ||||||||||
catch exception | try: risky() except: print('risky failed') | (catches StandardError) begin risky rescue print "risky failed: " puts $!.message end | try { risky(); } catch (e) { alert("risky failed"); } | eval { risky }; if ($@) { print "risky failed: $@\n"; } | try { risky(); } catch (Exception $e) { echo "risky failed: ", $e->getMessage(), "\n"; } | if not pcall(risky) then print "risky failed" end | |||||||
catch exception by type | try: raise Bam() except Bam as e: print(e) | begin raise Bam.new rescue Bam => e puts e.message end | try { throw new Bam; } catch (Bam $e) { echo $e->getMessage(), "\n"; } | ||||||||||
catch-all handler | try: risky() except: print('risky failed') | #include <stdexcept> try { risky(); } catch (...) { cout << "an error was ignored" << endl; } | |||||||||||
global variable for last exception | last exception: sys.exc_info()[1] | last exception: $! backtrace array of exc.: $@ exit status of child: $? | $EVAL_ERROR: $@ $OS_ERROR: $! $CHILD_ERROR: $? | none | |||||||||
finally/ensure | acquire_resource() try: risky() finally: release_resource() | acquire_resource begin risky ensure release_resource end | acquire_resource(); try { risky(); } finally { release_resource(); } | none | none | try { risky code } finally { perform cleanup } | none | ||||||
multiple handlers | #include <stdexcept> try { risky(); } catch (const system_error &e) { cout << "system error: " << e.name() << endl; } catch (const exception &e) { cout << "exception: " << e.what() << endl; } catch (...) { cout << "unknown error" << endl; } | ||||||||||||
uncaught exception behavior | error to console; script terminates. Other scripts in page will execute | calls terminate() which by default calls abort() | stderr and exit | ||||||||||
error message | #include <exception> try { risky(); } catch (const exception &e) { const char *msg = e.what(); } | ||||||||||||
system call errno | #include <system_error> try { risky(); } catch (const system_error &e) { int err_code_val = e.code().value(); } | ||||||||||||
exception specification | (Use noexcept to declare that a function does not raise exceptions; declaring which exceptions a function raises is deprecated in C++11.) int add(int a, int b) noexcept { return a + b; } | yes | |||||||||||
assert | assert(1 == 0) | assert(1 = 0);; | |||||||||||
errors | |||||||||||||
python | ruby | javascript | coffeescript | perl | php | cpp | d | java | scala | ocaml | haskell | lua | |
raise error | raise (Failure "bam!");; or failwith "bam!";; | error "bam!" | |||||||||||
handle error | let x = try 1 / 0 with Division_by_zero -> 0;; | import System.IO.Error dangerous :: IO () dangerous = error "bam!" handler :: IOError -> IO () handler e = putStrLn "Caught error!" dangerous `catch` handler | |||||||||||
concurrency | |||||||||||||
python | ruby | javascript | coffeescript | perl | php | cpp | d | java | scala | ocaml | haskell | lua | |
start thread | class sleep10(threading.Thread): def run(self): time.sleep(10) thr = sleep10() thr.start() | thr = Thread.new { sleep 10 } | use threads; $func = sub { sleep 10 }; $thr = threads->new($func); | none | |||||||||
terminate current thread | |||||||||||||
terminate other thread | |||||||||||||
list threads | |||||||||||||
wait on thread | thr.join() | thr.join | $thr->join; | ||||||||||
lock | |||||||||||||
create message queue | |||||||||||||
send message | |||||||||||||
receive message | |||||||||||||
file handles | |||||||||||||
python | ruby | javascript | coffeescript | perl | php | cpp | d | java | scala | ocaml | haskell | lua | |
standard file handles | sys.stdin sys.stdout sys.stderr | $stdin $stdout $stderr | STDIN STDOUT STDERR | only set by CLI; not set when reading script from stdin: STDIN STDOUT STDERR | cin cout cerr clog | stdin stderr stdout | System.in System.out System.err | System.in System.out System.err | stdin stdout stderr | import System.IO stdin, stdout, stderr :: Handle | io.stdin io.stdout io.stderr | ||
read line from stdin | line = sys.stdin.readline() | line = gets | js: var line = readline(); | $line = <STDIN>; | $line = fgets(STDIN); | string line = readln(); | val line = readLine() | let line = read_line();; | line <- getLine | line = io.stdin:read() | |||
write line to stdout | print('Hello, World!') | puts "Hello, World!" | var sys = require('sys'); sys.puts("Hello, World!"); | print "Hello, World!\n"; | echo "Hello, World!\n"; | writeln("Hello, world!"); | println("lorem ipsum") | print_endline "lorem ipsum";; | putStrLn "lorem ipsum" | print "Hello, World!" | |||
printf | import math print('%.2f' % math.pi) | printf("%.2f\n", Math::PI) | use Math::Trig 'pi'; printf("%.2f\n", pi); | printf("%.2f\n", M_PI); | cout << "count: " << 7 << endl; | writef("count: %d\n", 7); writefln("count: %d", 7); | System.out.printf("count: %d", 7); | import Text.Printf printf :: PrintfType r => String -> r (printf can be an IO action or a string, taking any number of format arguments, chosen by type-inference magic) | |||||
open file | |||||||||||||
open file for reading | f = open('/etc/hosts') | f = File.open("/etc/hosts") | var fs = require('fs'); f = fs.openSync("/tmp/foo", "r"); | open my $f, "/etc/hosts" or die; | $f = fopen("/etc/hosts", "r"); | import scala.io.Source val path = "/etc/hosts" val f = Source.fromFile(path) | let f = open_in "/etc/passwd";; | import System.IO f <- openFile "/etc/hosts" ReadMode | f = io.open("/tmp/foo") | ||||
open file for writing | f = open('/tmp/test', 'w') | f = File.open("/tmp/test", "w") | var fs = require('fs'); f = fs.openSync("/tmp/foo", "w"); | open my $f, ">/tmp/test" or die; | $f = fopen("/tmp/test", "w"); | let f = open_out "/tmp/ocaml.out";; | import System.IO f <- openFile "/tmp/test" WriteMode | f = io.open("/tmp/foo", "w") | |||||
open file for appending | f = open('/tmp/err.log', 'a') | f = File.open("/tmp/err.log", "a") | open my $f, ">>/tmp/err.log" or die; | $f = fopen("/tmp/test", "a"); | import System.IO f <- openFile "/tmp/err.log" AppendMode | ||||||||
set file handle encoding | import codecs fin = codecs.open('/tmp/foo', encoding='utf-8') fout = codecs.open('/tmp/bar', 'w', encoding='utf-8') | fin = File.open("/tmp/foo", "r:utf-8") fout = File.open("/tmp/bar", "w:utf-8") | open my $fin, "<:encoding(UTF-8)", "/tmp/foo" or die; open my $fout, ">:encoding(UTF-8)", "/tmp/bar" or die; | ||||||||||
read line | f.readline() | f.gets | $line = <$f>; | $line = fgets($f); | let ic = open_in "/etc/passwd" in let line = input_line ic in print_endline line;; | line <- hGetLine f | f:read() | ||||||
chomp | line = line.rstrip('\r\n') | line.chomp! | chomp $line; | chop($line); | none, read() and lines() remove trailing newlines | ||||||||
read file | var fs = require('fs'); fs.readFileSync("/tmp/foo", "utf8"); | f:read("*a") | |||||||||||
read from file | #include <fstream> string line; ifstream f("/etc/passwd"); if (f.is_open()) { while (!f.eof()) { getline(f, line); (process line) } f.close(); if ( 0 != f.fail() ) { (handle error) } } else { (handle error) } | import java.io.BufferedReader; import java.io.FileReader; BufferedReader in = new BufferedReader(new FileReader("/etc/passwd")); String line; while ((line = in.readLine()) != null) { process line } | |||||||||||
iterate over file by line | for line in f: print(line) | f.each do |line| print(line) end | var fs = require('fs'); var file = fs.readFileSync("/etc/hosts").toString(); file.split("\n").forEach(function (s) { use s }); | while ($line = <$f>) { print $line; } | while (!feof($f)) { $line = fgets($f); echo $line; } | import scala.io.Source val src = Source.fromFile("/etc/passwd") for (line <- src.getLines) print(line) | readAndPrintLines h = do eof <- hIsEOF h if eof then return () else do line <- hGetLine h putStrLn line readAndPrintLines h main = do h <- openFile "/etc/passwd" ReadMode readAndPrintLines h | for s in f:lines() do use s end | |||||
read file into string | s = f.read() | s = f.read | $s = do { local $/; <$f> }; | $s = file_get_contents( "/etc/hosts"); | readFile "/etc/hosts" f <- openFile "/etc/hosts" ReadMode hGetContents f | ||||||||
read file into array of strings | a = f.readlines() | a = f.lines.to_a | @a = <$f>; | $a = file("/etc/hosts"); | |||||||||
write to file | fs.writeSync(f, "lorem ipsum"); | #include <fstream> ofstream f("/tmp/test4"); int i; for (i = 0; i < 10; ++i) { f << i << endl; } f.close(); if (0 != f.fail()) { handle error } | import java.io.BufferedWriter; import java.io.FileWriter; BufferedWriter fout = new BufferedWriter(new FileWriter("/tmp/test2")); int i; for (i=0; i<10; i++) { fout.write(String.format("%d", i)); fout.newLine(); } fout.close(); | f:write("lorem ipsum") | |||||||||
write string | f.write('lorem ipsum') | f.write("lorem ipsum") | print $f "lorem ipsum"; | fwrite($f, "lorem ipsum"); | hPutStr f "hello world" | ||||||||
write line | f.write('lorem ipsum\n') | f.puts("lorem ipsum") | print $f "lorem ipsum\n"; | fwrite($f, "lorem ipsum"); | val out = new java.io.FileWriter("/tmp/test-scala") out.write("hello out\n") out.close | open Printf let oc = open_out "/tmp/test-ocaml" in fprintf oc "hello out\n"; close_out oc;; | s = "hello out\n" f = "/tmp/test-haskell" main = writeFile f s | ||||||
flush file handle | f.flush() | f.flush | none | use IO::Handle; $f->flush(); | CLI output isn't buffered fflush($f); | hFlush f | f:flush() | ||||||
close file | f.close() | f.close | fs.closeSync(f); | close $f or die; | fclose($f); | import scala.io.Source f.close | import System.IO hClose f | f:close() | |||||
close file implicitly | with open('/tmp/test', 'w') as f: f.write('lorem ipsum\n') | File.open("/tmp/test", "w") do |f| f.puts("lorem ipsum") end | { open(my $f, ">/tmp/test") or die; print $f "lorem ipsum\n"; } | none | |||||||||
end-of-file test | (?) | f.eof? | eof($f) | feof($f) | |||||||||
end-of-file behavior | returns string without newline or '' | returns non-empty string without newline or raises EOFError | returns string without newline or undef | returns string without newline or FALSE | raises End_of_file | when last data is returned, hIsEOF will return True. Reading after end-of-file throws an exception. | |||||||
i/o error | raise IOError exception | raise IOError or subclass of SystemCallError exception | return false value | return false value and write warning to stderr | |||||||||
i/o errors | |||||||||||||
encoding error | raise UnicodeDecodeError on read; raise UnicodeEncodeError on write | emit warning and replace bad byte with 4 character \xHH sequence | |||||||||||
get and set file handle position | f.tell() f.seek(0) | f.tell f.seek(0) f.pos f.pos = 0 | tell($f) seek($f, 0, SEEK_SET); | ftell($f) fseek($f, 0); | |||||||||
temporary file | import tempfile f = tempfile.NamedTemporaryFile() f.write('lorem ipsum\n') print("tmp file: %s" % f.name) f.close() file is removed when file handle is closed | require 'tempfile' f = Tempfile.new('') f.puts "lorem ipsum" puts "tmp file: #{f.path}" (file is removed when file handle is garbage-collected or interpreter exits) | use File::Temp; $f = File::Temp->new(); print $f "lorem ipsum\n"; print "tmp file: "; print $f->filename . "\n"; close $f or die; file is removed when file handle goes out of scope | $f = tmpfile(); fwrite($f, "lorem ipsum\n"); (no way to get file name) fclose($f); file is removed when file handle is closed | f = io.tmpfile() f:write("lorem ipsum\n") f:close() ?? | ||||||||
in memory file | from StringIO import StringIO f = StringIO() f.write('lorem ipsum\n') s = f.getvalue() (Python 3 moved StringIO to the io module) | require 'stringio' f = StringIO.new f.puts("lorem ipsum") f.rewind s = f.read | my ($f, $s); open($f, ">", \$s); print $f "lorem ipsum\n"; $s; | $meg = 1024 * 1024; $mem = "php://temp/maxmemory:$meg"; $f = fopen($mem, "r+"); fputs($f, "lorem ipsum"); rewind($f); $s = fread($f, $meg); | |||||||||
files | |||||||||||||
python | ruby | javascript | coffeescript | perl | php | cpp | d | java | scala | ocaml | haskell | lua | |
file exists test, file regular test | os.path.exists('/etc/hosts') os.path.isfile('/etc/hosts') | File.exists?("/etc/hosts") File.file?("/etc/hosts") | var path = require('path'); path.existsSync("/etc/hosts"); | -e "/etc/hosts" -f "/etc/hosts" | file_exists("/etc/hosts") is_file("/etc/hosts") | import java.io.File; File f = new File("/etc/hosts"); f.exists() f.isFile() | open Unix try Some (stat "/etc/hosts") with Unix_error (ENOENT, _, _) -> None (stat "/etc/hosts").st_kind = S_REG | import System Directory.doesFileExist "/etc/hosts" import Control.Monad import System.Posix.Files liftM isRegularFile (getFileStatus "/etc/hosts") | none | ||||
file size | os.path.getsize('/etc/hosts') | File.size("/etc/hosts") | -s "/etc/hosts" | filesize("/etc/hosts") | import java.io.File; File f = new File("/etc/hosts"); f.length() | (stat "/etc/hosts").st_size | import Control.Monad import System.Posix.Files liftM fileSize (getFileStatus "/etc/hosts") | ||||||
is file readable, writable, executable | os.access('/etc/hosts', os.R_OK) os.access('/etc/hosts', os.W_OK) os.access('/etc/hosts', os.X_OK) | File.readable?("/etc/hosts") File.writable?("/etc/hosts") File.executable?("/etc/hosts") | -r "/etc/hosts" -w "/etc/hosts" -x "/etc/hosts" | is_readable("/etc/hosts") is_writable("/etc/hosts") is_executable("/etc/hosts") | import java.io.File; File f = new File("/etc/hosts"); f.canRead() f.canWrite() f.canExecute() | open Unix try access "/tmp/bar" [R_OK]; true with Unix.Unix_error (EACCES, _, _) -> false;; try access "/tmp/bar" [W_OK]; true with Unix.Unix_error (EACCES, _, _) -> false;; try access "/tmp/bar" [X_OK]; true with Unix.Unix_error (EACCES, _, _) -> false;; | import Control.Monad liftM readable (getPermissions "/etc/hosts") liftM writable (getPermissions "/etc/hosts") liftM executable (getPermissions "/etc/hosts") | ||||||
set file permissions | os.chmod('/tmp/foo', 0755) | File.chmod(0755, "/tmp/foo") | var fs = require('fs'); fs.chmod("/tmp/foo", 0755); | chmod 0755, "/tmp/foo"; | chmod("/tmp/foo", 0755); | import java.io.File; File f = new File("/tmp/foo"); (sets owner perms; to turn perms off set arg to false:) f.setReadable(true); f.setWritable(true); f.setExecutable(true); (if 2nd arg is false, perms are for owner, group, and other:) f.setReadable(true, false); f.setWritable(true, false); f.setExecutable(true, false); | open Unix chmod "/tmp/foo" 0o755 | import System.Posix.Files setFileMode "/tmp/foo" ownerModes setFileMode "/tmp/foo" groupReadMode setFileMode "/tmp/foo" groupExecuteMode setFileMode "/tmp/foo" otherReadMode setFileMode "/tmp/foo" otherExecuteMode | none | ||||
copy file, remove file, rename file | import shutil shutil.copy('/tmp/foo', '/tmp/bar') os.remove('/tmp/foo') shutil.move('/tmp/bar', '/tmp/foo') | require 'fileutils' FileUtils.cp("/tmp/foo", "/tmp/bar") FileUtils.rm("/tmp/foo") FileUtils.mv("/tmp/bar", "/tmp/foo") | var fs = require('fs'); ?? fs.unlink("/tmp/foo"); fs.rename("/tmp/bar", "/tmp/foo"); | use File::Copy; copy("/tmp/foo", "/tmp/bar"); unlink "/tmp/foo"; move("/tmp/bar", "/tmp/foo"); | copy("/tmp/foo", "/tmp/bar"); unlink("/tmp/foo"); rename("/tmp/bar", "/tmp/foo"); | import java.io.File; ?? File f2 = new File("/tmp/foo"); f2.delete(); File f3 = new File("/tmp/bar"); f3.renameTo(new File("/tmp/bar")); | open Unix ?? unlink "/tmp/foo" rename "/tmp/bar" "/tmp/foo" | import System.Directory copyFile "/tmp/foo" "/tmp/bar" removeFile "/tmp/foo" renameFile "/tmp/bar" "/tmp/foo" | none | ||||
create symlink, symlink test, readlink | os.symlink('/etc/hosts', '/tmp/hosts') os.path.islink('/tmp/hosts') os.path.realpath('/tmp/hosts') | File.symlink("/etc/hosts", "/tmp/hosts") File.symlink?("/etc/hosts") File.realpath("/tmp/hosts") | symlink "/etc/hosts", "/tmp/hosts"; -l "/etc/hosts" readlink "/tmp/hosts" | symlink("/etc/hosts", "/tmp/hosts"); is_link("/etc/hosts") readlink("/tmp/hosts") | open Unix symlink "/etc/hosts" "/tmp/hosts" (lstat "/tmp/hosts").st_kind = S_LNK readlink "/tmp/hosts" | import System.Posix.Files createSymbolicLink "/etc/hosts" "/tmp/hosts" ?? readSymbolicLink "/tmp/hosts" | |||||||
generate unused file name | import tempfile f, path = tempfile.mkstemp( prefix='foo', dir='/tmp') | use File::Temp; $f = File::Temp->new(DIR=>"/tmp", TEMPLATE=>"fooXXXXX", CLEANUP=>0); $path = $f->filename; | $path = tempnam("/tmp", "foo"); $f = fopen($path, "w"); | open Filename (* prefix and suffix: *) temp_file "foo" ".txt" | |||||||||
last modification time | from datetime import datetime as dt (unix epoch:) t = os.stat('/etc/passwd').st_mtime (datetime object:) t2 = dt.fromtimestamp(t) | (Time object:) t2 = File.stat('/etc/passwd').mtime (unix epoch:) t = t2.to_i | my @data = stat('/etc/passwd'); # unix epoch: my $t = $data['mtime']; | (unix epoch:) $t = stat('/etc/passwd')['mtime']; (DateTime object:) $t2 = new DateTime('UTC'); $t2->setTimestamp($t); | |||||||||
file formats | |||||||||||||
python | ruby | javascript | coffeescript | perl | php | cpp | d | java | scala | ocaml | haskell | lua | |
csv | |||||||||||||
parse csv | import csv with open('foo.csv') as f: cr = csv.reader(f) for row in cr: print('\t'.join(row)) | require 'csv' CSV.foreach("foo.csv") do |row| puts row.join("\t") end | # cpan -i Text::CSV use Text::CSV; my $csv = Text::CSV->new or die; open my $f, $ARGV[0] or die; while (my $row = $csv->getline($f)) { print join("\t", @$row) . "\n"; } | $f = fopen("no-header.csv", "r"); while (($row = fgetcsv($f)) != FALSE) { echo implode("\t", $row) . "\n"; } | |||||||||
generate csv | import csv with open('foo.csv', 'w') as f: cw = csv.writer(f) cw.writerow(['one', 'une', 'uno']) cw.writerow(['two', 'deux', 'dos']) | require 'csv' CSV.open("foo.csv", "w") do |csv| csv << ["one", "une", "uno"] csv << ["two", "deux", "dos"] end | # cpan -i Text::CSV use Text::CSV; my $csv = Text::CSV->new or die; $csv->eol ("\r\n"); open my $f, ">foo.csv" or die; $csv->print($f, ["one", "une", "uno"]); $csv->print($f, ["two", "deux", "dos"]); $f->close or die; | ||||||||||
generate xml | import xml.etree.ElementTree as ET builder = ET.TreeBuilder() builder.start('a', {}) builder.start('b', {'id': '123'}) builder.data('foo') builder.end('b') builder.end('a') et = builder.close() (<a><b id="123">foo</b></a>:) print(ET.tostring(et)) | # gem install builder require 'builder' builder = Builder::XmlMarkup.new xml = builder.a do |child| child.b("foo", :id=>"123") end (<a><b id="123">foo</b></a>:) puts xml | # cpan -i XML::Writer use XML::Writer; my $writer = XML::Writer->new( OUTPUT => STDOUT); $writer->startTag("a"); $writer->startTag("b", id => "123"); $writer->characters("foo"); $writer->endTag("b"); $writer->endTag("a"); # <a><b id="123">foo</b></a>: $writer->end; | $xml = "<a></a>"; $sxe = new SimpleXMLElement($xml); $b = $sxe->addChild("b", "foo"); $b->addAttribute("id", "123"); (<a><b id="123">foo</b></a>:) echo $sxe->asXML(); | |||||||||
parse html | # pip install beautifulsoup4 import bs4 html = open('foo.html').read() doc = bs4.BeautifulSoup(html) for link in doc.find_all('a'): print(link.get('href')) | # gem install nokogiri require 'nokogiri' html = File.open("foo.html").read doc = Nokogiri::HTML(html) doc = doc.xpath("//a").each do |link| puts link["href"] end | # cpan -i Mojo::DOM use Mojo::DOM; | $html = file_get_contents("foo.html"); $doc = new DOMDocument; $doc->loadHTML($html); $xpath = new DOMXPath($doc); $nodes = $xpath->query("//a/@href"); foreach($nodes as $href) { echo $href->nodeValue; } | |||||||||
json | |||||||||||||
json generate/parse | import json s = json.dumps({'t': 1, 'f': 0}) d = json.loads(s) | require 'json' s = {'t' => 1,'f' => 0}.to_json d = JSON.parse(s) | # cpan -i JSON use JSON; $raw = {t => 1, f => 0}; $json = JSON->new->allow_nonref; $s = $json->encode($raw); $d = $json->decode($s); | $a = array("t" => 1, "f" => 0); $s = json_encode($a); $d = json_decode($s, TRUE); | |||||||||
build xml | |||||||||||||
parse xml | |||||||||||||
parse xml / all nodes matching xpath query; first node matching xpath query | from xml.etree import ElementTree xml = '<a><b><c ref="3">foo</c></b></a>' raises xml.etree.ElementTree.ParseError (if not well-formed:) doc = ElementTree.fromstring(xml) nodes = doc.findall('b/c') print(len(nodes)) print(nodes[0].text) node = doc.find('b/c') print(node.text) print(node.attrib['ref']) | require 'rexml/document' include REXML xml = "<a><b><c ref='3'>foo</c></b></a>" raises REXML::ParseException if not well-formed: doc = Document.new(xml) nodes = XPath.match(doc,"/a/b/c") puts nodes.size puts nodes[0].text node = XPath.first(doc,"/a/b/c") puts node.text puts node.attributes["ref"] | # cpan -i XML::XPath use XML::XPath; my $xml = "<a><b><c>foo</c></b></a>"; # fatal error if XML not well-formed my $doc = XML::XPath->new(xml => $xml); my $nodes = $doc->find("/a/b/c"); print $nodes->size . "\n"; $node = $nodes->get_node(0); print $node->string_value . "\n"; print $node->getAttribute("ref") . "\n"; | $xml = "<a><b><c ref='3'>foo</c></b></a>"; (returns NULL and emits warning if not well-formed:) $doc = simplexml_load_string($xml); $nodes = $doc->xpath("/a/b/c"); echo count($nodes); echo $nodes[0]; $node = $nodes[0]; echo $node; echo $node["ref"]; | |||||||||
parse html | # pip install beautifulsoup4 import bs4 html = open('foo.html').read() doc = bs4.BeautifulSoup(html) for link in doc.find_all('a'): print(link.get('href')) | # gem install nokogiri require 'nokogiri' html = File.open("foo.html").read doc = Nokogiri::HTML(html) doc = doc.xpath("//a").each do |link| puts link["href"] end | # cpan -i Mojo::DOM use Mojo::DOM; | $html = file_get_contents("foo.html"); $doc = new DOMDocument; $doc->loadHTML($html); $xpath = new DOMXPath($doc); $nodes = $xpath->query("//a/@href"); foreach($nodes as $href) { echo $href->nodeValue; } | |||||||||
directories | |||||||||||||
python | ruby | javascript | coffeescript | perl | php | cpp | d | java | scala | ocaml | haskell | lua | |
working directory | old_dir = os.path.abspath('.') os.chdir('/tmp') | old_dir = Dir.pwd Dir.chdir("/tmp") | use Cwd; my $old_dir = cwd(); chdir("/tmp"); | $old_dir = getcwd(); chdir("/tmp"); | |||||||||
build pathname | os.path.join('/etc', 'hosts') | File.join("/etc", "hosts") | var path = require('path'); path.join("/etc", "hosts"); | use File::Spec; File::Spec->catfile("/etc", "hosts") | "/etc" . DIRECTORY_SEPARATOR . "hosts" | import java.io.File; File root = File.listRoots()[0]; File etc = new File(root, "etc"); File hosts = newFile(etc, "hosts"); String path = hosts.getPath(); | open Filename concat "/etc" "hosts" | import System.FilePath ((</>)) let path = "/etc" </> "hosts" | |||||
dirname and basename | os.path.dirname('/etc/hosts') os.path.basename('/etc/hosts') | File.dirname("/etc/hosts") File.basename("/etc/hosts") | var path = require('path'); path.dirname("/etc/hosts"); path.basename("/etc/hosts"); | use File::Basename; print dirname("/etc/hosts"); print basename("/etc/hosts"); | dirname("/etc/hosts") basename("/etc/hosts") | #include <libgen.h> string s1 = dirname("/etc/hosts"); string s2 = basename("/etc/hosts"); | import java.io.File; File f = new File("/etc/hosts"); String dirname = f.getParent(); String basename = f.getName(); | open Filename dirname "/etc/hosts" basename "/etc/hosts" | import System.FilePath takeFileName "/etc/hosts" takeDirectory "/etc/hosts" | ||||
absolute pathname | #include <climits> #include <cstdlib> char buf[PATH_MAX]; if (realpath("..", buf) == NULL) { throw exception(); } else { string path(buf); } | import java.io.File; File f = new File("foo"); String abspath = f.getAbsolutePath(); (getCanonicalPath() expands .. and .:) File f2 = new File("../foo"); String abspath2 = f2.getCanonicalPath(); File f3 = new File("./foo"); String abspath3 = f3.getCanonicalPath(); | |||||||||||
absolute pathname / and tilde expansion | (symbolic links are not resolved:) os.path.abspath('foo') os.path.abspath('/foo') os.path.abspath('../foo') os.path.abspath('./foo') os.path.expanduser('~/foo') | # symbolic links are not resolved: File.expand_path("foo") File.expand_path("/foo") File.expand_path("../foo") File.expand_path("./foo") File.expand_path("~/foo") | use Cwd; # symbolic links are resolved: Cwd::abs_path("foo") Cwd::abs_path("/foo") Cwd::abs_path("../foo") Cwd::abs_path(".") # no function for tilde expansion | (file must exist; symbolic links are resolved:) realpath("foo") realpath("/foo") realpath("../foo") realpath("./foo") (no function for tilde expansion) | |||||||||
iterate over directory by file | for filename in os.listdir('/etc'): print(filename) | Dir.open("/etc").each do |file| puts file end | var fs = require('fs'); var sys = require('sys'); var a = fs.readdirSync("/etc"); for (var i=0; i<a.length; i++) { sys.puts(a[i]); } | opendir(my $dh, $ARGV[0]); while (my $file = readdir($dh)) { print $file . "\n"; } closedir($dh); | if ($dir = opendir("/etc")) { while ($file = readdir($dir)) { echo "$file\n"; } closedir($dir); } | import java.io.File; File dir = new File("/etc"); (iterate over names:) for (String name: dir.list()) { System.out.println(name); } (iterate over file objects:) for (File f: dir.listFiles()) { System.out.println(f.getName()); } | import System (returns IO [FilePath]) Directory.getDirectoryContents "/etc" | ||||||
glob paths | import glob for path in glob.glob('/etc/*'): print(path) | Dir.glob("/etc/*").each do |path| puts path end | while ( </etc/*> ) { print $_ . "\n"; } | foreach (glob("/etc/*") as $file) { echo "$file\n"; } | |||||||||
make directory | dirname = '/tmp/foo/bar' if not os.path.isdir(dirname): os.makedirs(dirname) | require 'fileutils' FileUtils.mkdir_p("/tmp/foo/bar") | var fs = require('fs'); fs.mkdirSync("/tmp/foo", 0755); fs.mkdirSync("/tmp/foo/bar", 0755); | use File::Path 'make_path'; make_path "/tmp/foo/bar"; | mkdir("/tmp/foo/bar", 0755, TRUE); | import java.io.File; File f = new File("/tmp/foo/bar"); f.mkdirs(); | (* opam install fileutils *) open FileUtil mkdir ~parent:true "/tmp/foo/bar" | import System.Directory createDirectoryIfMissing True "/tmp/foo/bar" | |||||
recursive copy | import shutil shutil.copytree('/tmp/foodir', '/tmp/bardir') | require 'fileutils' FileUtils.cp_r("/tmp/foodir", "/tmp/bardir") | # cpan -i File::Copy::Recursive use File::Copy::Recursive 'dircopy'; dircopy "/tmp/foodir", "/tmp/bardir"; | none | |||||||||
remove empty directory | os.rmdir('/tmp/foodir') | File.rmdir("/tmp/foodir") | var fs = require('fs'); fs.rmdirSync("/tmp/foo/bar"); | rmdir "/tmp/foodir"; | rmdir("/tmp/foodir"); | open Unix rmdir "/tmp/foodir" | import System.Directory removeDirectory "/tmp/foodir" | ||||||
remove directory and contents | import shutil shutil.rmtree('/tmp/foodir') | require 'fileutils' FileUtils.rm_rf("/tmp/foodir") | use File::Path 'remove_tree'; remove_tree "/tmp/foodir"; | none | import System.Directory removeDirectoryRecursive "/tmp/foodir" | ||||||||
directory test | os.path.isdir('/tmp') | File.directory?("/tmp") | -d "/tmp" | is_dir("/tmp") | import java.io.File; File f = new File("/tmp"); f.isDirectory() | import System Directory.doesDirectoryExist "/tmp" | |||||||
generate unused directory | import tempfile path = tempfile.mkdtemp(dir='/tmp', prefix='foo') | require 'tmpdir' path = Dir.mktmpdir("/tmp/foo") | use File::Temp qw(tempdir); $path = tempdir(DIR=>"/tmp", CLEANUP=>0); | ||||||||||
generate unused directory name | |||||||||||||
system temporary file directory | import tempfile tempfile.gettempdir() | require 'tmpdir' Dir.tmpdir | use File::Spec; File::Spec->tmpdir | sys_get_temp_dir() | |||||||||
processes and environment | |||||||||||||
python | ruby | javascript | coffeescript | perl | php | cpp | d | java | scala | ocaml | haskell | lua | |
exit | sys.exit(0) | exit(0) | process.exit(0) | exit 0; | exit(0); | exit 0 exit 1 | import System.Exit exitWith ExitSuccess (to return nonzero status:) exitWith (ExitFailure 1) | os.exit(0) | |||||
program name | import System s <- getProgName | ||||||||||||
command line arguments | process.argv.length process.argv[0] process.argv[1] … | object Test { def main(args: Array[String]) { for (arg <- args) println(arg) } } | for i = 0 to Array.length Sys.argv - 1 do print_endline i Sys.argv.(i) done | import System printArgs args = do if length args == 0 then return () else do putStrLn (head args) printArgs (tail args) main = do a <- getArgs printArgs a | # arg arg[0] arg[1] … | ||||||||
command line arguments / and script name | sys.argv[1:] sys.argv[0] | ARGV $0 | @ARGV $0 | $argv $_SERVER["SCRIPT_NAME"] | |||||||||
signature of main | int main(int argc, char** argv) { | public class Foo { public static void main(String[] args) { | |||||||||||
first argument | pathname of executable | first command line argument | |||||||||||
getopt | |||||||||||||
get and set environment variable | os.getenv('HOME') os.environ['PATH'] = '/bin' | ENV["HOME"] ENV["PATH"] = "/bin" | $ENV{"HOME"} $ENV{"PATH") = "/bin"; | getenv("HOME") putenv("PATH=/bin"); | open Unix s = getenv "HOME" putenv "PATH" "/bin" | import System.Posix.Env s <- getEnv "HOME" putEnv "PATH=/bin" | |||||||
get pid, parent pid | os.getpid() os.getppid() | Process.pid Process.ppid | $$ getppid | posix_getpid() posix_getppid() | open Unix let pid = getpid() let ppid = getppid() | import System.Posix.Process pid <- getProcessID ppid <- getParentProcessID | |||||||
get user id and name | import getpass os.getuid() getpass.getuser() | require 'etc' Process.uid Etc.getpwuid(Process.uid)["name"] | $< getpwuid($<) | $uid = posix_getuid(); $uinfo = posix_getpwuid($uid); $username = $uinfo["name"]; | let uid = getuid() let username = (getpwuid (getuid())).pw_name | import System.Posix.User uid <- getRealUserID username <- getLoginName | |||||||
environment variable | #include <stdlib.h> char* home = getenv("HOME"); setenv("EDITOR", "emacs", 1); unsetenv("EDITOR"); | String home = System.getenv("HOME"); | os.getenv("HOME") | ||||||||||
iterate through environment variables | import java.util.Map; Map<String, String> env = System.getenv(); for (String name : env.keySet()) { String value = env.get(name)); } | ||||||||||||
exit | sys.exit(0) | exit(0) | process.exit(0) | exit 0; | exit(0); | exit 0 exit 1 | import System.Exit exitWith ExitSuccess (to return nonzero status:) exitWith (ExitFailure 1) | os.exit(0) | |||||
set signal handler | import signal def handler(signo, frame): print('exiting...') sys.exit(1) signal.signal(signal.SIGINT, handler) | Signal.trap("INT", lambda do |signo| puts "exiting..." exit 1 end ) | $SIG{INT} = sub { die "exiting...\n"; }; | ||||||||||
executable test | os.access('/bin/ls', os.X_OK) | File.executable?("/bin/ls") | -x "/bin/ls" | is_executable("/bin/ls") | |||||||||
external command | if os.system('ls -l /tmp'): raise Exception('ls failed') | unless system("ls -l /tmp") raise "ls failed" end | var exec = require('child_process').exec; var child = exec('ls'); | system("ls -l /tmp") == 0 or die "ls failed"; | system("ls -l /tmp", $retval); if ($retval) { throw new Exception("ls failed"); } | import System.Cmd rawSystem "ls" ["-l", "/tmp"] | os.execute("ls") | ||||||
escaped external command | import subprocess cmd = ['ls', '-l', '/tmp'] if subprocess.call(cmd): raise Exception('ls failed') | path = gets path.chomp! unless system("ls", "-l", path) raise "ls failed" end | $path = <>; chomp($path); system("ls", "-l", $path) == 0 or die "ls failed"; | $path = chop(fgets(STDIN)); $safe = escapeshellarg($path); system("ls -l " . $safe, $retval); if ($retval) { throw new Exception("ls failed"); } | |||||||||
backticks | import subprocess cmd = ['ls', '-l', '/tmp'] files = subprocess.check_output(cmd) | files = `ls -l /tmp` unless $?.success? raise "ls failed" end files = %x(ls) unless $?.success? raise "ls failed" end | var exec = require('child_process').exec; var f = function(err, fout, ferr) { output in fout }; var child = exec('ls', f); | my $files = `ls -l /tmp`; or my $files = qx(ls); | $files = `ls -l /tmp`; | f = io.popen("ls") s = f:read("*a") | |||||||
option parsing | |||||||||||||
python | ruby | javascript | coffeescript | perl | php | cpp | d | java | scala | ocaml | haskell | lua | |
command line options / boolean option, option with argument, usage | import argparse parser = argparse.ArgumentParser() parser.add_argument('positional_args', nargs='*', metavar='ARG') parser.add_argument('--file', '-f', dest='file') parser.add_argument('--verbose', '-v', dest='verbose', action='store_true') args = parser.parse_args() the_file = args.file verbose = args.verbose (The flags -h and --help and the usage message are generated automatically. Positional arguments are in args.positional_args. Options can follow positional arguments.) | require 'optparse' options = {} OptionParser.new do |opts| opts.banner = "usage: #{$0} [OPTIONS] [ARG ...]" opts.on("-f", "--file FILE") do |arg| options[:file] = arg end opts.on("-v", "--verbose") do |arg| options[:verbose] = arg end end.parse! file = options[:file] verbose = options[:verbose] (The flags -h and --help and the usage message are generated automatically. After calling OptionParser.parse! only positional arguments are in ARGV. Options can follow positional args.) | use Getopt::Long; my ($file, $help, $verbose); my $usage = "usage: $0 [-f FILE] [-v] [ARG ...]\n"; if (!GetOptions("file=s" => \$file, "help" => \$help, "verbose" => \$verbose)) { print $usage; exit 1; } if ($help) { print $usage; exit 0; } (After call to GetOptions() only, positional arguments are in @ARGV. Options can follow positional arguments. Long options can be preceded by one or two hyphens. Single letters can be used if only one long option begins with that letter. Single letter options cannot be bundled after a single hyphen. Single letter options must be separated from an argument by a space or =.) | $usage = "usage: " . $_SERVER["SCRIPT_NAME"] . " [-f FILE] [-v] [ARG ...]\n"; $opts = getopt("f:hv", array("file:", "help", "verbose")); if (array_key_exists("h", $opts) || array_key_exists("help", $opts)) { echo $usage; exit(0); } $file = $opts["f"] ? $opts["f"] : $opts["file"]; if (array_key_exists("v", $opts) || array_key_exists("verbose", $opts)) { $verbose = TRUE; } (Processing stops at first positional argument. Unrecognized options are ignored. An option declared to have an argument is ignored if the argument is not provided on the command line. getopt() does not modify $argv or provide means to identify positional arguments.) | |||||||||
libraries and namespaces | |||||||||||||
python | ruby | javascript | coffeescript | perl | php | cpp | d | java | scala | ocaml | haskell | lua | |
library | cat foo.js function add(x,y) { return x+y; } | $ cat foo.lua function add(x, y) return x+y end | |||||||||||
load library | (searches sys.path for foo.pyc or foo.py:) import foo | require 'foo.rb' (searches $LOAD_PATH for foo.rb, foo.so, foo.o, foo.dll:) require 'foo' | require 'Foo.pm'; # searches @INC for Foo.pm: require Foo; | require_once("foo.php"); | |||||||||
load library in subdirectory | (foo must contain __init__.py file) import foo.bar | require 'foo/bar.rb' require 'foo/bar' | require 'Foo/Bar.pm'; require Foo::Bar; | require_once('foo/bar.php'); | |||||||||
hot patch | reload(foo) | load 'foo.rb' | do 'Foo.pm'; | require("foo.php"); | |||||||||
load error | raises ImportError if library not found; exceptions generated when parsing library propagate to client | raises LoadError if library not found; exceptions generated when parsing library propagate to client | fatal error if library not found or if last expression in library does not evaluate as true; fatal error parsing library propagates to client | require and require_once raise fatal error if library not found; include and include_once emit warnings | |||||||||
standard library name | C++ Standard Library | Java API | |||||||||||
main routine in library | if __name__ == '__main__': (code) | if $0 == __FILE__ (code) end | unless (caller) { (code) } | none | |||||||||
library path | sys.path sys.path.append('/some/path') | ($: is synonym for $LOAD_PATH:) $LOAD_PATH $LOAD_PATH << "/some/path" | (node.js, not available in repl:) require.paths | @INC push @INC, "/some/path"; | $libpath = ini_get("include_path"); ini_set("include_path", $libpath . ":/some/path"); | package.path | |||||||
library path environment variable | PYTHONPATH=~/lib python foo.py | RUBYLIB=~/lib ruby foo.rb | PERL5LIB=~/lib perl foo.pl | none | LUA_PATH | ||||||||
library path command line option | ruby -I ~/lib foo.rb | perl -I ~/lib foo.pl | none | ||||||||||
declare namespace | put declarations in foo.py | class Foo (class definition) end module Foo (module definition) end | package Foo; require Exporter; our @ISA = ("Exporter"); our @EXPORT_OK = qw(bar baz); | namespace Foo; | namespace foo { namespace bar { class Baz { static const int ANSWER = 42; }; } } | package foo.bar; public class Baz { public static final int ANSWER = 42; } | module | ||||||
simple global identifiers | built-in functions | variables which start with $ | variables defined outside of functions or with global keyword | ||||||||||
multiple label identifiers | modules | constants, classes, and modules | all identifiers not declared with my | classes, interfaces, functions, and constants | |||||||||
label separator | foo.bar.baz() | Foo::Bar.baz | Foo::Bar::baz(); | \Foo\Bar\baz(); | |||||||||
root namespace definition | (outside of class or module; only constants in root namespace:) FOO = 3 (inside class or module:) ::FOO = 3 | (outside of package or in package main:) our $foo = 3; (inside package:) our $::foo = 3; our $main::foo = 3; | \foo | ||||||||||
namespace declaration | put declarations in foo.py | class Foo (class definition) end module Foo (module definition) end | package Foo; require Exporter; our @ISA = ("Exporter"); our @EXPORT_OK = qw(bar baz); | namespace Foo; | namespace foo { namespace bar { class Baz { static const int ANSWER = 42; }; } } | package foo.bar; public class Baz { public static final int ANSWER = 42; } | module | ||||||
child namespace declaration | foo must be in sys.path: mkdir foo touch foo/__init__.py touch foo/bar.py | module Foo::Bar (module definitions) end module Foo module Bar (module definitions) end end (classes can nest inside classes or modules; modules can nest in classes) | package Foo::Bar; | namespace Foo\Bar; | |||||||||
namespace alias | import foo as fu | Fu = Foo.dup include Fu | use Foo as Fu; | module Gr = Graphics;; | import qualified Data.Bytestring as B | ||||||||
unqualified import of namespace | from foo import * | # inside class or module: include Foo | (imports symbols in @EXPORT:) use Foo; | none, but a long module name can be shortened | |||||||||
unqualified import of all subnamespaces | (subnamespaces in list __all__ of foo/__init__.py are imported) from foo import * | ||||||||||||
unqualified import of definitions | from foo import bar, baz | (none) | (bar and baz must be in @EXPORT or @EXPORT_OK:) use Foo qw(bar baz); | only class names can be imported | |||||||||
list installed packages, install a package | pip freeze pip install jinja2 | gem list gem install rails | perldoc perllocal cpan -i Moose | $ pear list $ pear install Math_BigInteger | |||||||||
package specification format | (in setup.py:) #!/usr/bin/env python from distutils.core import setup setup( name='foo', author='Joe Foo', version='1.0', description='a package', py_modules=['foo']) | (in foo.gemspec:) spec = Gem::Specification.new do |s| s.name = "foo" s.authors = "Joe Foo" s.version = "1.0" s.summary = "a gem" s.files = Dir["lib/*.rb"] end | |||||||||||
namespace example | (Baz.scala) package Foo.Bar; class Baz { def say() { println("hello"); } } (Main.scala) import Foo.Bar.Baz; object Main { def main(args : Array[String]) { val baz = new Baz; baz.say(); } } to compile and run scalac Baz.scala scalac Main.scala scala Main hello | (Foo/Bar.hs) module Foo.Bar where data Baz = Baz say Baz = putStrLn "hello" (Main.hs) module Main where import Foo.Bar baz = Baz main = say baz (to compile and run) ghc -c Foo/Bar.hs ghc Main.hs ./Main hello | |||||||||||
namespaces | values, constructors, type variables, type constructors, type classes, modules | ||||||||||||
file name restrictions | (none) | module Foo.Bar must be in Foo.ml | module Foo.Bar must be in Foo/Bar.hs | ||||||||||
namespace | open Graphics;; | import Data.Bytestring | |||||||||||
namespace creation | put code in file MODULE_NAME.ml | ||||||||||||
namespace alias | import foo as fu | Fu = Foo.dup include Fu | use Foo as Fu; | module Gr = Graphics;; | import qualified Data.Bytestring as B | ||||||||
namespace separator | . | . | . | ||||||||||
subnamespace | in A.ml: module B = sig val display_instruction : unit -> unit end = struct let msg = "attack" let display_instruction () = print_endline msg end in client source: A.B.display_instruction;; | ||||||||||||
namespace separator | . | . | . | ||||||||||
multiple namespaces per file | yes | no | |||||||||||
namespaces map to directories | no | yes | |||||||||||
import namespace | using namespace foo::bar; cout << Baz::ANSWER << endl; | import foo.bar.*; System.out.println(Baz.ANSWER); | |||||||||||
import library | <script src="foo.js"/> <script> alert(add(3,7)); </script> | require 'foo' add(3,7) | |||||||||||
import part of namespace | using namespace foo; cout << bar::Baz::ANSWER << endl; | none | |||||||||||
import symbol | using foo::bar::Baz; cout << Baz::ANSWER << endl; | import foo.bar.Baz; System.out.println(Baz.ANSWER); | |||||||||||
import static symbol | none | import static foo.bar.Baz.ANSWER; System.out.println(ANSWER); | |||||||||||
import position | anywhere a statement is legal | after package and before type definitions | |||||||||||
using a symbol that hasn't been imported | cout << foo::bar::Baz::ANSWER << endl; | System.out.println(foo.bar.Baz.ANSWER); | |||||||||||
application environment | |||||||||||||
multiple installations | set JAVA_HOME environment variable to directory containing a bin subdirectory with java, javac, and other command line tools. Put $JAVA_HOME/bin at front of search path. | ||||||||||||
package manager | |||||||||||||
package manager setup | do this once: $ opam init for each shell session: $ eval $(opam config env) | ||||||||||||
list installed packaged, install a package | npm ls npm install tmp | ||||||||||||
package manager / search; install; list installed | $ opam search utop $ opam install utop $ opam list --installed | cabal list parsec cabal install parsec cabal list --installed | |||||||||||
library path | sys.path sys.path.append('/some/path') | ($: is synonym for $LOAD_PATH:) $LOAD_PATH $LOAD_PATH << "/some/path" | (node.js, not available in repl:) require.paths | @INC push @INC, "/some/path"; | $libpath = ini_get("include_path"); ini_set("include_path", $libpath . ":/some/path"); | package.path | |||||||
library path environment variable | PYTHONPATH=~/lib python foo.py | RUBYLIB=~/lib ruby foo.rb | PERL5LIB=~/lib perl foo.pl | none | LUA_PATH | ||||||||
compile app using package | |||||||||||||
user-defined types | |||||||||||||
python | ruby | javascript | coffeescript | perl | php | cpp | d | java | scala | ocaml | haskell | lua | |
type synonym or typedef | typedef int customer_id; customer_id cid = 3; | alias customer_id = int; customer_id cid = 3; | none | type Name = String | type name = string;; | type Name = String | |||||||
sum type | abstract class Color case object Red extends Color case object Blue extends Color case object Green extends Color val col = Red (this won’t compile:) col < Green | type color = Red | Green | Blue;; let col = Red;; (* evaluates to true: *) col < Green;; | data Color = Red | Green | Blue deriving (Eq, Ord, Show) col = Red print col (Red) col < Green (True) | ||||||||||
tuple product type with one field | class SpecialInt(x: Int) val n = new SpecialInt(7) | type special_int = SpecialInt of int;; let n = SpecialInt 7;; | data SpecialIntType = SpecialInt Integer n = SpecialInt 7 newtype SpecialIntType = SpecialInt { runSpecialInt :: Integer } n = SpecialInt 7 | ||||||||||
tuple product type with two fields | class IntPair(a: Int, b: Int) val p = new IntPair(7, 11) | type int_pair = IntPair of int * int;; let p = IntPair (7, 11);; | data IntPairType = IntPair Integer Integer p = IntPair 7 11 | ||||||||||
enum | enum day_of_week { mon, tue, wed, thu, fri, sat, sun }; day_of_week d = tue; | enum DayOfWeek { Mon, Tue, Wed, Thu, Fri, Sat, Sun} DayOfWeek d = Tue; | public enum DayOfWeek { MON, TUE, WED, THU, FRI, SAT, SUN }; DayOfWeek d = DayOfWeek.TUE; | ||||||||||
struct definition | class MedalCount { public: const char *country; int gold; int silver; int bronze; }; | class MedalCount { string country; int gold; int silver; int bronze; } | public class MedalCount { public String country; public int gold; public int silver; public int bronze; } | ||||||||||
struct declaration | MedalCount spain; | MedalCount spain; | MedalCount spain = new MedalCount(); | ||||||||||
struct initialization | MedalCount spain = { "Spain", 3, 7, 4 }; | MedalCount spain = MedalCount("Spain", 3, 7, 4); | no object literal syntax; define a constructor | ||||||||||
struct member assignment | spain.country = "Spain"; spain.gold = 3; spain.silver = 7; spain.bronze = 4; | spain.country = "Spain"; spain.gold = 3; spain.silver = 7; spain.bronze = 4; | spain.country = "Spain"; spain.gold = 3; spain.silver = 7; spain.bronze = 4; | ||||||||||
struct member access | int spain_total = spain.gold + spain.silver + spain.bronze; | int spain_total = spain.gold + spain.silver + spain.bronze; | int spain_total = spain.gold + spain.silver + spain.bronze; | ||||||||||
record product type | case class Customer( id: Int, name: String, address: String ) | type customer = { id: int; name: string; address: string };; | data CustomerType = Customer { customerId :: Integer, name :: String, address :: String } | ||||||||||
record product type literal | Customer(7,"John","Topeka, KS") Customer(id=7, name="John", address="Topeka, KS") | let cust = { id=7; name="John"; address="Topeka, KS" };; | Customer { customerId=7, name="John", address="Topeka, KS" } | ||||||||||
recursive type | abstract class BinaryTree case class Tree(left: BinaryTree, right: BinaryTree) extends BinaryTree case class Leaf(x: Int) extends BinaryTree | type binary_tree = | Leaf of int | Tree of binary_tree * binary_tree;; | data BinaryTree = Leaf Integer | Tree BinaryTree BinaryTree | ||||||||||
pattern match sum type | val c:Color = Red; c match { case Red => "red"; case Green => "green"; case Blue => "blue" } | let col = Red;; let s = match col with | Red -> "red" | Blue -> "blue" | Green -> "green";; | c = Red case c of Red -> "red" Green -> "green" Blue -> "blue" | ||||||||||
pattern match product type | |||||||||||||
pattern match guard | match { case i: Int if i < 0 => - i; case i: Int => i } | match i with j when i < 0 -> -j | j -> j;; | none, use if or piecewise function definition | ||||||||||
pattern match catchall | val c : Color = Green c match { case Red => "red"; case _ => "not red" } | let to_s c = match c with Red -> "red" | _ -> "not red";; to_s Green;; | c = Green case c of Red -> "red"; _ -> "not red" | ||||||||||
generic types | |||||||||||||
python | ruby | javascript | coffeescript | perl | php | cpp | d | java | scala | ocaml | haskell | lua | |
generic type | class Twosome[A, B](a: A, b: B) val p = new Twosome("pi", 3.14) | type ('a, 'b) twosome = Twosome of 'a * 'b;; let p = Twosome ("pi", 3.14);; | data TwosomeType a b = Twosome a b p = Twosome ("pi", 3.14) | ||||||||||
define generic type | template <class A> class Foo { public: A a; Foo(A a); }; template <class A> Foo<A>::Foo(A a) : a(a) { } | public class Foo<A> { public A a; public Foo(A a) { this.a = a; } } | |||||||||||
instantiate generic type | Foo<string> f = Foo<string>("foo"); | Foo<String> f = new Foo<String>("foo"); | |||||||||||
generic function | template <class C> C add(C a, C b) { return a + b; } | ||||||||||||
generic array | template <class C> class Foo { public: C a[10]; }; | not permitted. Use Object as the element type for the array or use an ArrayList. | |||||||||||
value parameter | template <int N> int add(int i) { return N+i; } cout << add<7>(3) << endl; | ||||||||||||
template parameter | |||||||||||||
template specialization | |||||||||||||
multiple type parameters | template <class A, class B> class Pair { public: A a; B b; Pair(A a, B b); }; template <class A, class B> Pair<A, B>::Pair(A a, B b) : a(a), b(b) { } Pair<int, string> p = Pair<int, string>(7, "foo"); | ||||||||||||
generic type parameters | Pair<int, Foo<string> > p = Pair<int, Foo<string> >( 7, Foo<string>("foo")); | ||||||||||||
template parameters | |||||||||||||
variadic template | |||||||||||||
objects | |||||||||||||
python | ruby | javascript | coffeescript | perl | php | cpp | d | java | scala | ocaml | haskell | lua | |
semantics of == | value comparison | value comparison | object identity comparison | ||||||||||
define class | class Int(class): def __init__(self, v=0): self.value = v | class Int attr_accessor :value def initialize(i=0) @value = i end end | package Int; sub new { my $class = shift; my $v = $_[0] || 0; my $self = {value => $v}; bless $self, $class; $self; } sub value { my $self = shift; if ( @_ > 0 ) { $self->{'value'} = shift; } $self->{'value'}; } | class Int { public $value; function __construct($int=0) { $this->value = $int; } } | Rational.hpp: class Rational { public: int num, denom; Rational(int num, int denom); virtual ~Rational(); Rational operator+(Rational& addend); static Rational max(Rational& a, Rational& b); }; | public class Rational { public int num; public int denom; public Rational add(Rational o) throws Exception { return new Rational(this.num*o.denom + o.num*this.denom,this.denom*o.denom); } public static Rational max(Rational a, Rational b) { return (a.num*b.denom > a.num*b.denom) ? a : b; } } | class Counter { private var n = 0 def incr(): Unit = { n = n+1 } def get(): Int = { n } } | class counter = object val mutable n = 0 method incr = n <- n+1 method get = n end;; | |||||
class definition location | top level, class block, or function block | top level, class block, or function block for anonymous classes | |||||||||||
constructor | Rational::Rational(int n, int d) : num(n), denom(d) { if (denom == 0) { throw "zero denominator"; } int div = gcd(n,d); num = num / div; denom = denom / div; } | public Rational(int n, int d) throws Exception { if (d == 0) { throw new Exception("zero denominator"); } if ( d < 0 ) { this.num = -1 * n; this.denom = -1 * d; } else { this.num = n; this.denom = d; } } | |||||||||||
create object | i = Int() i2 = Int(7) | i = Int.new i2 = Int.new(7) | my $i = new Int(); # or my $i = Int->new(); | $i = new Int(); $i2 = new Int(7); | Rational r1(7, 3); Rational* r2 = new Rational(8, 5); | Rational r = new Rational(7,3); | val c = new Counter | let c = new counter;; | |||||
create blank object | var o = new Object(); or var o = {}; | o = {} | |||||||||||
instance variable visibility | public; attributes starting with underscore private by convention | private by default; use attr_reader, attr_writer, attr_accessor to make public | private; getters and setters must be explicitly defined | visibility must be declared | |||||||||
get and set instance variable | v = i.value i.value = v + 1 | v = i.value i.value = v + 1 | my $v = $i->value; $i->value($v + 1); | $v = $i->value; $i->value = $v + 1; | |||||||||
set attribute | o.score = 21; | o.score = 21 | |||||||||||
get attribute | if (o.score == 21) { alert("Blackjack!"); } | if o.score == 21 then print("Blackjack!") end | |||||||||||
destructor | def __del__(self): print('bye, %d' % self.value) | val = i.value ObjectSpace.define_finalizer(int) { puts "bye, #{val}" } | sub DESTROY { my $self = shift; my $v = $self->value; print "bye, $v\n"; } | function __destruct() { echo "bye, $this->value\n"; } | Rational::~Rational() {}; | protected void finalize() throws Throwable { super.finalize(); } | |||||||
destroy object | delete r2; | none | |||||||||||
define method | def plus(self,v): return self.value + v | def plus(i) value + i end | o.doubleScore = function() { return this.score * 2; }; | sub plus { my $self = shift; $self->value + $_[0]; } | function plus($i) { return $this->value + $i; } | int Rational::height() { return (abs(num) > abs(denom)) ? abs(num) : abs(denom); } | public int height() { return (Math.abs(this.num) > this.denom) ? Math.abs(this.num) : this.denom; } | function o.doubleScore(self) return 2 * self.score end | |||||
invoke method | i.plus(7) | i.plus(7) | alert("Answer: " + o.doubleScore()); | $i->plus(7) | $i->plus(7) | r1.height(); r2->height(); | r.height(); | c.incr c.get | c#incr;; c#get;; | print("Answer: " .. o:doubleScore()) | |||
define class method | @classmethod def get_instances(cls): return Counter.instances | declare static in class definition | declare static in class definition | ||||||||||
invoke class method | Counter.get_instances | Counter.instances | Counter->instances(); | Counter::getInstances() | |||||||||
define class variable | |||||||||||||
get and set class variable | |||||||||||||
handle undefined method invocation | def __getattr__(self, name): s = 'no def: ' + name + ' arity: %d' return lambda *a: print(s % len(a)) | def method_missing(name, *a) puts "no def: #{name}" + " arity: #{a.size}" end | our $AUTOLOAD; sub AUTOLOAD { my $self = shift; my $argc = scalar(@_); print "no def: $AUTOLOAD" . " arity: $argc\n"; } | function __call($name, $args) { $argc = count($args); echo "no def: $name " . "arity: $argc\n"; } | |||||||||
clone object | var o2 = Object.create(o); | ||||||||||||
object literal | var o = { score: 21, doubleScore: function() { return this.score * 2; } }; | o = { score=21, doubleScore=function(self) return 2*self.score end } | |||||||||||
name of receiver | this | this | |||||||||||
access control | access keywords define regions: class Foo { int privateInt1; int privateInt2; public: int publicInt1; int publicInt2; protected: int protectedInt1; int protectedInt2; private: int privateInt3; int privateInt4; }; | access keywords required for methods and members: public class Foo { private int privateInt; protected int protectedInt; public int publicInt; } | |||||||||||
anonymous class | possible but not useful | (new Object() { public void hello() { System.out.println("hello!"); } }).hello(); | |||||||||||
alias method | class Point attr_reader :x, :y, :color alias_method :colour, :color def initialize(x, y, color=:black) @x, @y = x, y @color = color end end | ||||||||||||
destructor | def __del__(self): print('bye, %d' % self.value) | val = i.value ObjectSpace.define_finalizer(int) { puts "bye, #{val}" } | sub DESTROY { my $self = shift; my $v = $self->value; print "bye, $v\n"; } | function __destruct() { echo "bye, $this->value\n"; } | Rational::~Rational() {}; | protected void finalize() throws Throwable { super.finalize(); } | |||||||
polymorphism | |||||||||||||
python | ruby | javascript | coffeescript | perl | php | cpp | d | java | scala | ocaml | haskell | lua | |
subclass | class Counter(Int): instances = 0 def __init__(self, v=0): Counter.instances += 1 Int.__init__(self, v) def incr(self): self.value += 1 | class Counter < Int @@instances = 0 def initialize @@instances += 1 super end def incr self.value += 1 end def self.instances @@instances end end | package Counter; our @ISA = "Int"; my $instances = 0; sub new { my $class = shift; my $self = Int->new(@_); $instances += 1; bless $self, $class; $self; } sub incr { my $self = shift; $self->value($self->value + 1); } sub instances { $instances; } | class Counter extends Int { private static $instances = 0; function __construct($int=0) { Counter::$instances += 1; parent::__construct($int); } function incr() { $this->value++; } static function getInstances() { return $instances; } } | class Integer : public Rational { public: Integer(int n); virtual ~Integer(); }; | public class RInteger extends Rational { public RInteger(int n) throws Throwable { super(n, 1); } } | |||||||
dynamic dispatch | declare as virtual in base class | dispatch dynamic by default | |||||||||||
static dispatch | dispatch static by default | declare as final, private, or static (i.e. make it a class method) | |||||||||||
mixin | |||||||||||||
overload function | int add(int m, int n) { return m + n; } float add(float x, float y) { return x + y; } | yes | |||||||||||
overload operator | class Rational: (...) def __add__(self, o): return Rational(self.num * o.denom + o.num * self.denom, self.denom * o.denom) (use special method names) | class Fixnum def /(n) self.fdiv(n) end end | Rational Rational::operator+(Rational& o) { return Rational(this->num * o.denom + o.num * this->denom, this->denom * o.denom); } | ref Rational opBinary(string op)(in Rational o) if (op == "+") { (compile-time test) return Rational(this.num * o.denom + o.num * this.denom, this.denom * o.denom); } | none | (almost all operators in Scala are just methods with symbolic names:) class Rational(val num: Int, val denom: Int) { (...) def +(o: Rational) = new Rational(num * o.denom + o.num * denom, denom * o.denom) } | |||||||
subclass | class Counter(Int): instances = 0 def __init__(self, v=0): Counter.instances += 1 Int.__init__(self, v) def incr(self): self.value += 1 | class Counter < Int @@instances = 0 def initialize @@instances += 1 super end def incr self.value += 1 end def self.instances @@instances end end | package Counter; our @ISA = "Int"; my $instances = 0; sub new { my $class = shift; my $self = Int->new(@_); $instances += 1; bless $self, $class; $self; } sub incr { my $self = shift; $self->value($self->value + 1); } sub instances { $instances; } | class Counter extends Int { private static $instances = 0; function __construct($int=0) { Counter::$instances += 1; parent::__construct($int); } function incr() { $this->value++; } static function getInstances() { return $instances; } } | class Integer : public Rational { public: Integer(int n); virtual ~Integer(); }; | public class RInteger extends Rational { public RInteger(int n) throws Throwable { super(n, 1); } } | |||||||
inheritance | |||||||||||||
invoking superclass constructor | Integer::Integer(int n) : Rational(n, 1) { } | super(n, 1); | |||||||||||
mark class underivable or method unoverrideable | none | final | |||||||||||
root class | none | java.lang.Object | |||||||||||
root class methods | none | clone() equals() finalize() getClass() hashCode() toString() | |||||||||||
reflection | |||||||||||||
python | ruby | javascript | coffeescript | perl | php | cpp | d | java | scala | ocaml | haskell | lua | |
get type class of object | o = new Object(); Class c = o.getClass(); | ||||||||||||
get type class from string | Class c = Class.forName("java.io.File"); | ||||||||||||
get type class from type identifier | typeid(Foo) | ||||||||||||
inspect class | o.__class__ == Foo isinstance(o, Foo) | o.class == Foo o.instance_of?(Foo) | ref($o) eq "Foo" | returns FALSE if not an object: get_class($o) == "Foo" | |||||||||
inspect class hierarchy | o.__class__.__bases__ | o.class.superclass o.class.included_modules | get_parent_class($o) | ||||||||||
object id | id(o) | o.object_id | |||||||||||
inspect type | type([]) == list | [].class == Array | typeof o | ref([]) eq "ARRAY" returns empty string if argument not a reference; returns package name for objects | gettype(array()) == "array" returns object for objects | repl displays the type of any expression entered | repl displays the type of any expression entered | let a = 3 :type a | type(o) | ||||
basic types | NoneType bool int long float str SRE_Pattern datetime list array dict object file | NilClass TrueClass FalseClass Fixnum Bignum Float String Regexp Time Array Hash Object File | SCALAR ARRAY HASH CODE REF GLOB LVALUE FORMAT IO VSTRING Regexp | NULL boolean integer double string array object resource unknown type | |||||||||
class name | typeid(Foo).name() | String name = c.getName(); | |||||||||||
get methods | import java.lang.reflect.*; Method[] m = c.getMethods(); | ||||||||||||
has method | hasattr(o, 'reverse') | o.respond_to?("reverse") | typeof o.foo == 'function' | $o->can("reverse") | method_exists($o, "reverse") | import java.lang.reflect.*; Class c = Class.forName("java.io.File"); Method[] a = c.getMethods(); boolean hasMethod = false; for (int i=0; i < a.length; i++) { if (a[i].getName() == "toString") { hasMethod = true; } } | |||||||
invoke method object | import java.lang.reflect.*; Class c = Class.forName("java.io.File"); Method m = c.getMethod("toString"); Object o = new Object(); m.invoke(o); | ||||||||||||
inspect type | type([]) == list | [].class == Array | typeof o | ref([]) eq "ARRAY" returns empty string if argument not a reference; returns package name for objects | gettype(array()) == "array" returns object for objects | repl displays the type of any expression entered | repl displays the type of any expression entered | let a = 3 :type a | type(o) | ||||
has method? | hasattr(o, 'reverse') | o.respond_to?("reverse") | typeof o.foo == 'function' | $o->can("reverse") | method_exists($o, "reverse") | import java.lang.reflect.*; Class c = Class.forName("java.io.File"); Method[] a = c.getMethods(); boolean hasMethod = false; for (int i=0; i < a.length; i++) { if (a[i].getName() == "toString") { hasMethod = true; } } | |||||||
message passing | for i in range(1,10): getattr(o, 'phone'+str(i))(None) | (1..9).each do |i| o.send("phone#{i}=", nil) end | o["foo"](1,1) | for $i (0..10) { $meth = "phone$i"; $o->$meth(undef); } | for ($i = 1; $i <= 10; $i++) { call_user_func(array($o, "phone$i"), NULL); } | ||||||||
eval | argument of eval must be an expression: while True: print(eval(sys.stdin.readline())) | loop do puts eval(gets) end | x = eval("1 + 1"); | while(<>) { print ((eval), "\n"); } | eval evaluates to argument of return statement or NULL: while ($line = fgets(STDIN)) { echo eval($line) . "\n"; } | assert(loadstring("x = 1+1"))() | |||||||
inspect methods | |||||||||||||
inspect attributes | |||||||||||||
list-obj object methods | [m for m in dir(o) if callable(getattr(o,m))] | o.methods | get_class_methods($o) | ||||||||||
list object attributes | dir(o) | o.instance_variables | keys %$o; | get_object_vars($o) | |||||||||
list loaded libraries | (relative to directory in lib path:) $LOADED_FEATURES $" | # relative to directory in lib path: keys %INC # absolute path: values %INC | |||||||||||
list loaded namespaces | dir() | Class.constants.select do |c| Module.const_get(c).class == Class end | grep { $_ =~ /::/ } keys %:: | ||||||||||
inspect namespace | import urlparse dir(urlparse) | require 'uri' URI.constants URI.methods URI.class_variables | keys %URI:: | module Unix = Unix;; | |||||||||
pretty print | import pprint d = {'lorem':1, 'ipsum':[2,3]} pprint.PrettyPrinter().pprint(d) | require 'pp' d = {"lorem"=>1, "ipsum"=>[2,3]} pp d | use Data::Dumper; %d = (lorem=>1, ipsum=>[2, 3]); print Dumper(\%d); | $d = array("lorem"=>1, "ipsum"=>array(2,3)); print_r($d); | |||||||||
source line number and file name | import inspect cf = inspect.currentframe() cf.f_lineno cf.f_code.co_filename | __LINE__ __FILE__ | __LINE__ __FILE__ | __LINE__ __FILE__ | |||||||||
command line documentation | pydoc math pydoc math.atan2 | ri -c ri Math ri Math.atan2 | perldoc Math::Trig | none | |||||||||
net and web | |||||||||||||
python | ruby | javascript | coffeescript | perl | php | cpp | d | java | scala | ocaml | haskell | lua | |
get local hostname, dns lookup, reverse dns lookup | import socket host = socket.gethostname() ip = socket.gethostbyname(host) host2 = socket.gethostbyaddr(ip)[0] | require 'socket' hostname = Socket.gethostname ip = Socket.getaddrinfo( Socket.gethostname, "echo")[0][3] host2 = Socket.gethostbyaddr(ip)[0] | use Sys::Hostname; use IO::Socket; $host = hostname; $ip = inet_ntoa( (gethostbyname(hostname))[4]); $host2 = (gethostbyaddr( inet_aton("10.45.234.23"), AF_INET))[0]; | $host = gethostname(); $ip = gethostbyname($host); $host2 = gethostbyaddr($ip); | |||||||||
http get | import httplib url = 'www.google.com' conn = httplib.HTTPConnection(url) conn.request("GET", '/') resp = conn.getresponse() if resp.status == httplib.OK: s = resp.read() | require 'net/http' url = "www.google.com" r = Net::HTTP.start(url, 80) do |f| f.get("/") end if r.code == "200" s = r.body end | use LWP::UserAgent; $url = "http://www.google.com"; $r = HTTP::Request->new(GET=>$url); $ua = LWP::UserAgent->new; $resp = $ua->request($r); my $s = $resp->content(); | $url = 'http://www.google.com'; $s = file_get_contents($url); | |||||||||
http post | import httplib import urllib url = 'www.acme.com' conn = httplib.HTTPConnection(url) data = urllib.urlencode({ 'item': 'anvil', 'qty': 1}) conn.request('POST', '/orders', data) resp = conn.getresponse() if resp.status == httplib.OK: s = resp.read() | ||||||||||||
serve working directory | python -m SimpleHTTPServer 8000 | ruby -rwebrick -e \ 'WEBrick::HTTPServer.new(:Port => 8000, '\ ':DocumentRoot => Dir.pwd).start' | $ php -S localhost:8000 | ||||||||||
absolute url | |||||||||||||
absolute url / from base and relative url | import urlparse urlparse.urljoin('http://google.com', 'analytics') | require 'uri' URI.join("http://google.com", "analytics") | use URI; URI->new_abs("analytics", "http://google.com"); | none | |||||||||
parse url | (Python 3 location: urllib.parse) import urlparse url = 'http://google.com:80/foo?q=3#bar' up = urlparse.urlparse(url) protocol = up.scheme hostname = up.hostname port = up.port path = up.path query_str = up.query fragment = up.fragment (returns dict of lists:) params = urlparse.parse_qs(query_str) | require 'uri' url = "http://google.com:80/foo?q=3#bar" up = URI(url) protocol = up.scheme hostname = up.host port = up.port path = up.path query_str = up.query fragment = up.fragment (Ruby 1.9; returns array of pairs:) params = URI.decode_www_form(query_str) | use URI; $url = "http://google.com:80/foo?q=3#bar"; $up = URI->new($url); $protocol = $up->scheme; $hostname = $up->host; $port = $up->port; $path = $up->path; $query_str = $up->query; $fragment = $up->fragment; # flat list of alternating keys and values: @params = $up->query_form(); | $url = "http://google.com:80/foo?q=3#bar"; $up = parse_url($url); $protocol = $up["scheme"]; $hostname = $up["host"]; $port = $up["port"]; $path = $up["path"]; $query_str = $up["query"]; $fragment = $up["fragment"]; ($params is associative array; if keys are reused, later values overwrite earlier values) parse_str($query_str, $params); | |||||||||
url encode/decode | (Python 3 location: urllib.parse) import urllib urllib.quote_plus("lorem ipsum?") urllib.unquote_plus("lorem+ipsum%3F") | require 'cgi' CGI::escape("lorem ipsum?") CGI::unescape("lorem+ipsum%3F") | use CGI; CGI::escape("lorem ipsum?") CGI::unescape("lorem%20ipsum%3F") | urlencode("lorem ipsum?") urldecode("lorem+ipsum%3F") | import java.net.URLEncoder; import java.net.URLDecoder; String url = "http://www.google.com"; String s = URLEncoder.encode(url, "utf8"); String s2 = URLDecoder.decode(s, "utf8"); | ||||||||
base64 encode/decode | import base64 s = open('foo.png').read() b64 = base64.b64encode(s) s2 = base64.b64decode(b64) | require 'base64' s = File.open("foo.png").read b64 = Base64.encode64(s) s2 = Base64.decode64(b64) | use MIME::Base64; open my $f, "<", "foo.png"; my $s = do { local $/; <$f> }; my $b64 = encode_base64($s); my $s2 = decode_base64($b64); | $s = file_get_contents("foo.png"); $b64 = base64_encode($s); $s2 = base64_decode($b64); | |||||||||
unit tests | |||||||||||||
python | ruby | javascript | coffeescript | perl | php | cpp | d | java | scala | ocaml | haskell | lua | |
test class | import unittest class TestFoo(unittest.TestCase): def test_01(self): self.assertTrue(True, 'not True!') if __name__ == '__main__': unittest.main() | require 'test/unit' class TestFoo < Test::Unit::TestCase def test_01 assert(true, "not true!") end end | # cpan -i Test::Class Test::More package TestFoo; use Test::Class; use Test::More; use base qw(Test::Class); sub test_01 : Test { ok(1, "not true!"); } 1; | # pear install pear.phpunit.de/PHPUnit <?php Class FooTest extends PHPUnit_Framework_TestCase { public function test_01() { $this->assertTrue(true, "not true!"); } } ?> | cat > test_foo.cpp #include <cppunit/TestCaller.h> #include <cppunit/TestCase.h> #include <cppunit/TestSuite.h> #include "test_foo.h" using namespace CppUnit; void TestFoo::test_01() { CPPUNIT_ASSERT_EQUAL(1, 1); } Test* TestFoo::suite() { TestSuite* suiteOfTests = new TestSuite("Foo"); suiteOfTests->addTest( new TestCaller<TestFoo>( "test_01", &TestFoo::test_01)); return suiteOfTests; } cat > test_foo.h #include <cppunit/TestCase.h> class TestFoo: public CppUnit::TestCase { public: void test_01(); static CppUnit::Test* suite(); }; | ||||||||
run tests, run test method | python test_foo.py python test_foo.py TestFoo.test_01 | ruby test_foo.rb ruby test_foo.rb -n test_01 | cat TestFoo.t use TestFoo; Test::Class->runtests; perl ./TestFoo.t | $ phpunit test_foo.php $ phpunit --filter test_01 test_foo.php | |||||||||
run all tests | cat > test_runner.cpp #include <cppunit/ui/text/TestRunner.h> #include "test_foo.h" int main( int argc, char** argv) { CppUnit::TextUi::TestRunner runner; runner.addTest(TestFoo::suite()); runner.run(); return 0; } sudo apt-get install libcppunit-dev cat > Makefile test_runner: test_runner.o test_foo.o g++ -o $@ $^ -lcppunit check: test_runner ./test_runner make check | ||||||||||||
equality assertion | s = 'do re me' self.assertEqual('do re me', s, 's: {}'.format(s)) | s = "do re me" assert_equal("do re me", s) | my $s = "do re me"; is($s, "do re me"); | $s = "do re me"; $this->assertEquals($s, "do re mi"); (also asserts args have same type:) $this->assertSame($s, "do re mi"); | #include <cppunit/TestCase.h> CPPUNIT_ASSERT_EQUAL(1, 1); CPPUNIT_ASSERT_EQUAL("foo", "bar"); CPPUNIT_ASSERT_EQUAL_MESSAGE("1 != 1", 1, 1); | ||||||||
approximate assertion | x = 10.0 * (1.0 / 3.0) y = 10.0 / 3.0 (default for delta is 0.1**7) self.assertAlmostEqual(x, y, delta=0.1**6) | x = 10.0 * (1.0 / 3.0) y = 10.0 / 3.0 (default for delta is 0.001) assert_in_delta(x, y, 0.1**6) | $x = 10.0 * (1.0 / 3.0); $y = 10.0 / 3.0; $this->assertEquals($x, $y, "not within delta", pow(0.1, 6)); | ||||||||||
regex assertion | s = 'lorem ipsum' (uses re.search, not re.match:) self.assertRegexpMatches(s, 'lorem') | s = "lorem ipsum" assert_match(/lorem/, s) | my $s = "lorem ipsum"; like($s, qr/lorem/); | $s = "lorem ipsum"; $this->assertRegExp("/lorem/", $s); | |||||||||
exception assertion | a = [] with self.assertRaises(IndexError): a[0] | assert_raises(ZeroDivisionError) do 1 / 0 end | use Test::Fatal; ok(exception { 1 / 0 }); | class Bam extends Exception {}; public function test_exc { $this->SetExpectedException("Bam"); throw new Bam("bam!"); } | |||||||||
mock method | # pip install mock import mock foo = Foo() foo.run = mock.MagicMock(return_value=7) self.assertEqual(7, foo.run(13)) foo.run.assert_called_once_with(13) | # gem install mocha require 'mocha' foo = mock() foo.expects(:run).returns(7).with(13).once foo.run(13) | $mock = $this->getMock('Foo', ['foo']); $mock->expects($this->once()) ->method('foo') ->with(13) ->will($this->returnValue(7)); $mock->foo(13); | ||||||||||
setup | (in class TestFoo:) def setUp(self): print('setting up') | (in class TestFoo:) def setup puts "setting up" end | # in class TestFoo: sub make_fixture : Test(setup) { print "setting up"; }; | public function setUp() { echo "setting up\n"; } | |||||||||
teardown | (in class TestFoo:) def tearDown(self): print('tearing down') | (in class TestFoo:) def teardown puts "tearing down" end | # in class TestFoo: sub teardown : Test(teardown) { print "tearing down"; }; | public function tearDown() { echo "tearing down\n"; } | |||||||||
debugging and profiling | |||||||||||||
python | ruby | javascript | coffeescript | perl | php | cpp | d | java | scala | ocaml | haskell | lua | |
check syntax | import py_compile (precompile to bytecode:) py_compile.compile('foo.py') | ruby -c foo.rb | perl -c foo.pl | $ php -l foo.php | |||||||||
flag for stronger warnings | python -t foo.py python -3t foo.py | ruby -w foo.rb ruby -W2 foo.rb | perl -w foo.pl perl -W foo.pl | none | g++ -Wall foo.cpp | ||||||||
flags for stronger and strongest warnings | python -t foo.py python -3t foo.py | ruby -w foo.rb ruby -W2 foo.rb | perl -w foo.pl perl -W foo.pl | none | g++ -Wall foo.cpp | ||||||||
suppress warnings | g++ -w foo.cpp | ||||||||||||
treat warnings as errors | g++ -Werror foo.cpp | ||||||||||||
run debugger | python -m pdb foo.py | sudo gem install ruby-debug rdebug foo.rb | perl -d foo.pl | g++ -g -o foo foo.cpp gdb foo (gdb) b main (gdb) run | |||||||||
debugger commands / help, list source, (re)load executable, next, step, set breakpoint, show breakpoints, delete breakpoint, continue, backtrace, up stack, down stack, print, run, quit | > h > l [FIRST_LINENO, LAST_LINENO] > file PATH > n > s > b [FILE:]LINENO > i > d NUM > c > bt > up > do > p EXPR > r [ARG1[, [ARG2 ...]] > q | ||||||||||||
debugger commands | h l n s b c w u d p q | h l n s b c w u down p q | h l n s b c T ?? ?? p q | ||||||||||
benchmark code | import timeit timeit.timeit('i += 1', 'i = 0', number=1000000) | require 'benchmark' n = 1_000_000 i = 0 puts Benchmark.measure do n.times { i += 1 } end | use Benchmark qw(:all); $t = timeit(1_000_000, '$i += 1;'); print timestr($t); | ||||||||||
profile code | python -m cProfile foo.py | sudo gem install ruby-prof ruby-prof foo.rb | perl -d:DProf foo.pl dprofpp | gprof does not work on Mac OS X: g++ -pg -o foo foo.cpp ./foo gprof foo | |||||||||
memory tool | sudo apt-get install valgrind g++ -o foo foo.cpp valgrind ./foo | ||||||||||||
lint | sudo pip install pylint pylint foo.py | perl MO=Lint foo.pl | |||||||||||
source cleanup | sudo pip install pep8 pep8 foo.py | ||||||||||||
about-repl | |||||||||||||
python | ruby | javascript | coffeescript | perl | php | cpp | d | java | scala | ocaml | haskell | lua | |
invoke repl | scala | $ ocaml Use this if you want history: $ rlwrap ocaml The utop toplevel, which can be installed via opam, also provides history. | $ ghci | ||||||||||
repl limitations | Must use let to define values and functions; when defining functions with multiple equations the equations must be separated by semicolons; the clauses of case/of statements must be separated by semicolons; it is not possible to define data types. | ||||||||||||
repl last value | res0, res1, … | none | it | ||||||||||
help | :help | none | :? | ||||||||||
quit | ^D | ||||||||||||
inspect type | type([]) == list | [].class == Array | typeof o | ref([]) eq "ARRAY" returns empty string if argument not a reference; returns package name for objects | gettype(array()) == "array" returns object for objects | repl displays the type of any expression entered | repl displays the type of any expression entered | let a = 3 :type a | type(o) | ||||
inspect namespace | import urlparse dir(urlparse) | require 'uri' URI.constants URI.methods URI.class_variables | keys %URI:: | module Unix = Unix;; | |||||||||
load source file | #use "hello";; | :edit hello.hs :load hello | |||||||||||
load package | consider adding to .ocamlinit: #use "topfind";; # thread;; #require "core";; open Core.Std;; | ||||||||||||
search path | #directory "libdir";; | ||||||||||||
set search path on command line | ocaml -Ilibdir | ||||||||||||
java interoperation | |||||||||||||
python | ruby | javascript | coffeescript | perl | php | cpp | d | java | scala | ocaml | haskell | lua | |
version | Jython 2.5 compatible with Python 2.5 :( | JRuby 1.7 compatible with Ruby 1.9 | |||||||||||
repl | jython | jirb | |||||||||||
interpreter | jython | jruby | |||||||||||
compiler | jrubyc | ||||||||||||
prologue | import java | none | |||||||||||
new | rnd = java.util.Random() | rnd = java.util.Random.new | |||||||||||
method | rnd.nextFloat() | rnd.next_float | |||||||||||
import | from java.util import Random rnd = Random() | java_import java.util.Random rnd = Random.new | |||||||||||
non-bundled java libraries | import sys sys.path.append('path/to/mycode.jar') import MyClass | require 'path/to/mycode.jar' | |||||||||||
shadowing avoidance | import java.io as javaio | module JavaIO include_package "java.io" end | |||||||||||
convert native array to java array | import jarray jarray.array([1, 2, 3], 'i') | [1, 2, 3].to_java(Java::int) | |||||||||||
are java classes subclassable? | yes | yes | |||||||||||
are java class open? | no | yes |