Lang Compare

Web
Systems
App Development
Scripting & Data

JavaScript

Web

TypeScript

Web

PHP

Web

Ruby

Web

Go

Systems

Rust

Systems

C++

Systems

C#

App Development

Swift

App Development

Kotlin

App Development

Python

Scripting & Data

Overview

High-level, dynamic scripting language. The language of the web — runs in every browser and on the server via Node.js/Deno/Bun.

Overview

Typed superset of JavaScript that compiles to plain JS. Adds static types, interfaces, and powerful tooling to JavaScript.

Overview

Widely-used server-side scripting language. Powers a huge portion of the web including WordPress, Laravel, and Symfony.

Overview

Dynamic, object-oriented language designed for developer happiness. Known for Ruby on Rails and an emphasis on convention over configuration.

Overview

Statically typed, compiled language designed at Google. Known for simplicity, fast compilation, built-in concurrency, and excellent tooling.

Overview

Systems programming language focused on safety, speed, and concurrency. Guarantees memory safety without a garbage collector.

Overview

High-performance systems language with zero-cost abstractions. Used for game engines, operating systems, embedded systems, and performance-critical applications.

Overview

Modern, object-oriented language by Microsoft. Used for desktop apps, games (Unity), web backends (ASP.NET), and cross-platform mobile apps (MAUI).

Overview

Modern, safe language by Apple. Primary language for iOS, macOS, watchOS, and tvOS development. Also used for server-side development.

Overview

Modern, concise JVM language by JetBrains. Primary language for Android development. Also used for server-side, multiplatform, and desktop apps.

Overview

General-purpose, high-level language known for readability. Widely used in data science, AI/ML, web backends, scripting, and automation.

Installation & Getting Started

JavaScript runs in every browser. For server-side / local development, install a runtime like Node.js, Deno, or Bun.

# Node.js — install via nvm (recommended)
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.0/install.sh | bash
nvm install --lts
node --version

# Or via Homebrew (macOS)
brew install node

# Deno — built-in TypeScript, no config needed
curl -fsSL https://deno.land/install.sh | sh
deno --version

# Bun — fast all-in-one runtime
curl -fsSL https://bun.sh/install | bash
bun --version
# REPL — start an interactive session
node           # Node.js REPL
deno           # Deno REPL
bun repl       # Bun REPL

# Run a script
node script.js
deno run script.js
bun run script.js

# Quick one-liner
node -e "console.log('Hello!')"

Installation & Getting Started

TypeScript requires a JavaScript runtime plus the TypeScript compiler. Some runtimes (Deno, Bun) support TypeScript natively.

# Install Node.js (see JavaScript) then add TypeScript
npm install -g typescript
tsc --version

# Or install locally per-project
npm install --save-dev typescript
npx tsc --version

# Deno — runs TypeScript natively, no setup
deno --version
deno run script.ts

# Bun — native TypeScript support
bun run script.ts

# tsx — run TS files directly in Node.js
npm install -g tsx
tsx script.ts
# REPL — no official TS REPL, but use tsx or ts-node
npx tsx          # Interactive TypeScript REPL
npx ts-node      # Alternative REPL
deno             # Deno REPL supports TypeScript

# Compile and run
npx tsc script.ts && node script.js

# Type-check without emitting
npx tsc --noEmit

Installation & Getting Started

PHP is pre-installed on many systems. For local development, use a package manager or a bundled environment.

# macOS (Homebrew)
brew install php

# Ubuntu / Debian
sudo apt install php php-cli php-mbstring php-xml

# Windows — use XAMPP, Laragon, or Scoop
scoop install php

# Check version
php --version
# REPL — interactive mode
php -a

# Run a script
php script.php

# Quick one-liner
php -r "echo 'Hello, PHP!' . PHP_EOL;"

# Built-in development server
php -S localhost:8000

# Built-in server with router
php -S localhost:8000 router.php

Installation & Getting Started

Ruby is pre-installed on macOS. Use a version manager like rbenv or asdf for managing versions.

# macOS (Homebrew)
brew install ruby

# rbenv — recommended version manager
brew install rbenv ruby-build
rbenv install 3.3.0
rbenv global 3.3.0

# Or use asdf
asdf plugin add ruby
asdf install ruby 3.3.0
asdf global ruby 3.3.0

# Ubuntu / Debian
sudo apt install ruby-full

# Check version
ruby --version
# IRB — interactive Ruby (REPL)
irb

# Pry — enhanced REPL
gem install pry
pry

# Run a script
ruby script.rb

# Quick one-liner
ruby -e "puts 'Hello, Ruby!'"

# Run with warnings
ruby -w script.rb

Installation & Getting Started

Download from the official site or use a package manager. Go is a single binary with everything included.

# macOS (Homebrew)
brew install go

# Linux
wget https://go.dev/dl/go1.22.0.linux-amd64.tar.gz
sudo tar -C /usr/local -xzf go1.22.0.linux-amd64.tar.gz
export PATH=$PATH:/usr/local/go/bin

# Windows — download installer from https://go.dev/dl/

# Verify installation
go version
# No REPL built-in — but alternatives exist:
# gore — a Go REPL
go install github.com/x-motemen/gore/cmd/gore@latest
gore

# Go Playground — try Go in the browser
# https://go.dev/play/

# Run a file directly (no build step needed)
go run main.go

# Quick one-liner (via go run)
echo 'package main; import "fmt"; func main() { fmt.Println("Hello!") }' > /tmp/hello.go && go run /tmp/hello.go

Installation & Getting Started

Install via rustup, the official Rust toolchain installer. It manages Rust versions, components, and targets.

# Install Rust via rustup (recommended)
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh

# macOS (Homebrew — not recommended, use rustup)
brew install rust

# Verify installation
rustc --version
cargo --version

# Update Rust
rustup update

# Install a specific toolchain
rustup install nightly
rustup default stable
# No built-in REPL — but evcxr is a popular Rust REPL
cargo install evcxr_repl
evcxr

# Rust Playground — try in the browser
# https://play.rust-lang.org/

# Run a file directly
rustc hello.rs && ./hello

# Run via Cargo (preferred)
cargo run

# Quick script with cargo-script
cargo install cargo-script
cargo script hello.rs

Installation & Getting Started

Install a C++ compiler (GCC, Clang, or MSVC) and optionally CMake for build management.

# macOS — Clang comes with Xcode Command Line Tools
xcode-select --install
clang++ --version

# Linux (Ubuntu/Debian) — GCC
sudo apt install build-essential cmake
g++ --version

# Linux — Clang
sudo apt install clang

# Windows — MSVC via Visual Studio, or MinGW/MSYS2
# Download from https://visualstudio.microsoft.com/

# Verify
g++ --version    # or clang++ --version
cmake --version
# No built-in REPL — but cling provides one
# Install cling: https://github.com/root-project/cling
cling

# Compiler Explorer — try in the browser
# https://godbolt.org/

# Compile and run
g++ -std=c++20 -o hello hello.cpp && ./hello
clang++ -std=c++20 -o hello hello.cpp && ./hello

# With CMake
cmake -B build && cmake --build build && ./build/app

# Quick compile + run
echo '#include <iostream>
int main() { std::cout << "Hello!\\n"; }' > /tmp/h.cpp && g++ -o /tmp/h /tmp/h.cpp && /tmp/h

Installation & Getting Started

Install the .NET SDK, which includes the C# compiler, runtime, and CLI tools.

# macOS (Homebrew)
brew install dotnet

# Linux (Ubuntu/Debian)
sudo apt install dotnet-sdk-8.0

# Windows — download from https://dotnet.microsoft.com/download

# Or use the install script
curl -sSL https://dot.net/v1/dotnet-install.sh | bash

# Verify installation
dotnet --version
# REPL — C# Interactive (csi)
dotnet tool install -g dotnet-script
dotnet script    # Interactive REPL

# Or use C# Interactive in Visual Studio
# Tools > C# Interactive

# .NET Fiddle — try in the browser
# https://dotnetfiddle.net/

# Run a project
dotnet run

# Run a single file script (.csx)
dotnet script hello.csx

# Quick one-liner
dotnet script eval "Console.WriteLine(\"Hello!\")"

Installation & Getting Started

Swift comes bundled with Xcode on macOS. On Linux, install via the official toolchain or swiftly.

# macOS — included with Xcode
xcode-select --install
swift --version

# macOS — standalone (without Xcode)
brew install swift

# Linux (Ubuntu)
# Download from https://swift.org/download/
# Or use swiftly (version manager)
curl -L https://swiftlang.github.io/swiftly/swiftly-install.sh | bash
swiftly install latest

# Windows — download from https://swift.org/download/

# Verify
swift --version
# REPL — Swift has a built-in REPL
swift                  # Start REPL
# > let x = 42
# > print(x)

# Swift Playgrounds — interactive learning (macOS/iPad)
# Xcode Playgrounds — rapid prototyping in Xcode

# Run a script
swift hello.swift

# Run a package
swift run

# Online playground
# https://swiftfiddle.com/

Installation & Getting Started

Install the Kotlin compiler standalone, or get it bundled with IntelliJ IDEA or Android Studio. Kotlin runs on the JVM, so a JDK is required.

# macOS (Homebrew)
brew install kotlin

# SDKMAN (recommended for JVM languages)
curl -s https://get.sdkman.io | bash
sdk install kotlin
sdk install java 21-tem  # Also install a JDK

# Linux (snap)
sudo snap install kotlin --classic

# Verify
kotlin -version
kotlinc -version
java -version  # JDK required
# REPL — Kotlin has a built-in REPL
kotlinc          # Start REPL
# >>> val x = 42
# >>> println(x)

# Kotlin Playground — try in the browser
# https://play.kotlinlang.org/

# Run a script (.kts file)
kotlin script.main.kts

# Compile and run
kotlinc hello.kt -include-runtime -d hello.jar
java -jar hello.jar

# Run directly (Kotlin 1.9+)
kotlin hello.kt

# Kotlin Notebooks — in IntelliJ IDEA
# Similar to Jupyter, for interactive exploration

Installation & Getting Started

Python comes pre-installed on macOS and most Linux distros. Use pyenv or the official installer for version management.

# macOS (Homebrew)
brew install python

# Using pyenv (recommended for version management)
brew install pyenv
pyenv install 3.12
pyenv global 3.12

# Using uv (fast Python version management)
uv python install 3.12
uv python pin 3.12

# Verify installation
python3 --version
# REPL — Python has an excellent built-in REPL
python3             # Standard REPL
python3 -i script.py  # Run script then drop into REPL

# IPython — enhanced REPL with autocomplete, syntax highlighting
pip install ipython
ipython

# Jupyter — interactive notebooks
pip install jupyter
jupyter notebook

# Run a script
python3 script.py

# Quick one-liner
python3 -c "print('Hello!')"

Project Scaffolding

Use npm init for a basic project or a framework CLI for a full setup.

# Basic project
mkdir my-project && cd my-project
npm init -y

# Using Vite
npm create vite@latest my-app

# Using Next.js
npx create-next-app@latest my-app

# Using Astro
npm create astro@latest

# Run the project
npm run dev

Project Scaffolding

Initialize a tsconfig.json or use a framework CLI that includes TypeScript.

# Basic TypeScript project
mkdir my-project && cd my-project
npm init -y
npm install --save-dev typescript
npx tsc --init

# Using Vite with TypeScript
npm create vite@latest my-app -- --template vanilla-ts

# Using tsx for scripts (no build step)
npm install --save-dev tsx
npx tsx src/index.ts

# Run with ts-node
npx ts-node src/index.ts

Project Scaffolding

Use Composer to create projects from templates. Laravel and Symfony have dedicated installers.

# Basic project with Composer
mkdir my-project && cd my-project
composer init

# Laravel — full-stack web framework
composer create-project laravel/laravel my-app
cd my-app && php artisan serve

# Laravel via installer
composer global require laravel/installer
laravel new my-app

# Symfony
composer create-project symfony/skeleton my-app
cd my-app && symfony server:start

# Slim (micro-framework)
composer create-project slim/slim-skeleton my-app

# Run development server
php -S localhost:8000 -t public

Project Scaffolding

Use bundler for dependency management and Rails or Sinatra for web projects.

# Basic Ruby project
mkdir my-project && cd my-project
bundle init            # Creates Gemfile

# Ruby on Rails — full-stack web framework
gem install rails
rails new my-app
cd my-app && rails server

# Rails with specific options
rails new my-api --api                  # API-only
rails new my-app --database=postgresql  # PostgreSQL

# Sinatra — lightweight web framework
mkdir my-app && cd my-app
bundle init
# Add: gem 'sinatra' to Gemfile
bundle install
ruby app.rb

# Gem scaffold (create a new gem/library)
bundle gem my-gem
# Creates lib/, spec/, Gemfile, .gemspec

Project Scaffolding

Initialize a module with go mod init. No external scaffolding tools needed.

# Create a new project
mkdir my-project && cd my-project
go mod init github.com/user/my-project

# Create main file
cat > main.go << 'EOF'
package main

import "fmt"

func main() {
    fmt.Println("Hello, World!")
}
EOF

# Run the project
go run .

# Build a binary
go build -o my-app .

Project Scaffolding

Cargo creates the full project structure with one command.

# Create a new binary project
cargo new my-project
cd my-project

# Create a library project
cargo new my-lib --lib

# Project structure created:
# my-project/
#   Cargo.toml
#   src/
#     main.rs  (or lib.rs)

# Run the project
cargo run

# Build for release
cargo build --release

# Run tests
cargo test

Project Scaffolding

Create a CMake project manually or use a tool like cmake --init.

# Basic CMake project
mkdir my-project && cd my-project
mkdir src

cat > CMakeLists.txt << 'EOF'
cmake_minimum_required(VERSION 3.20)
project(MyProject)
set(CMAKE_CXX_STANDARD 20)
add_executable(app src/main.cpp)
EOF

cat > src/main.cpp << 'EOF'
#include <iostream>
int main() {
    std::cout << "Hello, World!\n";
}
EOF

# Build and run
cmake -B build
cmake --build build
./build/app

Project Scaffolding

The dotnet CLI creates projects from built-in templates.

# Console app
dotnet new console -n MyApp
cd MyApp

# Web API
dotnet new webapi -n MyApi

# Class library
dotnet new classlib -n MyLib

# List available templates
dotnet new list

# Run the project
dotnet run

# Build for release
dotnet build -c Release

# Publish self-contained
dotnet publish -c Release --self-contained

Project Scaffolding

Use SPM for command-line tools or Xcode for app projects.

# Create a new package (library)
swift package init --name MyLib

# Create an executable
swift package init --type executable --name MyApp

# Project structure created:
# MyApp/
#   Package.swift
#   Sources/
#     main.swift

# Build and run
swift build
swift run

# Create an iOS/macOS app
# Open Xcode > File > New > Project
# Select template (App, Framework, etc.)

# Build for release
swift build -c release

Project Scaffolding

Use IntelliJ IDEA, Android Studio, or the Kotlin project wizard.

# Using Gradle init
gradle init --type kotlin-application

# Project structure:
# app/
#   build.gradle.kts
#   src/
#     main/kotlin/App.kt
#     test/kotlin/AppTest.kt

# Run the project
./gradlew run

# Build
./gradlew build

# Android project: use Android Studio wizard
# Multiplatform: use start.kotlinlang.org

# Kotlin scripting
echo 'println("Hello!")' > script.main.kts
kotlin script.main.kts

Project Scaffolding

Create a virtual environment and a pyproject.toml or requirements.txt.

# Basic project with venv
mkdir my-project && cd my-project
python -m venv .venv
source .venv/bin/activate

# Using uv (recommended)
uv init my-project
cd my-project
uv run python main.py

# Using poetry
poetry new my-project
cd my-project
poetry install

# Django web project
pip install django
django-admin startproject mysite

# FastAPI project
pip install "fastapi[standard]"

Package Management

npm is the default package manager. Yarn, pnpm, and Bun are popular alternatives.

# Install a package
npm install lodash

# Install as dev dependency
npm install --save-dev vitest

# Install globally
npm install -g typescript

# Using pnpm
pnpm add lodash

# Using yarn
yarn add lodash

# Using bun
bun add lodash

Package Management

Uses the same package managers as JavaScript. Type definitions are installed separately for untyped packages.

# Install a package
npm install zod

# Install type definitions
npm install --save-dev @types/node

# Most modern packages include types
npm install axios  # types included

# Using pnpm
pnpm add zod

# Using bun (has built-in TS support)
bun add zod

Package Management

Composer is the standard dependency manager for PHP. Packages are hosted on Packagist.

# Install Composer
curl -sS https://getcomposer.org/installer | php
sudo mv composer.phar /usr/local/bin/composer

# Install a package
composer require guzzlehttp/guzzle

# Install as dev dependency
composer require --dev phpunit/phpunit

# Install all dependencies
composer install

# Update dependencies
composer update

# Autoload classes
composer dump-autoload
// composer.json
{
  "require": {
    "php": "^8.2",
    "guzzlehttp/guzzle": "^7.0",
    "laravel/framework": "^11.0"
  },
  "require-dev": {
    "phpunit/phpunit": "^11.0"
  },
  "autoload": {
    "psr-4": {
      "App\\": "src/"
    }
  }
}

Package Management

RubyGems is the package manager. Bundler manages project dependencies via a Gemfile.

# Install a gem globally
gem install rails
gem install pry

# Bundler — project dependency management
gem install bundler

# Install all dependencies from Gemfile
bundle install

# Add a gem to the project
bundle add sidekiq

# Update dependencies
bundle update
bundle update rails  # Update specific gem

# Execute a command in bundle context
bundle exec rails server
bundle exec rspec
# Gemfile
source 'https://rubygems.org'

ruby '3.3.0'

gem 'rails', '~> 7.1'
gem 'pg'
gem 'puma'
gem 'redis'

group :development, :test do
  gem 'rspec-rails'
  gem 'pry-byebug'
  gem 'factory_bot_rails'
end

group :development do
  gem 'rubocop', require: false
end

Package Management

Go modules (go mod) is the built-in dependency management system.

# Add a dependency
go get github.com/gin-gonic/gin

# Add a specific version
go get github.com/gin-gonic/gin@v1.9.1

# Tidy up (remove unused, add missing)
go mod tidy

# List dependencies
go list -m all

# Update all dependencies
go get -u ./...

# Vendor dependencies
go mod vendor

Package Management

Cargo is Rust’s built-in package manager and build tool. Packages are called “crates”.

# Add a dependency
cargo add serde

# Add with features
cargo add serde --features derive

# Add a dev dependency
cargo add --dev tokio-test

# Remove a dependency
cargo remove serde

# Update dependencies
cargo update

# Search for crates
cargo search json

Package Management

No built-in package manager. vcpkg and Conan are the most popular options.

# Using vcpkg
vcpkg install fmt
vcpkg install boost:x64-linux

# Using Conan
conan install . --build=missing

# CMake FetchContent (download at build time)
# In CMakeLists.txt:
# FetchContent_Declare(fmt
#   GIT_REPOSITORY https://github.com/fmtlib/fmt
#   GIT_TAG 10.1.1)
# FetchContent_MakeAvailable(fmt)

# System package managers
sudo apt install libboost-all-dev  # Debian/Ubuntu
brew install fmt                    # macOS

Package Management

NuGet is the package manager for .NET. Managed via the dotnet CLI or Visual Studio.

# Add a package
dotnet add package Newtonsoft.Json

# Add a specific version
dotnet add package Serilog --version 3.1.0

# Remove a package
dotnet remove package Newtonsoft.Json

# Restore packages
dotnet restore

# List installed packages
dotnet list package

# Update packages
dotnet outdated  # requires dotnet-outdated tool

Package Management

Swift Package Manager (SPM) is built into Swift and Xcode.

# Add a dependency in Package.swift:
# dependencies: [
#     .package(url: "https://github.com/Alamofire/Alamofire",
#              from: "5.0.0")
# ]

# Resolve dependencies
swift package resolve

# Update dependencies
swift package update

# Show dependencies
swift package show-dependencies

# In Xcode: File > Add Package Dependencies
# Paste the repository URL and select version

Package Management

Uses Gradle (Kotlin DSL or Groovy) to manage dependencies from Maven Central.

// build.gradle.kts
dependencies {
    implementation("com.squareup.okhttp3:okhttp:4.12.0")
    implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.8.0")
    testImplementation("junit:junit:4.13.2")
}

// Version catalogs (libs.versions.toml)
// [versions]
// okhttp = "4.12.0"
// [libraries]
// okhttp = { module = "com.squareup.okhttp3:okhttp", version.ref = "okhttp" }
# Sync dependencies
./gradlew build

# Show dependency tree
./gradlew dependencies

Package Management

pip is the standard package manager. uv and poetry are modern alternatives.

# Install a package
pip install requests

# Install from requirements file
pip install -r requirements.txt

# Using uv (fast, modern)
uv pip install requests
uv add requests

# Using poetry
poetry add requests

# Virtual environments
python -m venv .venv
source .venv/bin/activate  # macOS/Linux

Tooling & Formatter/Linter

Rich ecosystem of formatters and linters. Most projects use a combination.

# Prettier — opinionated code formatter
npm install --save-dev prettier
npx prettier --write .

# ESLint — linting and code quality
npm install --save-dev eslint
npx eslint --init
npx eslint .

# Biome — fast all-in-one (format + lint)
npm install --save-dev @biomejs/biome
npx biome check --write .

# oxlint — extremely fast linter (Rust-based)
npx oxlint .
// .prettierrc
{
  "semi": false,
  "singleQuote": true,
  "trailingComma": "all",
  "printWidth": 100
}
// eslint.config.js (flat config)
import js from '@eslint/js'
export default [
  js.configs.recommended,
  { rules: { 'no-unused-vars': 'warn' } },
]

Tooling & Formatter/Linter

Same tools as JavaScript, with TypeScript-aware configurations. tsc itself is the primary type checker.

# Prettier — formats TS natively
npx prettier --write "**/*.ts"

# ESLint with TypeScript
npm install --save-dev eslint typescript-eslint
npx eslint .

# Biome — supports TypeScript out of the box
npx biome check --write .

# Type checking (not a linter, but essential)
npx tsc --noEmit
// eslint.config.js (flat config with TypeScript)
import eslint from '@eslint/js'
import tseslint from 'typescript-eslint'

export default tseslint.config(
  eslint.configs.recommended,
  ...tseslint.configs.strictTypeChecked,
  {
    languageOptions: {
      parserOptions: {
        projectService: true,
      },
    },
  },
)
# Editor support
# VS Code: ESLint + Prettier extensions
# Biome: Biome VS Code extension
# Type errors shown inline via TypeScript language server

Tooling & Formatter/Linter

PHP has mature code quality tools for formatting, linting, and static analysis.

# PHP CS Fixer — code formatter
composer require --dev friendsofphp/php-cs-fixer
./vendor/bin/php-cs-fixer fix src/

# PHP_CodeSniffer — linter & fixer
composer require --dev squizlabs/php_codesniffer
./vendor/bin/phpcs src/         # Lint
./vendor/bin/phpcbf src/        # Auto-fix

# PHPStan — static analysis
composer require --dev phpstan/phpstan
./vendor/bin/phpstan analyse src/ --level=max

# Psalm — static analysis (alternative)
composer require --dev vimeo/psalm
./vendor/bin/psalm

# Rector — automated refactoring
composer require --dev rector/rector
./vendor/bin/rector process src/
// .php-cs-fixer.dist.php
<?php
return (new PhpCsFixer\Config())
    ->setRules([
        '@PSR12' => true,
        'array_syntax' => ['syntax' => 'short'],
        'no_unused_imports' => true,
        'ordered_imports' => true,
    ])
    ->setFinder(
        PhpCsFixer\Finder::create()->in(__DIR__ . '/src')
    );

Tooling & Formatter/Linter

RuboCop is the standard linter and formatter. Sorbet adds static typing.

# RuboCop — linter & formatter
gem install rubocop
rubocop                    # Lint
rubocop -a                 # Auto-fix safe cops
rubocop -A                 # Auto-fix all cops (including unsafe)

# RuboCop with Rails extensions
gem install rubocop-rails rubocop-rspec rubocop-performance
rubocop --require rubocop-rails

# Standard Ruby — opinionated RuboCop config (zero config)
gem install standard
standardrb                 # Lint
standardrb --fix           # Auto-fix

# Sorbet — static type checker
gem install sorbet sorbet-runtime
srb init                   # Initialize in project
srb tc                     # Type check

# Steep — alternative type checker (uses RBS)
gem install steep
steep check
# .rubocop.yml
require:
  - rubocop-rails
  - rubocop-rspec

AllCops:
  NewCops: enable
  TargetRubyVersion: 3.3

Style/StringLiterals:
  EnforcedStyle: single_quotes

Metrics/MethodLength:
  Max: 15

Tooling & Formatter/Linter

Go has strong built-in tooling. Formatting is enforced by convention — all Go code looks the same.

# gofmt — built-in formatter (canonical style)
gofmt -w .

# goimports — gofmt + auto-manage imports
go install golang.org/x/tools/cmd/goimports@latest
goimports -w .

# go vet — built-in static analysis
go vet ./...

# golangci-lint — meta-linter (runs many linters)
# Install: https://golangci-lint.run/usage/install/
golangci-lint run

# staticcheck — advanced static analysis
go install honnef.co/go/tools/cmd/staticcheck@latest
staticcheck ./...
# .golangci.yml
linters:
  enable:
    - errcheck
    - govet
    - staticcheck
    - unused
    - gosimple
    - ineffassign
    - misspell
    - revive
# Editor: gopls (Go language server) provides
# formatting, linting, and refactoring in all editors

Tooling & Formatter/Linter

Rust ships with rustfmt and clippy as official tools. The compiler itself is an excellent linter.

# rustfmt — official formatter
rustfmt src/main.rs
cargo fmt              # Format entire project
cargo fmt -- --check   # Check without modifying

# Clippy — official linter (hundreds of lints)
cargo clippy
cargo clippy -- -W clippy::pedantic  # Stricter lints
cargo clippy --fix     # Auto-fix suggestions

# cargo check — fast type/borrow checking (no codegen)
cargo check
# rustfmt.toml
max_width = 100
edition = "2021"
use_field_init_shorthand = true
# Clippy config in Cargo.toml
[lints.clippy]
pedantic = { level = "warn", priority = -1 }
needless_pass_by_value = "allow"
# rust-analyzer — language server for all editors
# Provides inline errors, completions, refactoring,
# hover docs, and inlay type hints

Tooling & Formatter/Linter

C++ uses clang-format for formatting and clang-tidy for linting. Both are part of the LLVM toolchain.

# clang-format — code formatter
clang-format -i src/*.cpp src/*.h
clang-format --style=file -i main.cpp  # Use .clang-format

# clang-tidy — linter and static analyzer
clang-tidy src/*.cpp -- -std=c++20
clang-tidy --fix src/main.cpp

# cppcheck — additional static analysis
cppcheck --enable=all src/

# include-what-you-use — minimize #includes
iwyu src/main.cpp
# .clang-format
BasedOnStyle: Google
ColumnLimit: 100
IndentWidth: 4
Language: Cpp
Standard: c++20
AllowShortFunctionsOnASingleLine: Inline
# .clang-tidy
Checks: >
  -*,
  bugprone-*,
  modernize-*,
  performance-*,
  readability-*,
  -modernize-use-trailing-return-type
WarningsAsErrors: ''

Tooling & Formatter/Linter

C# uses .editorconfig for style rules and Roslyn analyzers for linting. dotnet format is the built-in formatter.

# dotnet format — built-in formatter
dotnet format                 # Format entire solution
dotnet format --verify-no-changes  # CI check

# Roslyn analyzers (NuGet packages)
dotnet add package Microsoft.CodeAnalysis.NetAnalyzers
dotnet add package StyleCop.Analyzers

# CSharpier — Prettier-inspired opinionated formatter
dotnet tool install csharpier -g
dotnet csharpier .
# .editorconfig
[*.cs]
indent_style = space
indent_size = 4
dotnet_sort_system_directives_first = true
csharp_new_line_before_open_brace = all
csharp_prefer_braces = true
dotnet_diagnostic.CA1062.severity = warning
<!-- Directory.Build.props — enable analyzers project-wide -->
<Project>
  <PropertyGroup>
    <AnalysisLevel>latest-recommended</AnalysisLevel>
    <EnforceCodeStyleInBuild>true</EnforceCodeStyleInBuild>
    <TreatWarningsAsErrors>true</TreatWarningsAsErrors>
  </PropertyGroup>
</Project>

Tooling & Formatter/Linter

Swift uses swift-format (Apple’s official formatter) or SwiftLint for linting. Xcode provides built-in formatting.

# swift-format — official formatter
brew install swift-format
swift-format format --in-place Sources/
swift-format lint Sources/

# SwiftLint — community linter (widely adopted)
brew install swiftlint
swiftlint
swiftlint --fix       # Auto-fix
# .swiftlint.yml
disabled_rules:
  - trailing_whitespace
opt_in_rules:
  - empty_count
  - closure_spacing
  - force_unwrapping
excluded:
  - .build
  - Packages
line_length:
  warning: 120
  error: 150
// .swift-format (JSON config)
{
  "version": 1,
  "indentation": { "spaces": 4 },
  "lineLength": 120,
  "maximumBlankLines": 1,
  "respectsExistingLineBreaks": true
}
# Xcode: Editor > Structure > Re-Indent (Ctrl+I)
# Periphery — detect unused code
brew install peripheryapp/periphery/periphery
periphery scan

Tooling & Formatter/Linter

Kotlin uses ktlint for linting/formatting and detekt for static analysis. IntelliJ IDEA provides built-in formatting.

# ktlint — linter + formatter (follows Kotlin style guide)
brew install ktlint
ktlint                # Lint
ktlint --format       # Auto-format

# detekt — static analysis
# Add to build.gradle.kts:
# plugins { id("io.gitlab.arturbosch.detekt") version "1.23.0" }
./gradlew detekt

# ktfmt — Google's Kotlin formatter
# Alternative to ktlint with Google/Meta style
# detekt.yml
complexity:
  LongMethod:
    threshold: 30
  ComplexCondition:
    threshold: 4
style:
  MaxLineLength:
    maxLineLength: 120
  WildcardImport:
    active: true
// build.gradle.kts — Spotless plugin (multi-formatter)
plugins {
    id("com.diffplug.spotless") version "6.25.0"
}
spotless {
    kotlin {
        ktlint()
        target("src/**/*.kt")
    }
}
// Run: ./gradlew spotlessApply

Tooling & Formatter/Linter

Python has mature formatting and linting tools. Ruff is rapidly becoming the standard for both.

# Ruff — extremely fast linter + formatter (Rust-based)
pip install ruff
ruff check .          # Lint
ruff format .         # Format
ruff check --fix .    # Auto-fix

# Black — opinionated formatter
pip install black
black .

# isort — import sorting (built into Ruff)
pip install isort
isort .

# mypy — static type checker
pip install mypy
mypy src/

# pyright — fast type checker (Microsoft)
pip install pyright
pyright
# pyproject.toml
[tool.ruff]
line-length = 100
target-version = "py312"

[tool.ruff.lint]
select = ["E", "F", "I", "N", "UP", "B"]

[tool.mypy]
strict = true

Build & Compile Model

Interpreted / JIT-compiled. JavaScript is parsed and JIT-compiled at runtime by the engine (V8, SpiderMonkey, JavaScriptCore).

# No compile step — run directly
node app.js
deno run app.js
bun run app.js

# Bundling for browsers (not compilation, but required)
npx vite build         # Vite (esbuild + Rollup)
npx esbuild app.js --bundle --outfile=out.js
npx webpack            # webpack

# Output: .js bundles, source maps
# No binary output — always JavaScript

Execution model:

  • Source → Parse → AST → Bytecode → JIT machine code
  • V8 uses TurboFan (optimizing compiler) and Sparkplug (baseline)
  • No ahead-of-time compilation (except experimental with Hermes, QuickJS)
  • Tree-shaking and dead-code elimination happen at bundle time, not compile time

Build & Compile Model

Transpiled to JavaScript, then interpreted/JIT. TypeScript is compiled to JS by tsc, or stripped/transpiled by faster tools.

# tsc — official compiler (type-check + emit JS)
npx tsc                    # Compile project
npx tsc --noEmit           # Type-check only (no output)
npx tsc --watch            # Watch mode

# Faster alternatives (strip types, no type-checking)
npx esbuild src/index.ts --bundle --outfile=out.js
npx tsup src/index.ts      # Library bundler
npx tsx src/index.ts        # Run directly (no build)

# Output: .js + .d.ts (type declarations) + .js.map

Execution model:

  • TypeScript → JavaScript (types erased) → Engine JIT
  • tsc performs full type checking but is slow for large projects
  • Most build tools (esbuild, SWC, Bun) only strip types — no type checking
  • --isolatedDeclarations enables parallel .d.ts generation
  • Node.js 22+ can run .ts files directly (type stripping)

Build & Compile Model

Interpreted with optional OPcache. PHP scripts are compiled to bytecode at runtime. OPcache stores precompiled bytecode in shared memory.

# No compile step — run directly
php app.php

# Built-in web server (development)
php -S localhost:8000 -t public

# Production — typically served via PHP-FPM + Nginx/Apache
# PHP-FPM compiles and caches bytecode via OPcache

# Check OPcache status
php -r "var_dump(opcache_get_status());"

Execution model:

  • Source → Lexer → Parser → AST → Opcodes → Zend VM execution
  • OPcache: Stores compiled opcodes in shared memory (skip parse/compile on each request)
  • JIT compiler (PHP 8.0+): Compiles hot opcodes to machine code via DynASM
  • Preloading (PHP 7.4+): Load files into memory at server start
  • No standalone binary output — always requires PHP runtime
  • RoadRunner / FrankenPHP: Keep PHP workers alive between requests (no per-request boot)

Build & Compile Model

Interpreted. Ruby code is parsed into an AST, compiled to bytecode, and executed by YARV (Yet Another Ruby VM). JIT compilation available since Ruby 2.6.

# No compile step — run directly
ruby app.rb

# Ruby with JIT (YJIT — default since Ruby 3.3)
ruby --yjit app.rb

# Check if YJIT is enabled
ruby -e "puts RubyVM::YJIT.enabled?"

# MJIT (older JIT, deprecated in 3.3)
ruby --mjit app.rb

# Precompile to bytecode (for inspection)
ruby --dump=insns script.rb

Execution model:

  • Source → Lexer → Parser → AST → YARV bytecode → VM execution
  • YJIT (Ruby 3.1+): Lazy Basic Block Versioning JIT compiler, written in Rust
  • YJIT is enabled by default in Ruby 3.3+ and gives 15-25% speedup for Rails apps
  • mruby: Lightweight Ruby for embedded systems
  • TruffleRuby: GraalVM-based implementation with aggressive JIT
  • JRuby: Ruby on the JVM — true threads, Java interop

Build & Compile Model

Ahead-of-time compiled to native binary. Go compiles directly to machine code. No VM, no runtime dependency.

# Compile and run
go run main.go           # Compile + run in one step
go build -o myapp .      # Compile to binary
./myapp                  # Run the binary

# Release build
go build -ldflags="-s -w" -o myapp .  # Strip debug info

# Cross-compilation (built-in!)
GOOS=linux GOARCH=amd64 go build -o myapp-linux .
GOOS=darwin GOARCH=arm64 go build -o myapp-mac .
GOOS=windows GOARCH=amd64 go build -o myapp.exe .

# Output: single static binary (no dependencies)

Execution model:

  • Source → AST → SSA IR → Machine code (single binary)
  • Compilation is extremely fast (seconds for large projects)
  • Statically linked by default — one binary, zero dependencies
  • Includes a small runtime (goroutine scheduler, GC) in the binary
  • No JIT — all optimization happens at compile time

Build & Compile Model

Ahead-of-time compiled to native binary via LLVM. Rust produces highly optimized machine code with zero-cost abstractions.

# Debug build (fast compile, slow runtime)
cargo build
./target/debug/myapp

# Release build (slow compile, fast runtime)
cargo build --release
./target/release/myapp

# Compile + run
cargo run
cargo run --release

# Cross-compilation
rustup target add x86_64-unknown-linux-musl
cargo build --target x86_64-unknown-linux-musl --release

# Check without building (fastest feedback)
cargo check

# Output: native binary, or .rlib/.so/.a for libraries

Execution model:

  • Source → HIR → MIR (borrow checking) → LLVM IR → Machine code
  • No runtime, no GC — zero-cost abstractions
  • Compile times are slower than Go/C due to deep optimization + borrow checker
  • Incremental compilation and sccache help with rebuild speed
  • Can target WASM: cargo build --target wasm32-unknown-unknown

Build & Compile Model

Ahead-of-time compiled to native binary. C++ compiles through a preprocessor → compiler → assembler → linker pipeline.

# Direct compilation
g++ -std=c++20 -O2 -o myapp main.cpp
clang++ -std=c++20 -O2 -o myapp main.cpp

# With CMake (standard build system)
cmake -B build -DCMAKE_BUILD_TYPE=Release
cmake --build build
./build/myapp

# Compile steps (explicit)
g++ -c main.cpp -o main.o    # Compile to object file
g++ main.o -o myapp           # Link

# Cross-compilation
x86_64-linux-gnu-g++ -o myapp main.cpp

# Output: native binary, .o object files, .a/.so libraries

Execution model:

  • Source → Preprocessor (#include expansion) → Compiler → Assembly → Object files → Linker → Binary
  • Headers are textually included (slow — modules in C++20 help)
  • Template instantiation happens at compile time (can be slow)
  • No runtime, no GC — manual memory or RAII
  • Link-time optimization (LTO) can significantly improve performance

Build & Compile Model

Compiled to IL (Intermediate Language), then JIT or AOT compiled. C# targets the .NET runtime (CLR).

# Build (compiles to IL in .dll)
dotnet build
dotnet build -c Release

# Run (JIT compiles IL to native at runtime)
dotnet run

# Publish — framework-dependent (needs .NET installed)
dotnet publish -c Release

# Publish — self-contained (includes runtime)
dotnet publish -c Release --self-contained -r linux-x64

# Native AOT (ahead-of-time, .NET 8+)
dotnet publish -c Release -r linux-x64 /p:PublishAot=true
# Output: single native binary, no .NET runtime needed

Execution model:

  • Source → Roslyn compiler → IL (.dll) → JIT (RyuJIT) → Machine code
  • JIT compilation happens at runtime, method by method
  • Native AOT eliminates JIT — compiles directly to native binary
  • Tiered compilation: quick JIT first, re-optimize hot paths
  • ReadyToRun (R2R) pre-compiles IL for faster startup

Build & Compile Model

Ahead-of-time compiled via LLVM. Swift compiles to native code. Apps can also use the Swift runtime for dynamic features.

# Compile a single file
swiftc hello.swift -o hello

# Build with SPM
swift build                   # Debug
swift build -c release        # Release

# Run
swift run

# Xcode build
xcodebuild -scheme MyApp -configuration Release build

# Output: native binary (macOS/Linux), .app bundle (macOS/iOS)

Execution model:

  • Source → SIL (Swift Intermediate Language) → LLVM IR → Machine code
  • Whole-module optimization (-whole-module-optimization) for release builds
  • Swift runtime is included in the OS on Apple platforms (since iOS 12.2)
  • On Linux, the Swift runtime is bundled with the binary
  • Supports both static and dynamic linking
  • Incremental compilation for fast debug builds

Build & Compile Model

Compiled to JVM bytecode (default), or native/JS. Kotlin targets multiple backends via the Kotlin compiler.

# Compile to JVM bytecode
kotlinc hello.kt -include-runtime -d hello.jar
java -jar hello.jar

# Build with Gradle
./gradlew build
./gradlew run

# Kotlin/Native — compile to native binary (no JVM)
# Uses Kotlin/Native compiler (LLVM-based)
# Output: native executable

# Kotlin/JS — compile to JavaScript
# Output: .js files for browser or Node.js

# Kotlin Multiplatform — shared code across targets
./gradlew :shared:build

Execution model:

  • JVM: Source → Kotlin IR → JVM bytecode (.class/.jar) → JIT (HotSpot)
  • Native: Source → Kotlin IR → LLVM IR → Machine code
  • JS: Source → Kotlin IR → JavaScript
  • WASM: Source → Kotlin IR → WebAssembly (experimental)
  • JVM target benefits from HotSpot JIT, tiered compilation, and GC
  • Gradle build can be slow — use build cache and configuration cache

Build & Compile Model

Interpreted with bytecode compilation. Python compiles source to bytecode (.pyc), then executes on the CPython VM.

# No explicit compile step — run directly
python3 app.py

# Bytecode is auto-cached in __pycache__/
# Force compile all files
python3 -m compileall src/

# PyInstaller — bundle into standalone executable
pip install pyinstaller
pyinstaller --onefile app.py
# Output: dist/app (single binary)

# Nuitka — compile to C, then native binary
pip install nuitka
nuitka --standalone app.py

# Cython — compile Python to C extension modules
cython module.pyx

Execution model:

  • Source → Bytecode (.pyc) → CPython VM interpreter
  • CPython has a GIL (Global Interpreter Lock) — one thread executes Python at a time
  • Alternative runtimes: PyPy (JIT), GraalPy, Cython (AOT to C)
  • Python 3.13+ has experimental free-threaded mode (no GIL)
  • No static binary output by default — requires third-party tools

Libraries & Frameworks

JavaScript has an enormous ecosystem. Key libraries and frameworks by category:

Web Frameworks - React, Vue, Svelte, Angular, Solid, Astro, Next.js, Nuxt, SvelteKit, Remix

Server / API - Express, Fastify, Hono, Koa, Nest.js, tRPC

Build Tools - Vite, esbuild, Rollup, webpack, Turbopack, Parcel

State Management - Zustand, Jotai, Redux Toolkit, Pinia (Vue), Signals

Styling - Tailwind CSS, Styled Components, CSS Modules, UnoCSS

Databases / ORM - Prisma, Drizzle, Mongoose, Knex, TypeORM

Utilities - Lodash, date-fns, Zod, Axios, Ramda

Testing - Vitest, Jest, Playwright, Cypress, Testing Library

Desktop - Electron, Tauri

Mobile - React Native, Expo, Capacitor, NativeScript

Libraries & Frameworks

TypeScript uses the same ecosystem as JavaScript. These libraries are TypeScript-first or have excellent type support:

Type-First Libraries - Zod (schema validation), tRPC (end-to-end typesafe APIs), Drizzle ORM, Effect, ts-pattern

Web Frameworks - Next.js, Nuxt, SvelteKit, Remix, Astro, Hono - all have first-class TS support

Full-Stack - T3 Stack (Next.js + tRPC + Prisma + Tailwind), Blitz.js, RedwoodJS

Runtime/Build - tsx, tsup, unbuild, Vite, esbuild

State Management - Zustand, Jotai, XState - all TypeScript-first

Validation - Zod, Valibot, ArkType, io-ts, Yup

API Clients - Axios, ky, openapi-typescript, GraphQL Code Generator

Type Utilities - type-fest, ts-essentials, utility-types

Testing - Vitest, Jest, Playwright - all TypeScript-native

Libraries & Frameworks

Libraries & Frameworks

Libraries & Frameworks

Go has a rich standard library and a growing ecosystem focused on cloud, networking, and backend services.

Web Frameworks - Gin, Echo, Fiber, Chi, net/http (stdlib)

API / RPC - gRPC, Connect, Twirp, OpenAPI generators

Databases - GORM, sqlx, pgx, ent, database/sql (stdlib)

Cloud / Infra - Docker, Kubernetes client-go, Terraform Plugin Framework, AWS SDK

CLI - Cobra, urfave/cli, Bubble Tea (TUI), Charm tools

Logging - slog (stdlib), Zap, zerolog, logrus

Config - Viper, envconfig, koanf

Testing - testify, gomock, ginkgo, go-cmp

Concurrency - errgroup, semaphore (x/sync), conc

Serialization - encoding/json (stdlib), json-iterator, protobuf

HTTP Clients - net/http (stdlib), resty, req

Libraries & Frameworks

Rust’s ecosystem is centered on crates.io. Strong focus on performance, safety, and systems programming.

Web Frameworks - Actix Web, Axum, Rocket, Warp, Poem

Async Runtime - Tokio, async-std, smol

Serialization - serde, serde_json, bincode, postcard

Databases - SQLx, Diesel, SeaORM, rusqlite

CLI - clap, structopt, dialoguer, indicatif, ratatui (TUI)

Error Handling - anyhow, thiserror, eyre, miette

HTTP Clients - reqwest, hyper, ureq

Logging - tracing, log, env_logger

Concurrency - rayon, crossbeam, tokio, parking_lot

Crypto - ring, rustls, rust-crypto

WASM - wasm-bindgen, wasm-pack, Leptos, Yew, Dioxus

Embedded - embedded-hal, embassy, probe-rs

Libraries & Frameworks

C++ has a vast ecosystem spanning systems, games, embedded, and high-performance computing.

Standard Library - STL, containers, algorithms, iterators, ranges, <format>, <filesystem>

GUI / Graphics - Qt, Dear ImGui, SDL, SFML, wxWidgets, GLFW

Game Engines - Unreal Engine, Godot, Cocos2d-x

Networking - Boost.Asio, cpp-httplib, libcurl, gRPC

Serialization - nlohmann/json, protobuf, cereal, MessagePack

Databases - SQLite (C API), SOCI, libpq, sqlpp11

Build Systems - CMake, Meson, Bazel, xmake

Package Managers - vcpkg, Conan, CPM.cmake

Testing - Google Test, Catch2, Doctest, Boost.Test

Concurrency - std::thread, std::async, Intel TBB, OpenMP

Math / Science - Eigen, Armadillo, BLAS/LAPACK, OpenCV

Embedded - Arduino, ESP-IDF, Zephyr, mbed

Libraries & Frameworks

C# has a mature ecosystem centered around .NET and NuGet. Strong in enterprise, web, games, and desktop.

Web Frameworks - ASP.NET Core, Minimal APIs, Blazor (WASM), Carter

Desktop / UI - WPF, WinUI 3, MAUI, Avalonia, WinForms

Game Development - Unity, Godot (C# support), MonoGame, Stride

ORM / Data - Entity Framework Core, Dapper, LINQ to DB, NHibernate

API / Communication - gRPC, SignalR, MassTransit, MediatR, Refit

Serialization - System.Text.Json, Newtonsoft.Json, MessagePack

Logging - Serilog, NLog, Microsoft.Extensions.Logging

Testing - xUnit, NUnit, FluentAssertions, Moq, NSubstitute, Bogus

Cloud - Azure SDK, AWS SDK, Pulumi

CLI - System.CommandLine, Spectre.Console, Cocona

DI / IoC - Microsoft.Extensions.DependencyInjection, Autofac

Libraries & Frameworks

Libraries & Frameworks

Kotlin has access to the entire Java ecosystem plus Kotlin-specific libraries. Strong in Android, server, and multiplatform.

Android - Jetpack Compose, Android KTX, Hilt (DI), Room, Navigation, Lifecycle

Server - Ktor, Spring Boot (Kotlin support), Micronaut, http4k, Javalin

Multiplatform - Kotlin Multiplatform (KMP), Compose Multiplatform, KMM

Coroutines - kotlinx.coroutines, Flow, Channels

Serialization - kotlinx.serialization, Moshi, Gson (Java)

Networking - Ktor Client, OkHttp, Retrofit

Databases - Exposed, SQLDelight, Room (Android), ktorm

DI - Koin, Hilt (Android), Kodein

Testing - JUnit 5, Kotest, MockK, Turbine (Flow testing)

Build - Gradle Kotlin DSL, Amper (experimental)

Desktop - Compose for Desktop, TornadoFX

Functional - Arrow (FP library), kotlin-result

Libraries & Frameworks

Python has a vast ecosystem spanning web, data science, machine learning, and automation.

Web Frameworks - Django, Flask, FastAPI, Starlette, Litestar

Data Science - NumPy, Pandas, Polars, SciPy, Matplotlib, Seaborn, Plotly

Machine Learning - scikit-learn, PyTorch, TensorFlow, Keras, Hugging Face Transformers, JAX

LLM / AI - LangChain, LlamaIndex, OpenAI SDK, Anthropic SDK

HTTP / API - Requests, httpx, aiohttp, urllib3

Databases / ORM - SQLAlchemy, Django ORM, Tortoise ORM, Peewee, databases

CLI - Click, Typer, argparse, Rich

Async - asyncio, trio, anyio, uvloop

Testing - pytest, unittest, hypothesis, coverage

DevOps / Automation - Fabric, Ansible, Boto3 (AWS), Celery

Type Checking - mypy, pyright, Pydantic

Testing

Popular testing frameworks include Vitest, Jest, and the built-in Node.js test runner. Playwright and Cypress are used for end-to-end testing.

// Vitest (recommended — fast, Vite-native)
import { describe, it, expect } from 'vitest'

describe('math', () => {
  it('adds numbers', () => {
    expect(1 + 2).toBe(3)
  })

  it('handles arrays', () => {
    expect([1, 2, 3]).toContain(2)
    expect([1, 2, 3]).toHaveLength(3)
  })
})
// Node.js built-in test runner (v18+)
import { describe, it } from 'node:test'
import assert from 'node:assert'

describe('math', () => {
  it('adds numbers', () => {
    assert.strictEqual(1 + 2, 3)
  })
})
# Run tests
npx vitest           # Vitest (watch mode)
npx vitest run       # Vitest (single run)
npx jest             # Jest
node --test          # Node.js built-in

# E2E testing
npx playwright test  # Playwright
npx cypress run      # Cypress

Testing

Same testing tools as JavaScript — Vitest and Jest work natively with TypeScript. Type-level testing is also possible.

// Vitest with TypeScript (zero config)
import { describe, it, expect } from 'vitest'

function add(a: number, b: number): number {
  return a + b
}

describe('add', () => {
  it('adds two numbers', () => {
    expect(add(1, 2)).toBe(3)
  })

  it('returns a number', () => {
    const result: number = add(1, 2)
    expect(typeof result).toBe('number')
  })
})
// Type-level testing with expectTypeOf (Vitest)
import { expectTypeOf } from 'vitest'

expectTypeOf(add).toBeFunction()
expectTypeOf(add).parameter(0).toBeNumber()
expectTypeOf(add).returns.toBeNumber()
# Run tests
npx vitest           # Vitest (watch mode)
npx jest             # Jest (needs ts-jest or @swc/jest)
node --test          # Node.js built-in (with tsx loader)

# Type-check as a test step
npx tsc --noEmit

Testing

PHPUnit is the standard testing framework. Pest provides a more expressive syntax.

// PHPUnit
use PHPUnit\Framework\TestCase;

class MathTest extends TestCase
{
    public function testAddition(): void
    {
        $this->assertEquals(3, 1 + 2);
        $this->assertTrue(true);
        $this->assertCount(3, [1, 2, 3]);
    }

    public function testException(): void
    {
        $this->expectException(\InvalidArgumentException::class);
        throw new \InvalidArgumentException('bad input');
    }
}
// Pest — expressive testing framework
test('addition works', function () {
    expect(1 + 2)->toBe(3);
});

it('handles arrays', function () {
    expect([1, 2, 3])->toContain(2)->toHaveCount(3);
});
# Run tests
./vendor/bin/phpunit
./vendor/bin/pest

# With coverage
./vendor/bin/phpunit --coverage-text
XDEBUG_MODE=coverage ./vendor/bin/pest --coverage

Testing

RSpec and Minitest are the two main testing frameworks. RSpec is more popular in the Rails community.

# RSpec
RSpec.describe 'Math' do
  it 'adds numbers' do
    expect(1 + 2).to eq(3)
  end

  it 'handles arrays' do
    expect([1, 2, 3]).to include(2)
    expect([1, 2, 3]).to have_attributes(length: 3)
  end

  context 'with negative numbers' do
    it 'returns negative sum' do
      expect(-1 + -2).to eq(-3)
    end
  end
end
# Minitest
require 'minitest/autorun'

class MathTest < Minitest::Test
  def test_addition
    assert_equal 3, 1 + 2
  end

  def test_array_includes
    assert_includes [1, 2, 3], 2
  end
end
# Run tests
bundle exec rspec                # RSpec
bundle exec rspec spec/models/   # Specific directory
ruby -Itest test/math_test.rb    # Minitest
bundle exec rails test           # Rails default (Minitest)

# With coverage
# Add simplecov gem, then: COVERAGE=true bundle exec rspec

Testing

Go has a built-in testing framework in the testing package. No external dependencies needed. testify is a popular assertion library.

// math_test.go — test files end in _test.go
package math

import "testing"

func TestAdd(t *testing.T) {
    result := Add(1, 2)
    if result != 3 {
        t.Errorf("Add(1, 2) = %d; want 3", result)
    }
}

// Table-driven tests (idiomatic Go pattern)
func TestAddTable(t *testing.T) {
    tests := []struct {
        a, b, want int
    }{
        {1, 2, 3},
        {0, 0, 0},
        {-1, 1, 0},
    }
    for _, tt := range tests {
        got := Add(tt.a, tt.b)
        if got != tt.want {
            t.Errorf("Add(%d, %d) = %d, want %d",
                tt.a, tt.b, got, tt.want)
        }
    }
}

// Benchmarks
func BenchmarkAdd(b *testing.B) {
    for i := 0; i < b.N; i++ {
        Add(1, 2)
    }
}
# Run tests
go test ./...           # All packages
go test -v ./...        # Verbose
go test -run TestAdd    # Specific test
go test -bench .        # Run benchmarks
go test -cover          # With coverage
go test -race ./...     # Race condition detection

Testing

Rust has built-in testing support — no external framework needed. Tests live alongside code or in a tests/ directory.

// Unit tests — in the same file as the code
pub fn add(a: i32, b: i32) -> i32 {
    a + b
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_add() {
        assert_eq!(add(1, 2), 3);
    }

    #[test]
    fn test_add_negative() {
        assert_eq!(add(-1, 1), 0);
    }

    #[test]
    #[should_panic(expected = "overflow")]
    fn test_overflow() {
        let _: u8 = 255u8 + 1; // panics in debug mode
    }
}
// Integration tests — in tests/ directory
// tests/integration_test.rs
use my_crate::add;

#[test]
fn it_adds() {
    assert_eq!(add(2, 3), 5);
}
# Run tests
cargo test              # All tests
cargo test test_add     # Specific test
cargo test -- --nocapture  # Show println! output
cargo test --doc        # Doc tests only
cargo bench             # Benchmarks (nightly)

Testing

No built-in testing framework. Google Test (gtest) and Catch2 are the most popular. Doctest is a lightweight alternative.

// Google Test
#include <gtest/gtest.h>

TEST(MathTest, Addition) {
    EXPECT_EQ(1 + 2, 3);
}

TEST(MathTest, Negative) {
    EXPECT_EQ(-1 + 1, 0);
    EXPECT_GT(5, 3);
    EXPECT_TRUE(true);
}

// Parameterized tests
class AddTest : public ::testing::TestWithParam<
    std::tuple<int, int, int>> {};

TEST_P(AddTest, AddsCorrectly) {
    auto [a, b, expected] = GetParam();
    EXPECT_EQ(a + b, expected);
}

INSTANTIATE_TEST_SUITE_P(Math, AddTest,
    ::testing::Values(
        std::make_tuple(1, 2, 3),
        std::make_tuple(0, 0, 0)
    ));
// Catch2 — header-only, no macros
#include <catch2/catch_test_macros.hpp>

TEST_CASE("Addition works", "[math]") {
    REQUIRE(1 + 2 == 3);

    SECTION("with negatives") {
        REQUIRE(-1 + 1 == 0);
    }
}
# Run tests (with CMake + CTest)
cmake -B build && cmake --build build
cd build && ctest --output-on-failure

Testing

Popular frameworks: xUnit (most popular), NUnit, and MSTest. FluentAssertions improves readability. Built-in dotnet test runner.

// xUnit (recommended)
using Xunit;

public class MathTests
{
    [Fact]
    public void Add_ReturnsCorrectSum()
    {
        Assert.Equal(3, 1 + 2);
    }

    [Theory]
    [InlineData(1, 2, 3)]
    [InlineData(0, 0, 0)]
    [InlineData(-1, 1, 0)]
    public void Add_WithVariousInputs(int a, int b, int expected)
    {
        Assert.Equal(expected, a + b);
    }
}
// FluentAssertions — readable assertions
using FluentAssertions;

[Fact]
public void List_Should_Contain_Item()
{
    var list = new[] { 1, 2, 3 };
    list.Should().Contain(2);
    list.Should().HaveCount(3);
}
# Run tests
dotnet test                    # All tests
dotnet test --filter "Add"     # Specific tests
dotnet test --collect:"XPlat Code Coverage"  # With coverage
dotnet test --logger "console;verbosity=detailed"

Testing

Swift has a built-in testing framework: Swift Testing (new, from Swift 5.9+) and XCTest (traditional). Both integrate with Xcode and SPM.

// Swift Testing (modern, recommended)
import Testing

@Test func addition() {
    #expect(1 + 2 == 3)
}

@Test("Addition with negatives")
func negativeAddition() {
    #expect(-1 + 1 == 0)
}

// Parameterized tests
@Test(arguments: [
    (1, 2, 3),
    (0, 0, 0),
    (-1, 1, 0),
])
func add(a: Int, b: Int, expected: Int) {
    #expect(a + b == expected)
}
// XCTest (traditional)
import XCTest

class MathTests: XCTestCase {
    func testAdd() {
        XCTAssertEqual(1 + 2, 3)
    }

    func testPerformance() {
        measure {
            // Code to benchmark
        }
    }
}
# Run tests
swift test                    # SPM projects
swift test --filter MathTests # Specific test
# In Xcode: Cmd+U to run all tests
# In Xcode: Click diamond next to test to run individually

Testing

JUnit 5 is the standard. Kotest is a Kotlin-native alternative with expressive DSLs. MockK is the preferred mocking library.

// JUnit 5 with Kotlin
import org.junit.jupiter.api.Test
import org.junit.jupiter.api.Assertions.*

class MathTest {
    @Test
    fun `adds two numbers`() {
        assertEquals(3, 1 + 2)
    }

    @Test
    fun `list contains element`() {
        val list = listOf(1, 2, 3)
        assertTrue(2 in list)
        assertEquals(3, list.size)
    }
}

// Parameterized tests
import org.junit.jupiter.params.ParameterizedTest
import org.junit.jupiter.params.provider.CsvSource

class ParameterizedMathTest {
    @ParameterizedTest
    @CsvSource("1,2,3", "0,0,0", "-1,1,0")
    fun `adds correctly`(a: Int, b: Int, expected: Int) {
        assertEquals(expected, a + b)
    }
}
// Kotest — Kotlin-native testing framework
import io.kotest.core.spec.style.StringSpec
import io.kotest.matchers.shouldBe
import io.kotest.matchers.collections.shouldContain

class MathSpec : StringSpec({
    "addition works" {
        (1 + 2) shouldBe 3
    }

    "list contains element" {
        listOf(1, 2, 3) shouldContain 2
    }
})
# Run tests
./gradlew test                          # All tests
./gradlew test --tests "MathTest"       # Specific class
./gradlew test --tests "*adds*"         # Pattern match

Testing

pytest is the de facto standard. Python also includes unittest in the standard library. hypothesis provides property-based testing.

# pytest (recommended)
def test_addition():
    assert 1 + 2 == 3

def test_list_contains():
    assert 2 in [1, 2, 3]

# Fixtures for setup/teardown
import pytest

@pytest.fixture
def sample_list():
    return [1, 2, 3]

def test_length(sample_list):
    assert len(sample_list) == 3

# Parametrize — run test with multiple inputs
@pytest.mark.parametrize("a,b,expected", [
    (1, 2, 3),
    (0, 0, 0),
    (-1, 1, 0),
])
def test_add(a, b, expected):
    assert a + b == expected
# unittest (standard library)
import unittest

class TestMath(unittest.TestCase):
    def test_add(self):
        self.assertEqual(1 + 2, 3)
# Run tests
pytest                  # pytest (auto-discovers tests)
pytest -v               # Verbose output
pytest --cov=mypackage  # With coverage
python -m unittest      # Standard library

Debugging

Chrome DevTools for browser, Node.js inspector for server. console methods and debugger statement.

// console methods
console.log('basic log')
console.error('error message')
console.warn('warning')
console.table([{ name: 'Alice', age: 30 }])
console.dir(obj, { depth: null })
console.time('op'); doWork(); console.timeEnd('op')
console.trace('call stack')
console.group('section'); /* ... */ console.groupEnd()

// debugger statement — triggers breakpoint
function processData(data) {
  debugger  // Pauses here if DevTools is open
  return data.map(transform)
}
# Node.js debugging
node --inspect app.js          # Start with inspector
node --inspect-brk app.js     # Break on first line
# Open chrome://inspect in Chrome

# VS Code — built-in debugger
# launch.json:
{
  "type": "node",
  "request": "launch",
  "program": "${workspaceFolder}/src/index.js",
  "console": "integratedTerminal"
}
# Set breakpoints by clicking gutter
# F5 to start, F10 step over, F11 step into

# Chrome DevTools
# Sources tab: breakpoints, watch, call stack
# Network tab: request/response inspection
# Console tab: live REPL in page context
# Elements tab: DOM inspection

# ndb — improved Node.js debugging
npx ndb node app.js

Debugging

Same tools as JavaScript. Source maps enable debugging TypeScript directly. VS Code has first-class TS debugging support.

# Source maps — map compiled JS back to TS
# tsconfig.json: "sourceMap": true

# VS Code debugging (recommended)
# launch.json:
{
  "type": "node",
  "request": "launch",
  "program": "${workspaceFolder}/src/index.ts",
  "runtimeExecutable": "tsx",
  "console": "integratedTerminal"
}

# Or with ts-node
{
  "type": "node",
  "request": "launch",
  "runtimeArgs": ["-r", "ts-node/register"],
  "args": ["${workspaceFolder}/src/index.ts"]
}

# Chrome DevTools — works with source maps
node --inspect -r tsx/cjs src/index.ts
// Type-narrowing aids debugging
function process(input: string | number) {
  if (typeof input === 'string') {
    // TypeScript knows input is string here
    console.log(input.toUpperCase())
  }
}

// satisfies — catch type errors without changing runtime
const config = {
  port: 3000,
  host: 'localhost',
} satisfies Record<string, string | number>

// // @ts-expect-error — document expected errors
// @ts-expect-error — testing invalid input
process(null)

Debugging

Xdebug is the primary debugger. Laravel has Telescope and Debugbar for web debugging.

// Basic debugging
var_dump($variable);       // Type + value
print_r($array);           // Human-readable array
echo gettype($variable);   // Type name
debug_print_backtrace();   // Stack trace

// Error reporting
error_reporting(E_ALL);
ini_set('display_errors', '1');

// Logging
error_log('Something happened');
error_log(print_r($data, true));  // Log complex data
# Xdebug — install and configure
pecl install xdebug

# php.ini configuration
zend_extension=xdebug
xdebug.mode=debug
xdebug.start_with_request=yes
xdebug.client_port=9003

# VS Code — install "PHP Debug" extension
# launch.json:
{
  "type": "php",
  "request": "launch",
  "name": "Listen for Xdebug",
  "port": 9003
}

# Laravel Telescope — request/job/query inspector
composer require laravel/telescope
php artisan telescope:install

# Laravel Debugbar
composer require barryvdh/laravel-debugbar --dev
# Automatically shows debug info in browser

Debugging

debug gem (Ruby 3.1+ built-in) and Pry are the primary debugging tools.

# Built-in debug gem (Ruby 3.1+)
require 'debug'

def process(data)
  binding.break  # Breakpoint — opens debugger
  data.map { |x| x * 2 }
end

# Pry — enhanced REPL debugger
require 'pry'

def process(data)
  binding.pry  # Breakpoint — opens Pry session
  data.map { |x| x * 2 }
end

# Basic debugging
puts variable.inspect
p variable              # Shorthand for puts .inspect
pp complex_object       # Pretty print
warn "debug message"    # Print to stderr
# debug gem commands (at breakpoint)
# n / next      — step over
# s / step      — step into
# c / continue  — continue execution
# bt            — backtrace
# info          — show local variables
# eval expr     — evaluate expression

# Start script in debug mode
ruby -r debug script.rb
rdbg script.rb

# VS Code — install "Ruby LSP" extension
# launch.json:
{
  "type": "ruby_lsp",
  "request": "launch",
  "program": "${workspaceFolder}/app.rb"
}

# Byebug (older, still used)
gem install byebug
# require 'byebug'; byebug  # in code

Debugging

Delve is the standard Go debugger. Built-in log and fmt for print debugging. VS Code and GoLand have GUI support.

// Print debugging
fmt.Println("debug:", value)
fmt.Printf("type: %T, value: %+v\n", obj, obj)

// log package — timestamped output
import "log"
log.Println("starting server")
log.Printf("request: %+v", req)
log.Fatal("cannot start")  // Logs then os.Exit(1)

// slog — structured logging (Go 1.21+)
import "log/slog"
slog.Info("request", "method", r.Method, "path", r.URL.Path)
slog.Error("failed", "err", err, "user_id", id)
# Delve — Go debugger
go install github.com/go-delve/delve/cmd/dlv@latest

# Start debugging
dlv debug                 # Debug current package
dlv debug ./cmd/myapp     # Debug specific package
dlv test                  # Debug tests
dlv attach <pid>          # Attach to running process

# Delve commands:
# break main.go:42  (set breakpoint)
# continue           (run to breakpoint)
# next               (step over)
# step               (step into)
# print expr         (evaluate expression)
# goroutines         (list goroutines)
# stack              (show call stack)

# VS Code — built-in Go debugging
# Install Go extension, F5 to debug
# Breakpoints, watch, goroutine inspection

# GoLand (JetBrains) — built-in debugger
# Click gutter, Shift+F9 to debug

Debugging

Use LLDB or GDB for debugging. The compiler provides excellent error messages. dbg!() macro for quick inspection.

// dbg! macro — print expression + value + file:line
let x = 42;
dbg!(x);        // [src/main.rs:3] x = 42
dbg!(x * 2);    // [src/main.rs:4] x * 2 = 84

// println! for basic output
println!("value: {:?}", my_struct);   // Debug format
println!("value: {:#?}", my_struct);  // Pretty-print

// eprintln! — print to stderr
eprintln!("error: {}", msg);

// tracing — structured logging
use tracing::{info, warn, error, debug, instrument};

#[instrument]
fn process(id: u32) {
    info!(id, "processing");
    debug!(?some_value, "details");
    error!(%err, "failed");
}
# LLDB (default on macOS, works on Linux)
lldb target/debug/myapp
# b main.rs:42    (breakpoint)
# r                (run)
# n                (next)
# s                (step into)
# p variable       (print)
# bt               (backtrace)

# GDB
gdb target/debug/myapp
# Same commands but GDB syntax

# VS Code — CodeLLDB extension (recommended)
# launch.json:
{
  "type": "lldb",
  "request": "launch",
  "program": "${workspaceFolder}/target/debug/myapp",
  "args": [],
  "cwd": "${workspaceFolder}"
}
# Set breakpoints, inspect variables, view call stack

# Compiler errors are the first line of debugging
# Rust's error messages include:
# - Exact location, suggested fixes
# - Borrow checker explanations
# cargo clippy for additional warnings

Debugging

GDB and LLDB are the standard debuggers. Compile with -g for debug symbols. Sanitizers catch runtime errors.

# Compile with debug info
g++ -g -O0 -o myapp main.cpp
clang++ -g -O0 -o myapp main.cpp

# GDB
gdb ./myapp
# run                    (start)
# break main.cpp:42      (breakpoint)
# next                   (step over)
# step                   (step into)
# print variable         (inspect)
# backtrace              (call stack)
# watch variable         (data breakpoint)
# info threads           (list threads)
# thread 2               (switch thread)

# LLDB (macOS default)
lldb ./myapp
# Same workflow, slightly different syntax
# b main.cpp:42, r, n, s, p variable, bt
// Print debugging
#include <iostream>
std::cerr << "debug: " << value << std::endl;

// Assertions
#include <cassert>
assert(ptr != nullptr && "pointer must not be null");

// static_assert (compile-time)
static_assert(sizeof(int) == 4, "int must be 4 bytes");
# Sanitizers — catch bugs at runtime
g++ -fsanitize=address -g -o myapp main.cpp    # Memory errors
g++ -fsanitize=undefined -g -o myapp main.cpp  # Undefined behavior
g++ -fsanitize=thread -g -o myapp main.cpp     # Data races

# VS Code — C/C++ extension or CodeLLDB
# CLion (JetBrains) — built-in debugger
# Visual Studio — best Windows C++ debugger

# Valgrind — memory error detection
valgrind --leak-check=full ./myapp

# Core dumps
ulimit -c unlimited
./myapp  # Crashes → generates core file
gdb ./myapp core

Debugging

Visual Studio and Rider have best-in-class debuggers. VS Code with C# extension also works well.

// Debug output
Console.WriteLine($"Value: {value}");
System.Diagnostics.Debug.WriteLine("debug only");

// Debugger.Break() — programmatic breakpoint
if (suspiciousCondition)
    System.Diagnostics.Debugger.Break();

// Logging (Microsoft.Extensions.Logging)
ILogger<MyService> _logger;
_logger.LogInformation("Processing {Id}", item.Id);
_logger.LogError(ex, "Failed to process {Id}", item.Id);
_logger.LogDebug("Details: {@Item}", item); // Structured
# Visual Studio debugging
# F5: Start debugging
# F9: Toggle breakpoint
# F10: Step over, F11: Step into
# Features: conditional breakpoints, hit counts,
# data breakpoints, IntelliTrace, hot reload

# VS Code
# Install C# extension (ms-dotnettools.csharp)
# launch.json auto-generated for .NET projects
# F5 to start debugging

# Rider (JetBrains)
# Built-in debugger with decompilation

# dotnet-dump — analyze crash dumps
dotnet dump collect --process-id <pid>
dotnet dump analyze <dump-file>
# dumpheap, dumpobj, gcroot commands

# dotnet-sos — SOS debugging extension
dotnet tool install -g dotnet-sos
dotnet sos install

# Remote debugging
# Visual Studio: Debug > Attach to Process > SSH

Debugging

Xcode debugger (LLDB-based) is the primary tool. Swift also supports command-line LLDB and VS Code debugging.

// Print debugging
print("value:", value)
print("struct:", myStruct)  // Uses CustomStringConvertible
debugPrint(myStruct)        // Uses CustomDebugStringConvertible
dump(myStruct)              // Deep recursive print

// Assertions and preconditions
assert(index >= 0, "Index must be non-negative")
precondition(array.count > 0, "Array must not be empty")
// assert: removed in release builds
// precondition: kept in release builds

// fatalError — always crashes (useful for unimplemented)
fatalError("Not implemented")

// Logging (os.Logger — Apple Unified Logging)
import os
let logger = Logger(subsystem: "com.app", category: "network")
logger.info("Request started")
logger.error("Failed: \(error.localizedDescription)")
logger.debug("Response: \(data, privacy: .private)")
# Xcode debugging
# Cmd+R: Run, Cmd+Y: Toggle breakpoints
# Click gutter for breakpoints
# Conditional breakpoints, symbolic breakpoints
# Debug navigator: CPU, memory, disk, network
# View debugger: 3D UI hierarchy
# Memory graph debugger: find retain cycles

# LLDB commands in Xcode console
(lldb) po myVariable       # Print object
(lldb) p myInt              # Print value
(lldb) expr myVar = 42     # Modify at runtime
(lldb) bt                   # Backtrace

# Command-line debugging
lldb .build/debug/MyApp
# b main.swift:42, r, n, s, po variable

# VS Code — Swift extension (on Linux/macOS)

Debugging

IntelliJ IDEA and Android Studio have excellent debuggers. Standard JVM debugging tools also apply.

// Print debugging
println("value: $value")
println("struct: $myObject")

// Logging (SLF4J / Logback — JVM standard)
import org.slf4j.LoggerFactory
val logger = LoggerFactory.getLogger(MyClass::class.java)
logger.info("Processing item {}", item.id)
logger.error("Failed", exception)
logger.debug("Details: {}", data)

// kotlin-logging — idiomatic Kotlin wrapper
import io.github.oshai.kotlinlogging.KotlinLogging
val logger = KotlinLogging.logger {}
logger.info { "Processing ${item.id}" }  // Lazy evaluation

// require / check — preconditions
require(age >= 0) { "Age must be non-negative: $age" }
check(isInitialized) { "Must be initialized first" }
// Throws IllegalArgumentException / IllegalStateException
# IntelliJ IDEA / Android Studio
# Shift+F9: Start debugging
# Click gutter for breakpoints
# Features: conditional breakpoints, evaluate expression,
# watches, coroutine debugger, inline variable values

# Coroutine debugging
# IntelliJ shows coroutine stack traces
# -Dkotlinx.coroutines.debug for enhanced output

# Android debugging
# Android Studio > Debug tab
# Layout Inspector: view hierarchy
# Database Inspector: live SQLite queries
# Network Inspector: HTTP traffic

# JVM debugging (command-line)
java -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005 -jar app.jar
# Attach IntelliJ: Run > Attach to Process

# jconsole / VisualVM — JVM monitoring
jconsole  # Memory, threads, MBeans

Debugging

Built-in pdb debugger, enhanced ipdb/pudb, and VS Code/PyCharm GUI debuggers.

# pdb — built-in debugger
import pdb; pdb.set_trace()  # Breakpoint

# Python 3.7+ — built-in breakpoint()
breakpoint()  # Drops into pdb (or configured debugger)

# pdb commands:
# n (next), s (step into), c (continue)
# p expr (print), pp expr (pretty print)
# l (list source), w (where/stack trace)
# b 42 (breakpoint at line 42)
# q (quit)
# Run with debugger
python -m pdb script.py

# ipdb — IPython-enhanced debugger
pip install ipdb
import ipdb; ipdb.set_trace()

# pudb — full-screen TUI debugger
pip install pudb
python -m pudb script.py

# VS Code debugging
# launch.json:
{
  "type": "debugpy",
  "request": "launch",
  "program": "${file}",
  "console": "integratedTerminal"
}
# Click gutter for breakpoints, F5 to start

# PyCharm — built-in debugger
# Click gutter, Shift+F9 to debug

# Logging (prefer over print)
import logging
logging.basicConfig(level=logging.DEBUG)
logger = logging.getLogger(__name__)
logger.debug("Processing %d items", len(items))
logger.error("Failed to connect", exc_info=True)

# Rich — beautiful tracebacks
pip install rich
from rich.traceback import install
install(show_locals=True)

Variables

Use const for immutable bindings and let for mutable ones. var is legacy and function-scoped.

const name = 'Alice';
let age = 30;
var legacy = true; // function-scoped, avoid

// Destructuring
const { x, y } = { x: 1, y: 2 };
const [first, ...rest] = [1, 2, 3];

Variables

Same as JavaScript but with type annotations. Types can be explicit or inferred.

const name: string = 'Alice';
let age: number = 30;

// Type inference (preferred when obvious)
const inferred = 'hello'; // type: string

// Destructuring with types
const { x, y }: { x: number; y: number } = { x: 1, y: 2 };
const [first, ...rest]: number[] = [1, 2, 3];

// Constants with literal types
const direction = 'north' as const; // type: "north"

Variables

Variables start with $. PHP is dynamically typed — no type declaration needed for variables.

$name = 'Alice';
$age = 30;
$isActive = true;
$price = 19.99;

// Constants
const MAX_SIZE = 100;
define('APP_NAME', 'MyApp');

// Variable variables
$varName = 'hello';
$$varName = 'world';  // $hello = 'world'

// Null coalescing
$value = $input ?? 'default';

// Destructuring (list / array)
[$a, $b, $c] = [1, 2, 3];
['name' => $name, 'age' => $age] = ['name' => 'Bob', 'age' => 25];

Variables

Variables don’t need type declarations. Naming conventions indicate scope: local, @instance, @@class, $global, CONSTANT.

# Local variables
name = 'Alice'
age = 30
is_active = true

# Constants (uppercase start)
MAX_SIZE = 100
PI = 3.14159

# Instance variables
@name = 'Alice'

# Class variables
@@count = 0

# Global variables (avoid)
$debug = true

# Multiple assignment
a, b, c = 1, 2, 3
first, *rest = [1, 2, 3, 4]  # first=1, rest=[2,3,4]

# Frozen (immutable) strings
name = 'Alice'.freeze
# name << ' Bob'  # => FrozenError

# String interpolation
greeting = "Hello, #{name}!"

Variables

Use var for explicit declarations or := for short declarations with type inference.

// Short declaration (most common)
name := "Alice"
age := 30

// Explicit var
var count int = 0
var label string

// Multiple declarations
var (
    x int    = 1
    y string = "hello"
)

// Constants
const Pi = 3.14159
const (
    StatusOK    = 200
    StatusNotFound = 404
)

Variables

Variables are immutable by default. Use mut for mutability.

// Immutable (default)
let name = "Alice";
let age = 30;

// Mutable
let mut count = 0;
count += 1;

// Type annotation
let x: i32 = 42;
let pi: f64 = 3.14;

// Shadowing (re-declare with same name)
let x = 5;
let x = x + 1; // x is now 6
let x = "now a string"; // different type

// Constants (must be typed, compile-time)
const MAX_SIZE: usize = 100;

Variables

Use auto for type inference or explicit types. const and constexpr for immutability.

// Auto (type inference, C++11)
auto name = std::string("Alice");
auto age = 30;

// Explicit types
int count = 0;
double pi = 3.14159;
std::string label = "hello";

// Constants
const int maxSize = 100;
constexpr int bufferSize = 1024; // compile-time

// References
int x = 10;
int& ref = x; // reference to x

// Pointers
int* ptr = &x;
auto uptr = std::make_unique<int>(42);

// Structured bindings (C++17)
auto [first, second] = std::make_pair(1, 2);

Variables

Use var for type inference or explicit types. const and readonly for immutability.

// Type inference
var name = "Alice";
var age = 30;

// Explicit types
string label = "hello";
int count = 0;

// Constants (compile-time)
const double Pi = 3.14159;

// Readonly (runtime)
readonly int maxSize = 100;

// Destructuring (tuples)
var (x, y) = (1, 2);

// Nullable types
string? maybeNull = null;
int? maybeInt = null;

Variables

Use let for constants and var for mutable variables. Type inference is the default.

// Constants (immutable)
let name = "Alice"
let age = 30

// Variables (mutable)
var count = 0
count += 1

// Explicit type annotation
let pi: Double = 3.14159
var label: String = "hello"

// Optionals
var maybeValue: String? = nil
maybeValue = "exists"

// Tuple destructuring
let (x, y) = (1, 2)
let point = (x: 10, y: 20)
print(point.x)

Variables

Use val for immutable and var for mutable. Type inference is the default.

// Immutable (val)
val name = "Alice"
val age = 30

// Mutable (var)
var count = 0
count += 1

// Explicit type annotation
val pi: Double = 3.14159
var label: String = "hello"

// Nullable types
var maybeValue: String? = null
maybeValue = "exists"

// Constants (compile-time)
const val MAX_SIZE = 100

// Destructuring
val (x, y) = Pair(1, 2)
val (first, second) = listOf("a", "b")

Variables

Variables are dynamically typed. No declaration keyword needed — just assign.

name = "Alice"
age = 30
is_active = True

# Multiple assignment
x, y, z = 1, 2, 3

# Swap
a, b = b, a

# Constants (convention only, not enforced)
MAX_SIZE = 100

# Type hints (optional, for tooling)
count: int = 0
label: str = "hello"

Types

JavaScript is dynamically typed. Primitives: string, number, boolean, null, undefined, symbol, bigint.

typeof 'hello';    // "string"
typeof 42;         // "number"
typeof true;       // "boolean"
typeof undefined;  // "undefined"
typeof null;       // "object" (legacy bug)
typeof Symbol();   // "symbol"
typeof 42n;        // "bigint"

// Arrays and objects
const arr = [1, 2, 3];
const obj = { key: 'value' };

Types

Rich type system with interfaces, unions, generics, and utility types.

// Primitives
let s: string = 'hello';
let n: number = 42;
let b: boolean = true;

// Interfaces
interface User {
  name: string;
  age: number;
  email?: string; // optional
}

// Union types
type Status = 'active' | 'inactive' | 'pending';

// Generics
function identity<T>(value: T): T {
  return value;
}

// Utility types
type Partial<T> = { [P in keyof T]?: T[P] };
type ReadonlyUser = Readonly<User>;

Types

PHP is dynamically typed but supports type declarations (PHP 7+). Scalar types: string, int, float, bool. Compound: array, object, callable.

// Type declarations (PHP 7+)
function add(int $a, int $b): int {
    return $a + $b;
}

// Union types (PHP 8.0+)
function format(string|int $value): string {
    return (string) $value;
}

// Intersection types (PHP 8.1+)
function process(Countable&Iterator $items): void { }

// Nullable types
function find(?string $name): ?User {
    return $name ? User::find($name) : null;
}

// Type checking
gettype($var);          // 'string', 'integer', etc.
is_string($var);        // true/false
is_int($var);
is_array($var);
$var instanceof MyClass;

// Enums (PHP 8.1+)
enum Color: string {
    case Red = 'red';
    case Blue = 'blue';
    case Green = 'green';
}
$c = Color::Red;
$c->value;  // 'red'

Types

Ruby is dynamically typed. Everything is an object — even integers and booleans. Optional type annotations via RBS or Sorbet.

# Core types — all are objects
42.class          # Integer
3.14.class        # Float
'hello'.class     # String
true.class        # TrueClass
nil.class         # NilClass
:symbol.class     # Symbol
[1, 2].class      # Array
{ a: 1 }.class    # Hash
(1..5).class      # Range

# Type checking
42.is_a?(Integer)     # true
42.is_a?(Numeric)     # true (parent class)
'hi'.respond_to?(:upcase)  # true (duck typing)

# Symbols — immutable, interned strings
:name
:status
:'multi word'

# Ranges
(1..5).to_a       # [1, 2, 3, 4, 5] (inclusive)
(1...5).to_a      # [1, 2, 3, 4] (exclusive)

# RBS — type signature files (Ruby 3.0+)
# sig/app.rbs:
# class User
#   attr_reader name: String
#   def initialize: (String name) -> void
# end

Types

Statically typed with basic types, structs, slices, maps, and interfaces.

// Basic types
var s string = "hello"
var n int = 42
var f float64 = 3.14
var b bool = true

// Structs
type User struct {
    Name  string
    Age   int
    Email string
}

// Slices (dynamic arrays)
nums := []int{1, 2, 3}

// Maps
ages := map[string]int{
    "Alice": 30,
    "Bob":   25,
}

// Interfaces
type Reader interface {
    Read(p []byte) (n int, err error)
}

// Type alias
type ID = string

Types

Statically typed with powerful enums, structs, traits, and generics.

// Primitives
let s: &str = "hello";
let n: i32 = 42;
let f: f64 = 3.14;
let b: bool = true;
let c: char = 'a';

// Structs
struct User {
    name: String,
    age: u32,
    email: Option<String>,
}

// Enums (algebraic data types)
enum Shape {
    Circle(f64),
    Rectangle(f64, f64),
}

// Vectors and HashMaps
let nums: Vec<i32> = vec![1, 2, 3];
let mut map = HashMap::new();
map.insert("key", "value");

// Option and Result
let maybe: Option<i32> = Some(42);
let result: Result<i32, String> = Ok(42);

Types

Statically typed with primitives, classes, templates, and smart pointers.

// Primitives
int n = 42;
double f = 3.14;
bool b = true;
char c = 'a';

// Strings
std::string s = "hello";
std::string_view sv = "view"; // non-owning

// Containers
std::vector<int> nums = {1, 2, 3};
std::map<std::string, int> ages = {
    {"Alice", 30}, {"Bob", 25}
};
std::array<int, 3> fixed = {1, 2, 3};

// Structs / Classes
struct Point { int x; int y; };
class User {
public:
    std::string name;
    int age;
};

// Enums
enum class Color { Red, Green, Blue };

// Optional (C++17)
std::optional<int> maybe = 42;
std::optional<int> empty = std::nullopt;

Types

Statically typed with value types, reference types, generics, and records.

// Value types
int n = 42;
double f = 3.14;
bool b = true;
char c = 'a';

// Reference types
string s = "hello";
int[] arr = { 1, 2, 3 };

// Classes
class User {
    public string Name { get; set; }
    public int Age { get; set; }
}

// Records (immutable by default)
record Point(int X, int Y);

// Enums
enum Color { Red, Green, Blue }

// Generics
List<int> nums = new() { 1, 2, 3 };
Dictionary<string, int> map = new() { ["a"] = 1 };

// Nullable reference types
string? nullable = null;

Types

Statically typed with structs, classes, enums, protocols, and generics.

// Primitives
let s: String = "hello"
let n: Int = 42
let f: Double = 3.14
let b: Bool = true

// Arrays and Dictionaries
let nums: [Int] = [1, 2, 3]
let ages: [String: Int] = ["Alice": 30, "Bob": 25]
let unique: Set<Int> = [1, 2, 3]

// Structs (value types)
struct Point {
    var x: Double
    var y: Double
}

// Enums (with associated values)
enum Shape {
    case circle(radius: Double)
    case rectangle(width: Double, height: Double)
}

// Protocols (like interfaces)
protocol Drawable {
    func draw()
}

// Optionals
let maybe: Int? = 42
let empty: Int? = nil

Types

Statically typed with null safety, data classes, sealed classes, and generics.

// Primitives
val s: String = "hello"
val n: Int = 42
val f: Double = 3.14
val b: Boolean = true

// Collections
val nums: List<Int> = listOf(1, 2, 3)
val mutableNums = mutableListOf(1, 2, 3)
val ages: Map<String, Int> = mapOf("Alice" to 30)
val unique: Set<Int> = setOf(1, 2, 3)

// Data classes
data class User(val name: String, val age: Int)

// Sealed classes (restricted hierarchy)
sealed class Shape {
    data class Circle(val radius: Double) : Shape()
    data class Rect(val w: Double, val h: Double) : Shape()
}

// Enums
enum class Color { RED, GREEN, BLUE }

// Nullable types
val maybe: Int? = null
val sure: Int = 42

Types

Dynamically typed with built-in types: int, float, str, bool, list, dict, tuple, set.

# Primitives
s: str = "hello"
n: int = 42
f: float = 3.14
b: bool = True

# Collections
items: list[int] = [1, 2, 3]
mapping: dict[str, int] = {"a": 1, "b": 2}
pair: tuple[int, str] = (1, "hello")
unique: set[int] = {1, 2, 3}

# None (null equivalent)
value: str | None = None

# Type checking
isinstance(42, int)  # True
type(42)             # <class 'int'>

Data Structures

Built-in: Arrays, Objects, Map, Set, WeakMap, WeakSet. No built-in linked list, queue, or stack types.

// Arrays — ordered, mixed types
const arr = [1, 'two', true]
arr.push(4)
arr.pop()
arr.includes(1)           // true
arr.find(x => x === 'two')
arr.slice(0, 2)           // [1, 'two']

// Objects — key-value (string keys)
const obj = { name: 'Alice', age: 30 }
obj.email = 'a@b.com'
delete obj.age
Object.keys(obj)          // ['name', 'email']
Object.entries(obj)       // [['name','Alice'], ...]

// Map — key-value (any key type, ordered)
const map = new Map()
map.set('key', 'value')
map.set(42, 'number key')
map.get('key')            // 'value'
map.has(42)               // true
map.size                  // 2

// Set — unique values
const set = new Set([1, 2, 3, 3])
set.add(4)
set.has(2)                // true
set.size                  // 4

// WeakMap / WeakSet — garbage-collectable keys
const wm = new WeakMap()
wm.set(someObj, 'metadata')

// Typed arrays (for binary data)
const buf = new ArrayBuffer(16)
const view = new Int32Array(buf)

Data Structures

Same runtime structures as JavaScript, with full type annotations. Generics make collections type-safe.

// Typed arrays
const nums: number[] = [1, 2, 3]
const names: Array<string> = ['Alice', 'Bob']

// Tuples — fixed-length typed arrays
const pair: [string, number] = ['age', 30]
const [key, value] = pair

// Readonly collections
const frozen: readonly number[] = [1, 2, 3]
const frozenTuple: readonly [string, number] = ['a', 1]

// Map with typed keys and values
const map = new Map<string, number>()
map.set('count', 42)

// Set
const ids = new Set<number>([1, 2, 3])

// Record — typed object with uniform value types
const scores: Record<string, number> = {
  alice: 95,
  bob: 87,
}

// Interface for structured data
interface User {
  name: string
  age: number
  tags: Set<string>
}

// Discriminated unions as data structures
type Tree<T> =
  | { kind: 'leaf'; value: T }
  | { kind: 'node'; left: Tree<T>; right: Tree<T> }

Data Structures

PHP arrays are versatile ordered maps. The SPL library provides additional data structures.

// Arrays — ordered map (used as list, map, set, stack, queue)
$list = [1, 2, 3];
$map = ['name' => 'Alice', 'age' => 30];

// Array operations
$list[] = 4;                    // Append
array_push($list, 5);
array_pop($list);               // Remove last
array_shift($list);             // Remove first
array_unshift($list, 0);        // Prepend
in_array(2, $list);             // Search
array_key_exists('name', $map); // Key exists
count($list);                   // Length

// Array manipulation
array_merge($a, $b);            // Merge arrays
array_slice($list, 1, 2);       // Slice
array_unique($list);            // Remove duplicates
array_reverse($list);           // Reverse
sort($list);                    // Sort in-place
usort($list, fn($a, $b) => $a <=> $b);  // Custom sort

// Spread operator
$merged = [...$list1, ...$list2];

// SPL Data Structures
$stack = new SplStack();
$stack->push('a');
$stack->pop();

$queue = new SplQueue();
$queue->enqueue('a');
$queue->dequeue();

$heap = new SplMinHeap();
$set = new SplObjectStorage();  // Object set

Data Structures

Arrays, Hashes, Sets, Structs, and Data (Ruby 3.2+) are the core data structures.

# Arrays — ordered, mixed types
arr = [1, 'two', :three]
arr.push(4)          # or arr << 4
arr.pop              # Remove last
arr.shift            # Remove first
arr.unshift(0)       # Prepend
arr.include?(1)      # true
arr.flatten          # Flatten nested arrays
arr.compact          # Remove nils
arr.uniq             # Remove duplicates

# Hashes — key-value pairs
hash = { name: 'Alice', age: 30 }
hash[:email] = 'a@b.com'
hash.delete(:age)
hash.keys            # [:name, :email]
hash.values
hash.fetch(:name, 'default')
hash.merge(other_hash)

# Set
require 'set'
set = Set.new([1, 2, 3, 3])  # {1, 2, 3}
set.add(4)
set.include?(2)      # true
set & other_set       # Intersection
set | other_set       # Union

# Struct — lightweight data class
User = Struct.new(:name, :age, keyword_init: true)
user = User.new(name: 'Alice', age: 30)

# Data (Ruby 3.2+) — immutable value object
Point = Data.define(:x, :y)
p = Point.new(x: 1, y: 2)
# p.x = 3  # => NoMethodError (immutable)

# OpenStruct — dynamic attributes
require 'ostruct'
obj = OpenStruct.new(name: 'Alice')
obj.age = 30

Data Structures

Built-in: arrays, slices, maps, and channels. No generics-based collection library in stdlib (use slices/maps packages).

// Arrays — fixed size
var arr [3]int = [3]int{1, 2, 3}

// Slices — dynamic, most common
s := []int{1, 2, 3}
s = append(s, 4)
s[0]                    // 1
s[1:3]                  // [2, 3]
len(s)                  // 4
cap(s)                  // capacity

// Make with initial capacity
s := make([]int, 0, 100)

// Maps — key-value
m := map[string]int{
    "alice": 95,
    "bob":   87,
}
m["charlie"] = 72
val, ok := m["alice"]   // ok = true
delete(m, "bob")

// Iteration
for i, v := range s { fmt.Println(i, v) }
for k, v := range m { fmt.Println(k, v) }
// Structs as data containers
type Point struct {
    X, Y float64
}

// Slices/maps packages (Go 1.21+)
import "slices"
slices.Sort(s)
slices.Contains(s, 3)
idx := slices.Index(s, 2)

import "maps"
maps.Keys(m)
maps.Values(m)

// No built-in set — use map[T]struct{}
set := map[string]struct{}{}
set["a"] = struct{}{}
_, exists := set["a"]   // exists = true

Data Structures

Rich standard library: Vec, HashMap, HashSet, BTreeMap, VecDeque, LinkedList. All generic and ownership-aware.

// Vec — growable array (most common)
let mut v = vec![1, 2, 3];
v.push(4);
v.pop();                // Some(4)
v[0];                   // 1
v.len();                // 3
v.contains(&2);         // true
let slice = &v[1..3];   // &[2, 3]

// HashMap
use std::collections::HashMap;
let mut map = HashMap::new();
map.insert("alice", 95);
map.insert("bob", 87);
map.get("alice");       // Some(&95)
map.contains_key("bob");
map.entry("charlie").or_insert(0);

// HashSet
use std::collections::HashSet;
let mut set: HashSet<i32> = [1, 2, 3].into();
set.insert(4);
set.contains(&2);      // true
let intersection = &set & &other_set;

// Iterators (lazy, chainable)
let sum: i32 = v.iter().filter(|&&x| x > 1).sum();
let doubled: Vec<_> = v.iter().map(|x| x * 2).collect();
// Tuples
let pair: (String, i32) = ("age".into(), 30);
let (key, value) = pair;

// BTreeMap — sorted keys
use std::collections::BTreeMap;
let mut bt = BTreeMap::new();
bt.insert(3, "c");
bt.insert(1, "a");
// Iteration is in key order

// VecDeque — double-ended queue
use std::collections::VecDeque;
let mut dq = VecDeque::from([1, 2, 3]);
dq.push_front(0);
dq.push_back(4);

Data Structures

STL containers: vector, map, unordered_map, set, deque, list, array, stack, queue, priority_queue.

#include <vector>
#include <map>
#include <unordered_map>
#include <set>
#include <array>

// vector — dynamic array (most common)
std::vector<int> v = {1, 2, 3};
v.push_back(4);
v.pop_back();
v[0];                    // 1
v.size();                // 3
v.empty();               // false

// array — fixed-size (stack allocated)
std::array<int, 3> arr = {1, 2, 3};

// map — sorted key-value (red-black tree)
std::map<std::string, int> m;
m["alice"] = 95;
m.contains("alice");     // true (C++20)
m.erase("alice");

// unordered_map — hash map (faster lookup)
std::unordered_map<std::string, int> um;
um["bob"] = 87;
auto it = um.find("bob");

// set — sorted unique values
std::set<int> s = {3, 1, 2};
s.insert(4);
s.contains(2);           // true (C++20)
// Iteration
for (auto& [key, val] : m) { /* structured binding */ }
for (const auto& x : v) { /* range-for */ }

// Algorithms
#include <algorithm>
#include <ranges>

std::sort(v.begin(), v.end());
auto it = std::find(v.begin(), v.end(), 2);
bool has = std::ranges::contains(v, 3); // C++23

// Ranges (C++20)
auto evens = v | std::views::filter([](int x) { return x % 2 == 0; });

// stack, queue, priority_queue (adaptors)
#include <stack>
std::stack<int> stk;
stk.push(1);
stk.top();  // 1
stk.pop();

Data Structures

Rich System.Collections.Generic namespace: List<T>, Dictionary<K,V>, HashSet<T>, Queue<T>, Stack<T>, and more.

// List<T> — dynamic array
var list = new List<int> { 1, 2, 3 };
list.Add(4);
list.Remove(2);
list.Contains(3);        // true
list.Count;              // 3

// Dictionary<TKey, TValue>
var dict = new Dictionary<string, int>
{
    ["alice"] = 95,
    ["bob"] = 87,
};
dict["charlie"] = 72;
dict.TryGetValue("alice", out var score);
dict.ContainsKey("bob");

// HashSet<T>
var set = new HashSet<int> { 1, 2, 3 };
set.Add(4);
set.Contains(2);
set.IntersectWith(new[] { 2, 3, 5 });

// Arrays — fixed size
int[] arr = { 1, 2, 3 };
int[,] matrix = { { 1, 2 }, { 3, 4 } };
// Queue and Stack
var queue = new Queue<string>();
queue.Enqueue("first");
var item = queue.Dequeue();

var stack = new Stack<int>();
stack.Push(1);
var top = stack.Pop();

// Immutable collections
using System.Collections.Immutable;
var iList = ImmutableList.Create(1, 2, 3);
var iDict = ImmutableDictionary<string, int>.Empty
    .Add("a", 1);

// LINQ on any collection
var evens = list.Where(x => x % 2 == 0).ToList();
var grouped = items.GroupBy(x => x.Category);

// Span<T> — stack-allocated view (no allocation)
Span<int> span = stackalloc int[] { 1, 2, 3 };

Data Structures

Built-in value types: Array, Dictionary, Set. All generic and copy-on-write. Swift Collections package adds more.

// Array — ordered, generic
var arr = [1, 2, 3]
arr.append(4)
arr.remove(at: 0)
arr.contains(2)          // true
arr.count                // 3
arr[0...1]               // ArraySlice [2, 3]
arr.first                // Optional(2)

// Dictionary — key-value
var dict: [String: Int] = ["alice": 95, "bob": 87]
dict["charlie"] = 72
dict["alice"]             // Optional(95)
dict.keys                 // Dictionary.Keys
dict.removeValue(forKey: "bob")

// Set — unique values
var set: Set<Int> = [1, 2, 3]
set.insert(4)
set.contains(2)           // true
let intersection = set.intersection([2, 3, 5])
let union = set.union([5, 6])

// Tuples
let point = (x: 10, y: 20)
let (x, y) = point
// Iteration
for (index, value) in arr.enumerated() { }
for (key, value) in dict { }

// Functional operations
let doubled = arr.map { $0 * 2 }
let evens = arr.filter { $0 % 2 == 0 }
let sum = arr.reduce(0, +)
let sorted = arr.sorted(by: >)

// Swift Collections package (extras)
// import Collections
// Deque, OrderedDictionary, OrderedSet, Heap
import Collections
var deque = Deque([1, 2, 3])
deque.prepend(0)

Data Structures

Kotlin distinguishes mutable and immutable collection interfaces: List/MutableList, Map/MutableMap, Set/MutableSet.

// List — ordered (immutable by default)
val list = listOf(1, 2, 3)
val mutable = mutableListOf(1, 2, 3)
mutable.add(4)
mutable.removeAt(0)
list[0]                  // 1
list.size                // 3
list.contains(2)         // true

// Map — key-value
val map = mapOf("alice" to 95, "bob" to 87)
val mutableMap = mutableMapOf("alice" to 95)
mutableMap["charlie"] = 72
map["alice"]             // 95 (nullable)
map.getOrDefault("missing", 0)

// Set — unique values
val set = setOf(1, 2, 3)
val mutableSet = mutableSetOf(1, 2, 3)
mutableSet.add(4)
set.contains(2)          // true
set intersect setOf(2, 3, 5)  // [2, 3]

// Pair and Triple
val pair = "age" to 30
val (key, value) = pair
// Collection operations (rich stdlib)
val doubled = list.map { it * 2 }
val evens = list.filter { it % 2 == 0 }
val sum = list.reduce { acc, x -> acc + x }
val grouped = items.groupBy { it.category }
val chunked = list.chunked(2)
val windowed = list.windowed(3)

// Sequences — lazy evaluation
val result = (1..1_000_000).asSequence()
    .filter { it % 2 == 0 }
    .map { it * it }
    .take(10)
    .toList()

// Destructuring
data class Point(val x: Int, val y: Int)
val (x, y) = Point(10, 20)

// Array (JVM array, fixed size)
val arr = arrayOf(1, 2, 3)
val intArr = intArrayOf(1, 2, 3) // Primitive array

Data Structures

Rich built-in types: list, dict, set, tuple, frozenset. collections module adds deque, Counter, defaultdict, and more.

# List — ordered, mutable
nums = [1, 2, 3]
nums.append(4)
nums.pop()
nums[0]               # 1
nums[1:3]             # [2, 3] (slicing)

# Tuple — ordered, immutable
point = (10, 20)
x, y = point          # Unpacking

# Dict — key-value (ordered since 3.7)
user = {"name": "Alice", "age": 30}
user["email"] = "a@b.com"
user.get("missing", "default")
user.keys()
user.items()

# Set — unique values
s = {1, 2, 3, 3}     # {1, 2, 3}
s.add(4)
s & {2, 3, 5}         # Intersection: {2, 3}
s | {5, 6}            # Union: {1, 2, 3, 4, 5, 6}

# Comprehensions
squares = [x**2 for x in range(10)]
evens = {x for x in range(10) if x % 2 == 0}
mapping = {k: v for k, v in pairs}
# collections module
from collections import deque, Counter, defaultdict, namedtuple

dq = deque([1, 2, 3])
dq.appendleft(0)       # O(1) prepend

counts = Counter("abracadabra")
# Counter({'a': 5, 'b': 2, 'r': 2, 'c': 1, 'd': 1})

dd = defaultdict(list)
dd["key"].append(1)     # No KeyError

Point = namedtuple("Point", ["x", "y"])
p = Point(10, 20)

Functions

Functions can be declared, expressed, or written as arrow functions.

// Function declaration
function greet(name) {
  return `Hello, ${name}!`;
}

// Arrow function
const add = (a, b) => a + b;

// Default parameters
function power(base, exp = 2) {
  return base ** exp;
}

// Rest parameters
function sum(...nums) {
  return nums.reduce((a, b) => a + b, 0);
}

Functions

Functions with typed parameters, return types, and overloads.

// Typed function
function greet(name: string): string {
  return `Hello, ${name}!`;
}

// Arrow function with types
const add = (a: number, b: number): number => a + b;

// Optional and default parameters
function power(base: number, exp: number = 2): number {
  return base ** exp;
}

// Generic function
function first<T>(arr: T[]): T | undefined {
  return arr[0];
}

// Function type
type Callback = (data: string) => void;

Functions

Functions support type hints, default parameters, named arguments, and closures.

// Basic function
function greet(string $name): string {
    return "Hello, {$name}!";
}

// Default parameters
function power(int $base, int $exp = 2): int {
    return $base ** $exp;
}

// Named arguments (PHP 8.0+)
power(exp: 3, base: 2);  // 8

// Variadic parameters
function sum(int ...$nums): int {
    return array_sum($nums);
}

// Arrow functions (PHP 7.4+)
$double = fn(int $x): int => $x * 2;

// Closures
$multiplier = function (int $factor): Closure {
    return fn(int $x) => $x * $factor;
};
$triple = $multiplier(3);
$triple(5);  // 15

// First-class callable syntax (PHP 8.1+)
$fn = strlen(...);
$fn('hello');  // 5

Functions

Methods are defined with def. Ruby also supports blocks, procs, and lambdas.

# Method definition
def greet(name)
  "Hello, #{name}!"  # Implicit return (last expression)
end

# Default parameters
def power(base, exp = 2)
  base ** exp
end

# Keyword arguments
def create_user(name:, age:, role: 'user')
  { name: name, age: age, role: role }
end
create_user(name: 'Alice', age: 30)

# Splat (rest) parameters
def sum(*nums)
  nums.reduce(0, :+)
end

# Double splat (keyword rest)
def config(**options)
  options
end

# Blocks
def with_logging
  puts 'Start'
  yield  # Execute the block
  puts 'End'
end
with_logging { puts 'Working...' }

# Procs and Lambdas
double = ->(x) { x * 2 }    # Lambda
double.call(5)                # 10
double.(5)                    # 10 (shorthand)

square = proc { |x| x ** 2 } # Proc
square.call(4)                # 16

Functions

Functions can return multiple values. Methods are functions with a receiver.

// Basic function
func greet(name string) string {
    return fmt.Sprintf("Hello, %s!", name)
}

// Multiple return values
func divide(a, b float64) (float64, error) {
    if b == 0 {
        return 0, errors.New("division by zero")
    }
    return a / b, nil
}

// Variadic function
func sum(nums ...int) int {
    total := 0
    for _, n := range nums {
        total += n
    }
    return total
}

// Method (function with receiver)
func (u User) FullName() string {
    return u.FirstName + " " + u.LastName
}

// Anonymous function
add := func(a, b int) int { return a + b }

Functions

Functions use fn. The last expression is the return value (no semicolon).

// Basic function
fn greet(name: &str) -> String {
    format!("Hello, {}!", name)
}

// Multiple parameters
fn add(a: i32, b: i32) -> i32 {
    a + b
}

// Closures
let add = |a: i32, b: i32| -> i32 { a + b };
let double = |x| x * 2;

// Generic function
fn first<T>(items: &[T]) -> Option<&T> {
    items.first()
}

// Methods (impl block)
impl User {
    fn new(name: String, age: u32) -> Self {
        Self { name, age, email: None }
    }

    fn display(&self) -> String {
        format!("{} ({})", self.name, self.age)
    }
}

Functions

Functions support overloading, templates, and lambdas.

// Basic function
std::string greet(const std::string& name) {
    return "Hello, " + name + "!";
}

// Default parameters
int power(int base, int exp = 2) {
    return std::pow(base, exp);
}

// Function overloading
int add(int a, int b) { return a + b; }
double add(double a, double b) { return a + b; }

// Template function
template <typename T>
T first(const std::vector<T>& items) {
    return items.front();
}

// Lambda
auto multiply = [](int a, int b) { return a * b; };
auto adder = [offset = 10](int x) { return x + offset; };

// Trailing return type
auto divide(int a, int b) -> double {
    return static_cast<double>(a) / b;
}

Functions

Methods live inside classes or structs. C# also supports local functions and lambdas.

// Method
string Greet(string name) {
    return $"Hello, {name}!";
}

// Expression-bodied method
int Add(int a, int b) => a + b;

// Default parameters
int Power(int baseVal, int exp = 2)
    => (int)Math.Pow(baseVal, exp);

// Lambda expressions
Func<int, int> double = x => x * 2;
Action<string> log = msg => Console.WriteLine(msg);

// Local function
void Outer() {
    int Inner(int x) => x + 1;
    Console.WriteLine(Inner(5));
}

// Generic method
T First<T>(List<T> items) => items[0];

Functions

Functions use named parameters by default. Closures are first-class.

// Basic function
func greet(name: String) -> String {
    return "Hello, \(name)!"
}

// Argument labels
func move(from start: Int, to end: Int) -> Int {
    return end - start
}
move(from: 0, to: 10)

// Default parameters
func power(base: Int, exp: Int = 2) -> Int {
    return Int(pow(Double(base), Double(exp)))
}

// Closures
let add = { (a: Int, b: Int) -> Int in a + b }
let doubled = [1, 2, 3].map { $0 * 2 }

// Generic function
func first<T>(_ items: [T]) -> T? {
    return items.first
}

// Throwing function
func parse(_ input: String) throws -> Int {
    guard let n = Int(input) else {
        throw ParseError.invalidInput
    }
    return n
}

Functions

Functions support default arguments, named parameters, and lambdas.

// Basic function
fun greet(name: String): String {
    return "Hello, $name!"
}

// Single-expression function
fun add(a: Int, b: Int) = a + b

// Default and named parameters
fun power(base: Int, exp: Int = 2): Int {
    return base.toDouble().pow(exp).toInt()
}
power(base = 3, exp = 4)

// Lambda
val double = { x: Int -> x * 2 }
val sum = listOf(1, 2, 3).fold(0) { acc, x -> acc + x }

// Extension function
fun String.addExclamation() = "$this!"
"hello".addExclamation() // "hello!"

// Generic function
fun <T> first(items: List<T>): T = items.first()

// Higher-order function
fun apply(x: Int, fn: (Int) -> Int): Int = fn(x)

Functions

Defined with def. Support default args, keyword args, and type hints.

# Basic function
def greet(name: str) -> str:
    return f"Hello, {name}!"

# Default parameters
def power(base: int, exp: int = 2) -> int:
    return base ** exp

# *args and **kwargs
def log(*args, **kwargs):
    print(*args, **kwargs)

# Lambda (anonymous function)
add = lambda a, b: a + b

# Decorators
def timer(func):
    def wrapper(*args):
        import time
        start = time.time()
        result = func(*args)
        print(f"{time.time() - start:.2f}s")
        return result
    return wrapper

Conditionals

Standard if/else, ternary operator, and switch.

// If / else
if (x > 0) {
  console.log('positive');
} else if (x === 0) {
  console.log('zero');
} else {
  console.log('negative');
}

// Ternary
const label = x > 0 ? 'positive' : 'non-positive';

// Switch
switch (color) {
  case 'red':
    console.log('#f00');
    break;
  case 'blue':
    console.log('#00f');
    break;
  default:
    console.log('unknown');
}

// Nullish coalescing
const val = input ?? 'default';

// Optional chaining
const city = user?.address?.city;

Conditionals

Same as JavaScript, plus type narrowing and exhaustive checks.

// Type narrowing with if
function process(value: string | number) {
  if (typeof value === 'string') {
    console.log(value.toUpperCase()); // string
  } else {
    console.log(value.toFixed(2)); // number
  }
}

// Discriminated unions
type Shape =
  | { kind: 'circle'; radius: number }
  | { kind: 'square'; side: number };

function area(shape: Shape): number {
  switch (shape.kind) {
    case 'circle':
      return Math.PI * shape.radius ** 2;
    case 'square':
      return shape.side ** 2;
  }
}

// Satisfies operator
const palette = {
  red: '#f00',
  green: '#0f0',
} satisfies Record<string, string>;

Conditionals

Standard if/else, ternary, null coalescing, and match expression.

// If / else
if ($x > 0) {
    echo 'positive';
} elseif ($x === 0) {
    echo 'zero';
} else {
    echo 'negative';
}

// Ternary
$label = $x > 0 ? 'positive' : 'non-positive';

// Elvis operator (short ternary)
$name = $input ?: 'default';

// Null coalescing
$value = $data['key'] ?? 'fallback';
$value ??= 'fallback';  // Null coalescing assignment

// Match expression (PHP 8.0+) — strict comparison, returns value
$result = match ($status) {
    'active' => 'User is active',
    'banned', 'suspended' => 'User is restricted',
    default => 'Unknown status',
};

// Switch
switch ($color) {
    case 'red':
        echo '#f00';
        break;
    case 'blue':
        echo '#00f';
        break;
    default:
        echo 'unknown';
}

Conditionals

Ruby has if/elsif/else, unless, case/when, and pattern matching (Ruby 3.0+).

# If / elsif / else
if x > 0
  puts 'positive'
elsif x == 0
  puts 'zero'
else
  puts 'negative'
end

# Inline if / unless
puts 'positive' if x > 0
puts 'not zero' unless x.zero?

# Ternary
label = x > 0 ? 'positive' : 'non-positive'

# Case / when
case color
when 'red'
  puts '#f00'
when 'blue', 'navy'
  puts '#00f'
else
  puts 'unknown'
end

# Pattern matching (Ruby 3.0+)
case [1, 2, 3]
in [Integer => a, Integer => b, *rest]
  puts "a=#{a}, b=#{b}"
end

case { name: 'Alice', age: 30 }
in { name: String => name, age: (18..) => age }
  puts "#{name} is #{age}"
end

# Guard clauses (idiomatic Ruby)
def process(data)
  return if data.nil?
  return unless data.valid?
  # ... process data
end

Conditionals

if/else and switch. Conditions don’t need parentheses.

// If / else (can include init statement)
if x := compute(); x > 0 {
    fmt.Println("positive")
} else if x == 0 {
    fmt.Println("zero")
} else {
    fmt.Println("negative")
}

// Switch (no break needed, implicit)
switch day {
case "Mon", "Tue", "Wed", "Thu", "Fri":
    fmt.Println("weekday")
case "Sat", "Sun":
    fmt.Println("weekend")
default:
    fmt.Println("unknown")
}

// Type switch
switch v := val.(type) {
case int:
    fmt.Println("int:", v)
case string:
    fmt.Println("string:", v)
default:
    fmt.Println("other")
}

Conditionals

if/else is an expression. match is powerful pattern matching.

// If / else (is an expression)
let label = if x > 0 {
    "positive"
} else if x == 0 {
    "zero"
} else {
    "negative"
};

// Match (exhaustive pattern matching)
match shape {
    Shape::Circle(r) => std::f64::consts::PI * r * r,
    Shape::Rectangle(w, h) => w * h,
}

// Match with guards
match age {
    0..=12 => "child",
    13..=17 => "teen",
    18..=64 => "adult",
    _ => "senior",
}

// If let (single pattern)
if let Some(value) = maybe_value {
    println!("Got: {}", value);
}

// Let-else
let Some(x) = optional else {
    return;
};

Conditionals

if/else, switch, and if with initializer (C++17).

// If / else
if (x > 0) {
    std::cout << "positive\n";
} else if (x == 0) {
    std::cout << "zero\n";
} else {
    std::cout << "negative\n";
}

// Ternary
auto label = (x > 0) ? "positive" : "non-positive";

// If with initializer (C++17)
if (auto it = map.find("key"); it != map.end()) {
    std::cout << it->second;
}

// Switch
switch (color) {
    case Color::Red:   std::cout << "red"; break;
    case Color::Green: std::cout << "green"; break;
    default:           std::cout << "other"; break;
}

// std::variant + std::visit (pattern matching)
std::visit([](auto&& arg) {
    std::cout << arg;
}, myVariant);

Conditionals

if/else, switch expressions, and pattern matching.

// If / else
if (x > 0) {
    Console.WriteLine("positive");
} else if (x == 0) {
    Console.WriteLine("zero");
} else {
    Console.WriteLine("negative");
}

// Ternary
var label = x > 0 ? "positive" : "non-positive";

// Switch expression (pattern matching)
var result = shape switch {
    Circle c => Math.PI * c.Radius * c.Radius,
    Rectangle r => r.Width * r.Height,
    _ => 0
};

// Pattern matching with when
var category = age switch {
    <= 12 => "child",
    <= 17 => "teen",
    <= 64 => "adult",
    _ => "senior"
};

// Null-coalescing
var val = input ?? "default";
var city = user?.Address?.City;

Conditionals

if/else, switch with pattern matching, and guard for early exits.

// If / else
if x > 0 {
    print("positive")
} else if x == 0 {
    print("zero")
} else {
    print("negative")
}

// Ternary
let label = x > 0 ? "positive" : "non-positive"

// Switch (exhaustive, no fallthrough)
switch shape {
case .circle(let radius):
    print("Circle: \(radius)")
case .rectangle(let w, let h):
    print("Rect: \(w)x\(h)")
}

// Guard (early exit)
func process(value: String?) {
    guard let unwrapped = value else {
        print("no value")
        return
    }
    print(unwrapped)
}

// If-let (optional binding)
if let city = user?.address?.city {
    print(city)
}

// Nil coalescing
let val = input ?? "default"

Conditionals

if is an expression. when replaces switch with pattern matching.

// If expression
val label = if (x > 0) "positive" else "non-positive"

// If / else
if (x > 0) {
    println("positive")
} else if (x == 0) {
    println("zero")
} else {
    println("negative")
}

// When expression (like switch)
val result = when (shape) {
    is Shape.Circle -> Math.PI * shape.radius * shape.radius
    is Shape.Rect -> shape.w * shape.h
}

// When with conditions
val category = when {
    age <= 12 -> "child"
    age <= 17 -> "teen"
    age <= 64 -> "adult"
    else -> "senior"
}

// Null safety
val len = maybeStr?.length ?: 0
val city = user?.address?.city

// Safe cast
val str = value as? String

Conditionals

if/elif/else blocks. Python 3.10+ adds match/case for pattern matching.

# If / elif / else
if x > 0:
    print("positive")
elif x == 0:
    print("zero")
else:
    print("negative")

# Ternary (inline if)
label = "positive" if x > 0 else "non-positive"

# Match / case (Python 3.10+)
match command:
    case "quit":
        exit()
    case "hello":
        print("Hi!")
    case _:
        print("Unknown command")

# Truthy / falsy
if not []:
    print("empty list is falsy")

Loops

Standard for, while, and iterator-based loops.

// For loop
for (let i = 0; i < 5; i++) {
  console.log(i);
}

// For...of (iterables)
for (const item of [1, 2, 3]) {
  console.log(item);
}

// For...in (object keys)
for (const key in { a: 1, b: 2 }) {
  console.log(key);
}

// While
let n = 0;
while (n < 3) {
  n++;
}

// Array methods
[1, 2, 3].forEach((x) => console.log(x));
[1, 2, 3].map((x) => x * 2);

Loops

Same loop constructs as JavaScript, with type safety.

// For loop
for (let i = 0; i < 5; i++) {
  console.log(i);
}

// For...of with typed arrays
const items: string[] = ['a', 'b', 'c'];
for (const item of items) {
  console.log(item); // item is string
}

// For...in
const obj: Record<string, number> = { a: 1, b: 2 };
for (const key in obj) {
  console.log(key, obj[key]);
}

// Array methods (type-safe)
[1, 2, 3].map((x): string => x.toString());
[1, 2, 3].filter((x): x is number => x > 1);

Loops

Standard for, foreach, while, and do-while loops.

// For loop
for ($i = 0; $i < 5; $i++) {
    echo $i;
}

// Foreach — arrays and iterables
foreach ([1, 2, 3] as $item) {
    echo $item;
}

// Foreach with key
foreach (['a' => 1, 'b' => 2] as $key => $value) {
    echo "$key: $value";
}

// While
$n = 0;
while ($n < 3) {
    $n++;
}

// Do-while
do {
    $n--;
} while ($n > 0);

// Array functions (functional-style)
$doubled = array_map(fn($x) => $x * 2, [1, 2, 3]);
$evens = array_filter([1, 2, 3, 4], fn($x) => $x % 2 === 0);
$sum = array_reduce([1, 2, 3], fn($carry, $x) => $carry + $x, 0);

Loops

Ruby favors iterators and blocks over traditional loops. each, map, select are idiomatic.

# each — the Ruby way
[1, 2, 3].each { |x| puts x }

# each with index
['a', 'b', 'c'].each_with_index do |item, i|
  puts "#{i}: #{item}"
end

# times
5.times { |i| puts i }

# upto / downto
1.upto(5) { |i| puts i }
5.downto(1) { |i| puts i }

# Ranges
(1..5).each { |i| puts i }

# while / until
n = 0
while n < 3
  n += 1
end

until n == 0
  n -= 1
end

# loop (infinite)
loop do
  break if some_condition
end

# Iterators (functional-style)
[1, 2, 3].map { |x| x * 2 }       # [2, 4, 6]
[1, 2, 3, 4].select { |x| x.even? } # [2, 4]
[1, 2, 3].reduce(0) { |sum, x| sum + x }  # 6
[1, 2, 3].reduce(:+)                # 6 (shorthand)

Loops

Go has only for — it covers all loop patterns.

// Classic for loop
for i := 0; i < 5; i++ {
    fmt.Println(i)
}

// While-style
n := 0
for n < 3 {
    n++
}

// Infinite loop
for {
    break // exit
}

// Range over slice
for i, val := range []string{"a", "b", "c"} {
    fmt.Println(i, val)
}

// Range over map
for key, val := range myMap {
    fmt.Println(key, val)
}

// Range over string (runes)
for i, ch := range "hello" {
    fmt.Printf("%d: %c\n", i, ch)
}

Loops

for, while, and loop (infinite). Iterators are idiomatic.

// For loop with range
for i in 0..5 {
    println!("{}", i);
}

// Iterate over a collection
let items = vec!["a", "b", "c"];
for item in &items {
    println!("{}", item);
}

// While loop
let mut n = 0;
while n < 3 {
    n += 1;
}

// Infinite loop with break
loop {
    break;
}

// Loop with return value
let result = loop {
    if condition {
        break 42;
    }
};

// Iterator methods
let squares: Vec<i32> = (0..10).map(|x| x * x).collect();
let sum: i32 = vec![1, 2, 3].iter().sum();

Loops

Standard for, range-based for, while, and STL algorithms.

// Classic for loop
for (int i = 0; i < 5; i++) {
    std::cout << i << "\n";
}

// Range-based for (C++11)
std::vector<std::string> items = {"a", "b", "c"};
for (const auto& item : items) {
    std::cout << item << "\n";
}

// While
int n = 0;
while (n < 3) {
    n++;
}

// Do-while
do {
    n--;
} while (n > 0);

// STL algorithms
std::vector<int> nums = {1, 2, 3};
std::for_each(nums.begin(), nums.end(),
    [](int x) { std::cout << x; });

// Ranges (C++20)
auto squares = nums
    | std::views::transform([](int x) { return x * x; });

Loops

Standard for, foreach, while, and LINQ for functional iteration.

// For loop
for (int i = 0; i < 5; i++) {
    Console.WriteLine(i);
}

// Foreach
foreach (var item in new[] { "a", "b", "c" }) {
    Console.WriteLine(item);
}

// While
int n = 0;
while (n < 3) {
    n++;
}

// Do-while
do {
    n--;
} while (n > 0);

// LINQ
var squares = Enumerable.Range(0, 10)
    .Select(x => x * x)
    .ToList();

var evens = new[] { 1, 2, 3, 4 }
    .Where(x => x % 2 == 0);

Loops

for-in loops, while, and functional methods on collections.

// For-in with range
for i in 0..<5 {
    print(i)
}

// For-in over array
for item in ["a", "b", "c"] {
    print(item)
}

// Enumerated (index + value)
for (i, val) in ["a", "b", "c"].enumerated() {
    print(i, val)
}

// While
var n = 0
while n < 3 {
    n += 1
}

// Repeat-while (do-while)
repeat {
    n -= 1
} while n > 0

// Functional methods
let squares = (0..<10).map { $0 * $0 }
let evens = [1, 2, 3, 4].filter { $0 % 2 == 0 }
let sum = [1, 2, 3].reduce(0, +)

Loops

for loops with ranges, while, and rich collection functions.

// For with range
for (i in 0 until 5) {
    println(i)
}

// For over collection
for (item in listOf("a", "b", "c")) {
    println(item)
}

// With index
for ((i, item) in listOf("a", "b").withIndex()) {
    println("$i: $item")
}

// While
var n = 0
while (n < 3) {
    n++
}

// Do-while
do {
    n--
} while (n > 0)

// Functional
val squares = (0 until 10).map { it * it }
val evens = listOf(1, 2, 3, 4).filter { it % 2 == 0 }
val sum = listOf(1, 2, 3).reduce { acc, x -> acc + x }

// Repeat
repeat(3) { println("hello") }

Loops

for loops iterate over any iterable. while for condition-based loops.

# For loop
for i in range(5):
    print(i)

# Iterate over a list
for item in ["a", "b", "c"]:
    print(item)

# Enumerate (index + value)
for i, val in enumerate(["a", "b", "c"]):
    print(i, val)

# While loop
n = 0
while n < 3:
    n += 1

# List comprehension
squares = [x ** 2 for x in range(10)]

# Dict comprehension
mapping = {k: v for k, v in [("a", 1), ("b", 2)]}

Generics & Type System

JavaScript has no type system at runtime. Types are dynamic — any variable can hold any value. Use TypeScript for static types.

// No generics — functions work with any type naturally
function identity(x) { return x }
identity(42)       // number
identity('hello')  // string

// Duck typing — if it has the right shape, it works
function getLength(thing) {
  return thing.length  // Works for strings, arrays, etc.
}

// typeof — runtime type checking
typeof 42          // 'number'
typeof 'hello'     // 'string'
typeof true        // 'boolean'
typeof undefined   // 'undefined'
typeof null        // 'object' (historical bug)
typeof {}          // 'object'
typeof []          // 'object'

// instanceof — check prototype chain
[] instanceof Array     // true
new Date() instanceof Date  // true

// Array.isArray — reliable array check
Array.isArray([1, 2])  // true

JavaScript is dynamically typed — generics are a TypeScript concept. See the TypeScript column for full generics support.

Generics & Type System

Structural type system with powerful generics, conditional types, mapped types, and template literal types.

// Generic functions
function identity<T>(value: T): T { return value }
identity<number>(42)
identity('hello')  // T inferred as string

// Generic constraints
function getLength<T extends { length: number }>(x: T): number {
  return x.length
}

// Generic interfaces and classes
interface Repository<T> {
  findById(id: string): Promise<T>
  save(item: T): Promise<void>
}

class Box<T> {
  constructor(public value: T) {}
  map<U>(fn: (val: T) => U): Box<U> {
    return new Box(fn(this.value))
  }
}
// Conditional types
type IsString<T> = T extends string ? true : false
type A = IsString<'hello'>  // true
type B = IsString<42>       // false

// Mapped types
type Readonly<T> = { readonly [K in keyof T]: T[K] }
type Partial<T> = { [K in keyof T]?: T[K] }
type Pick<T, K extends keyof T> = { [P in K]: T[P] }

// Template literal types
type EventName = `on${Capitalize<'click' | 'focus'>}`
// 'onClick' | 'onFocus'

// infer — extract types
type ReturnType<T> = T extends (...args: any[]) => infer R ? R : never
type Awaited<T> = T extends Promise<infer U> ? Awaited<U> : T

// Variance annotations (4.7+)
interface Producer<out T> { get(): T }
interface Consumer<in T> { accept(value: T): void }

Generics & Type System

PHP has no native generics. Type safety is achieved through type declarations, interfaces, and static analysis tools (PHPStan/Psalm) that support generics via docblocks.

// No native generics — use type declarations
function first(array $items): mixed {
    return $items[0] ?? null;
}

// PHPStan/Psalm generics via docblocks
/**
 * @template T
 * @param T[] $items
 * @return T|null
 */
function firstItem(array $items): mixed {
    return $items[0] ?? null;
}

/**
 * @template T
 * @implements Iterator<int, T>
 */
class TypedCollection implements Iterator {
    /** @var T[] */
    private array $items = [];

    /** @param T $item */
    public function add(mixed $item): void {
        $this->items[] = $item;
    }
}

// Union types (PHP 8.0+)
function process(string|int $value): string { return (string) $value; }

// Intersection types (PHP 8.1+)
function handle(Countable&Traversable $items): void { }

// DNF types (PHP 8.2+)
function parse((Stringable&Countable)|string $input): string { }

Static analysis tools (PHPStan level 9, Psalm) provide generics-like type safety through annotations.

Generics & Type System

Ruby has no native generics. It relies on duck typing. Static type checking is available via RBS (built-in) and Sorbet (third-party).

# Duck typing — no generics needed
def first(items)
  items.first
end
first([1, 2, 3])    # 1
first('hello')      # 'h'

# respond_to? — check capabilities
def process(obj)
  if obj.respond_to?(:each)
    obj.each { |x| puts x }
  else
    puts obj
  end
end

# Comparable / Enumerable — mixin-based polymorphism
class Temperature
  include Comparable

  attr_reader :degrees

  def initialize(degrees)
    @degrees = degrees
  end

  def <=>(other)
    degrees <=> other.degrees
  end
end

temps = [Temperature.new(30), Temperature.new(20)]
temps.sort  # Works via Comparable
temps.min   # Works via Comparable
# RBS — type signatures (Ruby 3.0+)
# sig/app.rbs
# class Array[unchecked out Elem]
#   def first: () -> Elem?
#   def map: [U] () { (Elem) -> U } -> Array[U]
# end

# Sorbet — static type checker
# typed: strict
class Box
  extend T::Sig
  extend T::Generic

  Elem = type_member

  sig { params(value: Elem).void }
  def initialize(value)
    @value = T.let(value, Elem)
  end
end

Generics & Type System

Statically typed with generics added in Go 1.18. Type parameters use constraints (interfaces).

// Generic function
func Map[T any, U any](s []T, fn func(T) U) []U {
    result := make([]U, len(s))
    for i, v := range s {
        result[i] = fn(v)
    }
    return result
}

// Usage
doubled := Map([]int{1, 2, 3}, func(x int) int { return x * 2 })

// Constraints — restrict type parameters
type Number interface {
    ~int | ~int32 | ~int64 | ~float32 | ~float64
}

func Sum[T Number](nums []T) T {
    var total T
    for _, n := range nums {
        total += n
    }
    return total
}

// Built-in constraints
import "cmp"
func Max[T cmp.Ordered](a, b T) T {
    if a > b { return a }
    return b
}
// Generic types
type Stack[T any] struct {
    items []T
}

func (s *Stack[T]) Push(item T) {
    s.items = append(s.items, item)
}

func (s *Stack[T]) Pop() (T, bool) {
    if len(s.items) == 0 {
        var zero T
        return zero, false
    }
    item := s.items[len(s.items)-1]
    s.items = s.items[:len(s.items)-1]
    return item, true
}

// Comparable constraint
func Contains[T comparable](s []T, target T) bool {
    for _, v := range s {
        if v == target { return true }
    }
    return false
}

Generics & Type System

Powerful generics with trait bounds. Monomorphized at compile time (zero-cost). Supports associated types, lifetimes, and const generics.

// Generic function
fn identity<T>(value: T) -> T { value }

// Trait bounds — constrain type parameters
fn largest<T: PartialOrd>(list: &[T]) -> &T {
    let mut max = &list[0];
    for item in &list[1..] {
        if item > max { max = item; }
    }
    max
}

// Multiple bounds
fn print_debug<T: std::fmt::Debug + Clone>(item: T) {
    println!("{:?}", item.clone());
}

// Where clause (cleaner for complex bounds)
fn process<T, U>(t: T, u: U) -> String
where
    T: std::fmt::Display + Clone,
    U: std::fmt::Debug,
{
    format!("{} {:?}", t, u)
}
// Generic structs
struct Wrapper<T> {
    value: T,
}

impl<T: std::fmt::Display> Wrapper<T> {
    fn show(&self) { println!("{}", self.value); }
}

// Associated types (in traits)
trait Iterator {
    type Item;
    fn next(&mut self) -> Option<Self::Item>;
}

// Lifetime generics
fn longest<'a>(x: &'a str, y: &'a str) -> &'a str {
    if x.len() > y.len() { x } else { y }
}

// Const generics
fn create_array<const N: usize>() -> [i32; N] {
    [0; N]
}
let arr = create_array::<5>(); // [0, 0, 0, 0, 0]

// Trait objects (dynamic dispatch)
fn print_all(items: &[&dyn std::fmt::Display]) {
    for item in items { println!("{}", item); }
}

Generics & Type System

Templates — compile-time code generation. More powerful than generics (Turing-complete). C++20 adds concepts for constraints.

// Function template
template<typename T>
T identity(T value) { return value; }

identity(42);       // T = int
identity("hello");  // T = const char*

// Concepts (C++20) — constrain templates
#include <concepts>

template<typename T>
concept Numeric = std::integral<T> || std::floating_point<T>;

template<Numeric T>
T add(T a, T b) { return a + b; }

// Requires clause
template<typename T>
requires std::totally_ordered<T>
T max(T a, T b) { return a > b ? a : b; }

// Class template
template<typename T>
class Stack {
    std::vector<T> items;
public:
    void push(T item) { items.push_back(std::move(item)); }
    T pop() {
        T item = std::move(items.back());
        items.pop_back();
        return item;
    }
};
// Template specialization
template<typename T>
std::string to_string(T value) { return std::to_string(value); }

template<>
std::string to_string(bool value) { return value ? "true" : "false"; }

// Variadic templates
template<typename... Args>
void print(Args... args) {
    (std::cout << ... << args) << '\n';  // Fold expression
}

// Non-type template parameters (like const generics)
template<int N>
struct Array {
    int data[N];
};
Array<5> arr;

// SFINAE / if constexpr (compile-time branching)
template<typename T>
auto describe(T val) {
    if constexpr (std::is_integral_v<T>) return "integer";
    else if constexpr (std::is_floating_point_v<T>) return "float";
    else return "other";
}

Generics & Type System

Reified generics — type information preserved at runtime (unlike Java). Supports constraints, covariance, and contravariance.

// Generic method
T Identity<T>(T value) => value;

// Constraints
T Max<T>(T a, T b) where T : IComparable<T>
    => a.CompareTo(b) > 0 ? a : b;

// Multiple constraints
void Process<T>(T item)
    where T : class, IDisposable, new()
{
    // T must be: reference type, IDisposable, have parameterless constructor
}

// Generic class
class Stack<T>
{
    private readonly List<T> _items = new();
    public void Push(T item) => _items.Add(item);
    public T Pop()
    {
        var item = _items[^1];
        _items.RemoveAt(_items.Count - 1);
        return item;
    }
}
// Variance (on interfaces and delegates)
// Covariant (out) — can return T
interface IProducer<out T> { T Produce(); }
// Contravariant (in) — can accept T
interface IConsumer<in T> { void Consume(T item); }

// IEnumerable<out T> is covariant:
IEnumerable<object> objects = new List<string>(); // OK

// Generic interfaces
interface IRepository<T> where T : class
{
    Task<T?> FindByIdAsync(int id);
    Task SaveAsync(T entity);
}

// Nullable reference types (C# 8+)
string? nullable = null;     // Allowed
string nonNull = "hello";    // Compiler warns if null assigned

// Pattern matching with types
object obj = 42;
if (obj is int n) Console.WriteLine(n * 2);

// Generic math (C# 11+)
T Add<T>(T a, T b) where T : INumber<T> => a + b;

Generics & Type System

Protocol-oriented generics with associated types, where clauses, and opaque types (some). Strong type inference.

// Generic function
func identity<T>(_ value: T) -> T { value }

// Protocol constraints
func largest<T: Comparable>(_ items: [T]) -> T? {
    items.max()
}

// Multiple constraints
func process<T: Hashable & CustomStringConvertible>(_ item: T) {
    print(item.description)
}

// Generic types
struct Stack<Element> {
    private var items: [Element] = []

    mutating func push(_ item: Element) { items.append(item) }
    mutating func pop() -> Element? { items.popLast() }
    var isEmpty: Bool { items.isEmpty }
}

var intStack = Stack<Int>()
intStack.push(42)
// Associated types (in protocols)
protocol Container {
    associatedtype Item
    mutating func append(_ item: Item)
    var count: Int { get }
    subscript(i: Int) -> Item { get }
}

// Where clauses
func allMatch<C: Container>(_ container: C, _ predicate: (C.Item) -> Bool) -> Bool
    where C.Item: Equatable
{
    container.allSatisfy(predicate)
}

// Opaque types — hide concrete type
func makeCollection() -> some Collection { [1, 2, 3] }

// Existential types (any)
func printAll(_ items: [any CustomStringConvertible]) {
    for item in items { print(item.description) }
}

// Primary associated types (Swift 5.7+)
func process(_ items: some Collection<Int>) { }

Generics & Type System

Reified generics (inline functions), declaration-site variance (in/out), and type projections. Null safety built into the type system.

// Generic function
fun <T> identity(value: T): T = value

// Constraints (upper bounds)
fun <T : Comparable<T>> max(a: T, b: T): T =
    if (a > b) a else b

// Multiple bounds
fun <T> process(item: T) where T : Serializable, T : Comparable<T> {
    // T must implement both
}

// Generic class
class Stack<T> {
    private val items = mutableListOf<T>()
    fun push(item: T) = items.add(item)
    fun pop(): T = items.removeLast()
}

// Reified type parameters (inline functions only)
inline fun <reified T> isType(value: Any): Boolean = value is T
isType<String>("hello")  // true — type available at runtime!
// Variance
// out = covariant (producer)
interface Source<out T> { fun next(): T }
// in = contravariant (consumer)
interface Sink<in T> { fun accept(item: T) }

// Use-site variance (type projections)
fun copy(from: Array<out Any>, to: Array<in Any>) {
    for (i in from.indices) to[i] = from[i]
}

// Null safety — built into the type system
val name: String = "Alice"      // Non-null
val nullable: String? = null    // Nullable
val length = nullable?.length   // Safe call → Int?
val forced = nullable!!.length  // Throws if null
val default = nullable ?: "Unknown"  // Elvis operator

// Smart casts
fun describe(obj: Any): String = when (obj) {
    is String -> "String of length ${obj.length}"
    is Int -> "Int: $obj"
    else -> "Unknown"
}

Generics & Type System

Dynamically typed with optional type hints (PEP 484+). Generics via typing module. Type checkers (mypy, pyright) enforce at analysis time.

# Generic functions (Python 3.12+ syntax)
def identity[T](value: T) -> T:
    return value

# Constrained generics
from typing import Protocol

class HasLength(Protocol):
    def __len__(self) -> int: ...

def get_length[T: HasLength](x: T) -> int:
    return len(x)

# Generic classes
class Box[T]:
    def __init__(self, value: T) -> None:
        self.value = value

    def map[U](self, fn: Callable[[T], U]) -> "Box[U]":
        return Box(fn(self.value))
# Pre-3.12 syntax (still common)
from typing import TypeVar, Generic

T = TypeVar("T")

class Stack(Generic[T]):
    def __init__(self) -> None:
        self._items: list[T] = []

    def push(self, item: T) -> None:
        self._items.append(item)

    def pop(self) -> T:
        return self._items.pop()

# Union types
def process(value: int | str) -> str:
    return str(value)

# TypeGuard — narrow types
from typing import TypeGuard

def is_string_list(val: list[object]) -> TypeGuard[list[str]]:
    return all(isinstance(x, str) for x in val)

# Variance
from typing import TypeVar
T_co = TypeVar("T_co", covariant=True)
T_contra = TypeVar("T_contra", contravariant=True)

Inheritance & Composition

Prototypal inheritance with class syntax sugar. Composition via mixins and object spread is often preferred.

// Class inheritance
class Animal {
  constructor(name) { this.name = name }
  speak() { return `${this.name} makes a sound` }
}

class Dog extends Animal {
  speak() { return `${this.name} barks` }
}

// Super calls
class Puppy extends Dog {
  constructor(name) {
    super(name)
    this.young = true
  }
}

// Mixins (composition pattern)
const Serializable = (Base) => class extends Base {
  toJSON() { return JSON.stringify(this) }
}

class User extends Serializable(Animal) {}

// Object composition (preferred)
const canWalk = (state) => ({
  walk: () => `${state.name} walks`,
})
const canSwim = (state) => ({
  swim: () => `${state.name} swims`,
})
const createDuck = (name) => {
  const state = { name }
  return { ...canWalk(state), ...canSwim(state) }
}

Inheritance & Composition

Class inheritance with full type checking. Interfaces and intersection types enable powerful composition patterns.

// Class inheritance
class Animal {
  constructor(public name: string) {}
  speak(): string { return `${this.name} makes a sound` }
}

class Dog extends Animal {
  speak(): string { return `${this.name} barks` }
}

// Abstract classes
abstract class Shape {
  abstract area(): number
  describe(): string { return `Area: ${this.area()}` }
}

class Circle extends Shape {
  constructor(public radius: number) { super() }
  area(): number { return Math.PI * this.radius ** 2 }
}

// Interfaces (composition)
interface Serializable {
  toJSON(): string
}
interface Printable {
  print(): void
}
class Report implements Serializable, Printable {
  toJSON() { return '{}' }
  print() { console.log(this.toJSON()) }
}

// Intersection types (type-level composition)
type WithId = { id: string }
type WithTimestamp = { createdAt: Date }
type Entity = WithId & WithTimestamp

Inheritance & Composition

Single inheritance with interfaces and traits for composition. PHP supports abstract classes and final methods.

// Class inheritance
class Animal {
    public function __construct(
        protected string $name
    ) {}

    public function speak(): string {
        return "{$this->name} makes a sound";
    }
}

class Dog extends Animal {
    public function speak(): string {
        return "{$this->name} barks";
    }
}

// Abstract classes
abstract class Shape {
    abstract public function area(): float;
}

// Interfaces
interface Serializable {
    public function serialize(): string;
}

interface Loggable {
    public function log(): void;
}

// Implementing multiple interfaces
class User extends Animal implements Serializable, Loggable {
    public function serialize(): string { return json_encode($this); }
    public function log(): void { error_log($this->name); }
}

// Traits — horizontal code reuse
trait HasTimestamps {
    public \DateTime $createdAt;
    public \DateTime $updatedAt;

    public function touch(): void {
        $this->updatedAt = new \DateTime();
    }
}

class Post {
    use HasTimestamps;
}

// Readonly classes (PHP 8.2+)
readonly class Point {
    public function __construct(
        public float $x,
        public float $y,
    ) {}
}

Inheritance & Composition

Single inheritance with modules (mixins) for composition. Ruby strongly favors composition over inheritance.

# Class inheritance
class Animal
  attr_reader :name

  def initialize(name)
    @name = name
  end

  def speak
    "#{name} makes a sound"
  end
end

class Dog < Animal
  def speak
    "#{name} barks"
  end
end

# Super
class Puppy < Dog
  def initialize(name)
    super(name)
    @young = true
  end
end

# Modules (mixins) — composition
module Serializable
  def to_json
    JSON.generate(to_h)
  end
end

module Loggable
  def log
    puts "#{self.class}: #{inspect}"
  end
end

class User < Animal
  include Serializable  # Instance methods
  include Loggable
  extend ClassMethods   # Class methods

  def to_h
    { name: name }
  end
end

# Abstract-like pattern (no built-in abstract)
module Abstract
  def self.included(klass)
    klass.instance_method(:perform)
  rescue NameError
    raise NotImplementedError, "#{klass} must implement #perform"
  end
end

# Open classes — extend existing classes
class String
  def shout
    upcase + '!!!'
  end
end
'hello'.shout  # "HELLO!!!"

Inheritance & Composition

Go has no classes or inheritance. Uses struct embedding for composition and interfaces for polymorphism. “Composition over inheritance” is idiomatic.

// Struct embedding (composition)
type Animal struct {
    Name string
}
func (a Animal) Speak() string {
    return a.Name + " makes a sound"
}

type Dog struct {
    Animal // embedded — Dog "inherits" Speak()
    Breed string
}

// Override by defining same method
func (d Dog) Speak() string {
    return d.Name + " barks"
}

// Interfaces (implicit satisfaction)
type Speaker interface {
    Speak() string
}

type Writer interface {
    Write(data []byte) (int, error)
}

// Compose interfaces
type ReadWriter interface {
    Reader
    Writer
}

// Any type with Speak() satisfies Speaker
func announce(s Speaker) {
    fmt.Println(s.Speak())
}

// Embedding interfaces in structs
type Logger struct {
    Writer // embed interface
}

// Empty interface (any type)
func process(v any) { /* ... */ }

Inheritance & Composition

Rust has no class inheritance. Uses traits for shared behavior, generics for polymorphism, and composition via struct fields.

// Traits (shared behavior)
trait Speak {
    fn speak(&self) -> String;
}

struct Dog { name: String }
impl Speak for Dog {
    fn speak(&self) -> String {
        format!("{} barks", self.name)
    }
}

// Default implementations
trait Greet {
    fn name(&self) -> &str;
    fn greet(&self) -> String {
        format!("Hello, {}!", self.name())
    }
}

// Trait inheritance (supertraits)
trait Animal: Speak + std::fmt::Display {}

// Composition via fields
struct PetOwner {
    pet: Dog,
    name: String,
}

// Generic bounds (static dispatch)
fn announce(speaker: &impl Speak) {
    println!("{}", speaker.speak());
}

// Trait objects (dynamic dispatch)
fn announce_dyn(speaker: &dyn Speak) {
    println!("{}", speaker.speak());
}

// Derive macros (auto-implement traits)
#[derive(Debug, Clone, PartialEq)]
struct Point { x: f64, y: f64 }

Inheritance & Composition

Supports single and multiple inheritance, virtual functions for polymorphism, and CRTP for static polymorphism.

// Class inheritance
class Animal {
public:
    std::string name;
    Animal(std::string n) : name(std::move(n)) {}
    virtual std::string speak() {
        return name + " makes a sound";
    }
    virtual ~Animal() = default; // virtual destructor
};

class Dog : public Animal {
public:
    using Animal::Animal;
    std::string speak() override {
        return name + " barks";
    }
};

// Abstract class (pure virtual)
class Shape {
public:
    virtual double area() = 0;
    virtual ~Shape() = default;
};

// Multiple inheritance
class Swimmer { public: void swim(); };
class Flyer   { public: void fly(); };
class Duck : public Animal, public Swimmer, public Flyer {
    using Animal::Animal;
};

// Composition (preferred)
class Engine { public: void start(); };
class Car {
    Engine engine; // composed, not inherited
public:
    void start() { engine.start(); }
};

// CRTP (static polymorphism)
template <typename Derived>
class Base {
    void doWork() { static_cast<Derived*>(this)->impl(); }
};

Inheritance & Composition

Single class inheritance with interfaces for multiple behavior contracts. Abstract classes, sealed classes, and extension methods.

// Class inheritance
class Animal {
    public string Name { get; }
    public Animal(string name) => Name = name;
    public virtual string Speak() => $"{Name} makes a sound";
}

class Dog : Animal {
    public Dog(string name) : base(name) {}
    public override string Speak() => $"{Name} barks";
}

// Abstract classes
abstract class Shape {
    public abstract double Area();
    public string Describe() => $"Area: {Area()}";
}

// Interfaces (multiple)
interface ISerializable { string ToJson(); }
interface IPrintable { void Print(); }

class Report : ISerializable, IPrintable {
    public string ToJson() => "{}";
    public void Print() => Console.WriteLine(ToJson());
}

// Sealed (prevent further inheritance)
sealed class Singleton : Animal {
    public Singleton() : base("single") {}
}

// Extension methods (add behavior without inheritance)
static class StringExt {
    public static string Shout(this string s) => s.ToUpper() + "!";
}
// "hello".Shout() => "HELLO!"

Inheritance & Composition

Single class inheritance with protocols for composition. Protocol extensions provide default implementations. Structs (value types) don’t support inheritance.

// Class inheritance
class Animal {
    let name: String
    init(name: String) { self.name = name }
    func speak() -> String { "\(name) makes a sound" }
}

class Dog: Animal {
    override func speak() -> String { "\(name) barks" }
}

// Protocols (composition)
protocol Drawable {
    func draw()
}
protocol Printable {
    func printOut()
}

class Canvas: Drawable, Printable {
    func draw() { /* ... */ }
    func printOut() { /* ... */ }
}

// Protocol extensions (default implementations)
protocol Greetable {
    var name: String { get }
}
extension Greetable {
    func greet() -> String { "Hello, \(name)!" }
}

// Protocol-oriented programming
protocol Shape {
    func area() -> Double
}
extension Shape {
    func describe() -> String { "Area: \(area())" }
}

// Final (prevent subclassing)
final class Singleton { /* cannot be subclassed */ }

// Structs use protocols, not inheritance
struct Point: Equatable { var x: Double; var y: Double }

Inheritance & Composition

Single class inheritance (classes are final by default). Interfaces with default methods, sealed hierarchies, and delegation for composition.

// Classes are final by default — use `open`
open class Animal(val name: String) {
    open fun speak(): String = "$name makes a sound"
}

class Dog(name: String) : Animal(name) {
    override fun speak(): String = "$name barks"
}

// Abstract classes
abstract class Shape {
    abstract fun area(): Double
    fun describe() = "Area: ${area()}"
}

// Interfaces (with default methods)
interface Serializable {
    fun toJson(): String
}
interface Printable {
    fun printOut() { println(toJson()) }
    fun toJson(): String
}

class Report : Serializable, Printable {
    override fun toJson() = "{}"
}

// Sealed classes (restricted hierarchy)
sealed class Result {
    data class Success(val data: String) : Result()
    data class Error(val msg: String) : Result()
}

// Delegation (composition pattern)
interface Closer { fun close() }
class FileCloser : Closer { override fun close() {} }

class Resource(closer: Closer) : Closer by closer
// Resource delegates close() to closer

Inheritance & Composition

Supports single and multiple inheritance with MRO (Method Resolution Order). Mixins and protocols (structural typing) for composition.

# Single inheritance
class Animal:
    def __init__(self, name: str):
        self.name = name
    def speak(self) -> str:
        return f"{self.name} makes a sound"

class Dog(Animal):
    def speak(self) -> str:
        return f"{self.name} barks"

# Multiple inheritance
class Swimmer:
    def swim(self): return "swimming"

class Flyer:
    def fly(self): return "flying"

class Duck(Animal, Swimmer, Flyer):
    pass

# Super and MRO
class Puppy(Dog):
    def __init__(self, name: str):
        super().__init__(name)
        self.young = True

# Abstract base classes
from abc import ABC, abstractmethod

class Shape(ABC):
    @abstractmethod
    def area(self) -> float: ...

# Protocols (structural typing, Python 3.8+)
from typing import Protocol

class Drawable(Protocol):
    def draw(self) -> None: ...
# Any class with draw() satisfies Drawable

Functional Patterns

First-class functions, closures, and a rich set of array methods for functional programming.

// Higher-order functions
const apply = (fn, x) => fn(x)
const double = (x) => x * 2
apply(double, 5) // 10

// Map, filter, reduce
const nums = [1, 2, 3, 4, 5]
const squared = nums.map((x) => x * x)
const evens = nums.filter((x) => x % 2 === 0)
const sum = nums.reduce((acc, x) => acc + x, 0)

// Function composition
const compose = (f, g) => (x) => f(g(x))
const addOne = (x) => x + 1
const doubleAndAdd = compose(addOne, double)

// Closures
function counter(start = 0) {
  let count = start
  return { inc: () => ++count, get: () => count }
}

// Currying
const add = (a) => (b) => a + b
const add5 = add(5)
add5(3) // 8

// Chaining
const result = [1, 2, 3, 4, 5]
  .filter((x) => x > 2)
  .map((x) => x * 10)
  .reduce((a, b) => a + b, 0)

Functional Patterns

All JavaScript functional patterns with full type safety. Generics enable strongly-typed higher-order functions.

// Typed higher-order functions
function map<T, U>(arr: T[], fn: (x: T) => U): U[] {
  return arr.map(fn)
}

// Typed composition
const pipe = <T>(...fns: Array<(x: T) => T>) =>
  (x: T) => fns.reduce((v, fn) => fn(v), x)

const transform = pipe<number>(
  (x) => x * 2,
  (x) => x + 1,
)

// Currying with types
const add = (a: number) => (b: number): number => a + b

// Discriminated unions (algebraic data types)
type Result<T, E> =
  | { ok: true; value: T }
  | { ok: false; error: E }

function map<T, U, E>(
  result: Result<T, E>,
  fn: (v: T) => U,
): Result<U, E> {
  return result.ok
    ? { ok: true, value: fn(result.value) }
    : result
}

// Readonly for immutability
const nums: readonly number[] = [1, 2, 3]
type Immutable<T> = { readonly [K in keyof T]: T[K] }

Functional Patterns

PHP supports closures, higher-order functions, and functional array operations.

// Higher-order functions
function apply(callable $fn, int $x): int {
    return $fn($x);
}
$double = fn(int $x) => $x * 2;
apply($double, 5);  // 10

// Array functional operations
$nums = [1, 2, 3, 4, 5];
$squared = array_map(fn($x) => $x ** 2, $nums);
$evens = array_filter($nums, fn($x) => $x % 2 === 0);
$sum = array_reduce($nums, fn($carry, $x) => $carry + $x, 0);

// Closures with captured variables
function counter(int $start = 0): Closure {
    $count = $start;
    return function () use (&$count): int {
        return ++$count;
    };
}
$inc = counter();
$inc();  // 1
$inc();  // 2

// Currying
$add = fn(int $a) => fn(int $b) => $a + $b;
$add5 = $add(5);
$add5(3);  // 8

// Pipe / compose (manual)
function pipe(mixed $value, callable ...$fns): mixed {
    foreach ($fns as $fn) {
        $value = $fn($value);
    }
    return $value;
}

$result = pipe(
    5,
    fn($x) => $x * 2,
    fn($x) => $x + 1,
    fn($x) => "Result: $x",
);
// "Result: 11"

// First-class callable syntax (PHP 8.1+)
$lengths = array_map(strlen(...), ['hello', 'world']);

Functional Patterns

Ruby has strong functional programming support with blocks, procs, lambdas, and Enumerable methods.

# Higher-order functions
def apply(fn, x)
  fn.call(x)
end
double = ->(x) { x * 2 }
apply(double, 5)  # 10

# Map, select, reduce
nums = [1, 2, 3, 4, 5]
squared = nums.map { |x| x ** 2 }
evens = nums.select(&:even?)
sum = nums.reduce(:+)

# Method reference with &
['hello', 'world'].map(&:upcase)  # ["HELLO", "WORLD"]

# Closures
def counter(start = 0)
  count = start
  -> { count += 1 }
end
inc = counter
inc.call  # 1
inc.call  # 2

# Currying
add = ->(a, b) { a + b }
add5 = add.curry.(5)
add5.(3)  # 8

# Chaining with Enumerable
result = (1..10)
  .select(&:odd?)
  .map { |x| x ** 2 }
  .reject { |x| x > 50 }
  .sum

# Lazy evaluation
(1..Float::INFINITY)
  .lazy
  .select(&:odd?)
  .map { |x| x ** 2 }
  .first(5)  # [1, 9, 25, 49, 81]

# Proc composition (Ruby 2.6+)
double = ->(x) { x * 2 }
add_one = ->(x) { x + 1 }
double_then_add = add_one << double  # compose
double_then_add.(5)  # 11

Functional Patterns

Functions are first-class. Closures and higher-order functions are supported, but Go favours explicit loops over functional chaining.

// First-class functions
func apply(fn func(int) int, x int) int {
    return fn(x)
}
double := func(x int) int { return x * 2 }
apply(double, 5) // 10

// Closures
func counter(start int) func() int {
    count := start
    return func() int {
        count++
        return count
    }
}
inc := counter(0)
inc() // 1
inc() // 2

// Higher-order filter (manual, no generics before 1.18)
func filter[T any](s []T, fn func(T) bool) []T {
    var result []T
    for _, v := range s {
        if fn(v) {
            result = append(result, v)
        }
    }
    return result
}

// Map with generics (Go 1.18+)
func mapSlice[T, U any](s []T, fn func(T) U) []U {
    result := make([]U, len(s))
    for i, v := range s {
        result[i] = fn(v)
    }
    return result
}

evens := filter([]int{1,2,3,4}, func(x int) bool {
    return x%2 == 0
})

Functional Patterns

Iterators, closures, and Option/Result combinators are core to idiomatic Rust. Zero-cost abstractions make functional style performant.

// Closures
let double = |x: i32| x * 2;
let add = |a: i32, b: i32| a + b;

// Iterator combinators
let nums = vec![1, 2, 3, 4, 5];
let squared: Vec<i32> = nums.iter().map(|x| x * x).collect();
let evens: Vec<&i32> = nums.iter().filter(|x| *x % 2 == 0).collect();
let sum: i32 = nums.iter().sum();

// Chaining
let result: i32 = (0..100)
    .filter(|x| x % 2 == 0)
    .map(|x| x * x)
    .take(10)
    .sum();

// Option combinators
let name: Option<String> = Some("Alice".into());
let upper = name.map(|n| n.to_uppercase());
let len = name.and_then(|n| if n.is_empty() { None } else { Some(n.len()) });
let fallback = name.unwrap_or("default".into());

// Result combinators
let parsed: Result<i32, _> = "42".parse();
let doubled = parsed.map(|n| n * 2);
let chained = parsed.and_then(|n| if n > 0 { Ok(n) } else { Err("negative") });

// Higher-order functions
fn apply(f: impl Fn(i32) -> i32, x: i32) -> i32 { f(x) }

Functional Patterns

Lambdas, <algorithm>, <ranges>, and std::function enable functional patterns. C++20 ranges add composable pipelines.

// Lambdas
auto double_val = [](int x) { return x * 2; };
auto add = [](int a, int b) { return a + b; };

// Capture by value and reference
int offset = 10;
auto adder = [offset](int x) { return x + offset; };
auto inc = [&offset]() { offset++; };

// STL algorithms
std::vector<int> nums = {1, 2, 3, 4, 5};

std::vector<int> squared;
std::transform(nums.begin(), nums.end(),
    std::back_inserter(squared),
    [](int x) { return x * x; });

auto sum = std::accumulate(nums.begin(), nums.end(), 0);

// C++20 Ranges (composable pipelines)
#include <ranges>
auto result = nums
    | std::views::filter([](int x) { return x % 2 == 0; })
    | std::views::transform([](int x) { return x * x; });

// std::function (type-erased callable)
std::function<int(int)> fn = [](int x) { return x + 1; };

// Higher-order function
template <typename F>
auto apply(F fn, int x) { return fn(x); }

// std::optional chaining
std::optional<int> val = 42;
auto doubled = val.transform([](int x) { return x * 2; });

Functional Patterns

LINQ, lambdas, delegates, and expression-bodied members bring functional style to C#.

// Lambdas and delegates
Func<int, int> double = x => x * 2;
Func<int, int, int> add = (a, b) => a + b;
Action<string> log = msg => Console.WriteLine(msg);

// LINQ (functional collection processing)
var nums = new[] { 1, 2, 3, 4, 5 };
var squared = nums.Select(x => x * x);
var evens = nums.Where(x => x % 2 == 0);
var sum = nums.Aggregate(0, (acc, x) => acc + x);

// Chaining
var result = Enumerable.Range(0, 100)
    .Where(x => x % 2 == 0)
    .Select(x => x * x)
    .Take(10)
    .Sum();

// Higher-order functions
T Apply<T>(Func<T, T> fn, T value) => fn(value);

// Pattern matching as expression
string Describe(object obj) => obj switch {
    int n when n > 0 => "positive",
    int n => "non-positive",
    string s => $"string: {s}",
    _ => "unknown"
};

// Immutable records
record Point(int X, int Y);
var p1 = new Point(1, 2);
var p2 = p1 with { X = 10 }; // non-destructive mutation

// Local functions
int Factorial(int n) {
    int Go(int x, int acc) => x <= 1 ? acc : Go(x - 1, acc * x);
    return Go(n, 1);
}

Functional Patterns

First-class closures, trailing closure syntax, and rich collection methods. Enums with associated values for algebraic data types.

// Closures
let double = { (x: Int) -> Int in x * 2 }
let add: (Int, Int) -> Int = { $0 + $1 }

// Collection methods
let nums = [1, 2, 3, 4, 5]
let squared = nums.map { $0 * $0 }
let evens = nums.filter { $0 % 2 == 0 }
let sum = nums.reduce(0, +)

// Chaining
let result = (0..<100)
    .filter { $0 % 2 == 0 }
    .map { $0 * $0 }
    .prefix(10)
    .reduce(0, +)

// Optional chaining (like Maybe monad)
let name: String? = "Alice"
let upper = name.map { $0.uppercased() }
let len = name.flatMap { $0.isEmpty ? nil : $0.count }

// Enums as algebraic data types
enum Result<T, E: Error> {
    case success(T)
    case failure(E)

    func map<U>(_ fn: (T) -> U) -> Result<U, E> {
        switch self {
        case .success(let v): return .success(fn(v))
        case .failure(let e): return .failure(e)
        }
    }
}

// Higher-order functions
func apply<T>(_ fn: (T) -> T, to value: T) -> T {
    fn(value)
}

Functional Patterns

First-class functions, extension functions, scope functions, and rich collection APIs. Kotlin blends OOP and FP naturally.

// Lambdas
val double = { x: Int -> x * 2 }
val add: (Int, Int) -> Int = { a, b -> a + b }

// Collection methods
val nums = listOf(1, 2, 3, 4, 5)
val squared = nums.map { it * it }
val evens = nums.filter { it % 2 == 0 }
val sum = nums.reduce { acc, x -> acc + x }

// Chaining
val result = (0 until 100)
    .filter { it % 2 == 0 }
    .map { it * it }
    .take(10)
    .sum()

// Scope functions
val user = User("Alice", 30).apply {
    println(name)  // configure
}
val len = name?.let { it.length } ?: 0

// Sealed classes (algebraic data types)
sealed class Result<out T> {
    data class Ok<T>(val value: T) : Result<T>()
    data class Err(val msg: String) : Result<Nothing>()
}
fun <T, U> Result<T>.map(fn: (T) -> U): Result<U> =
    when (this) {
        is Result.Ok -> Result.Ok(fn(value))
        is Result.Err -> this
    }

// Higher-order + extension functions
fun <T> T.applyFn(fn: (T) -> T): T = fn(this)
5.applyFn { it * 2 } // 10

Functional Patterns

First-class functions, comprehensions, generators, and functools for functional programming.

# Higher-order functions
def apply(fn, x):
    return fn(x)

double = lambda x: x * 2
apply(double, 5)  # 10

# Map, filter, reduce
from functools import reduce

nums = [1, 2, 3, 4, 5]
squared = list(map(lambda x: x * x, nums))
evens = list(filter(lambda x: x % 2 == 0, nums))
total = reduce(lambda a, b: a + b, nums, 0)

# List comprehensions (preferred over map/filter)
squared = [x * x for x in nums]
evens = [x for x in nums if x % 2 == 0]

# Generator expressions (lazy)
gen = (x * x for x in range(1_000_000))

# Closures
def counter(start=0):
    count = start
    def inc():
        nonlocal count
        count += 1
        return count
    return inc

# Partial application
from functools import partial
add = lambda a, b: a + b
add5 = partial(add, 5)

# Decorators (higher-order functions)
def log(fn):
    def wrapper(*args, **kwargs):
        print(f"Calling {fn.__name__}")
        return fn(*args, **kwargs)
    return wrapper

Concurrency

Single-threaded event loop with async/await. Web Workers and worker_threads provide true parallelism.

// async/await — non-blocking I/O
async function fetchData() {
  const res = await fetch('/api/data')
  return res.json()
}

// Promise.all — concurrent requests
const [users, posts] = await Promise.all([
  fetch('/api/users').then(r => r.json()),
  fetch('/api/posts').then(r => r.json()),
])

// Promise.allSettled — don't fail on one rejection
const results = await Promise.allSettled([
  fetch('/api/a'),
  fetch('/api/b'),
])

// setTimeout / setInterval
setTimeout(() => console.log('delayed'), 1000)
// Worker threads (Node.js) — true parallelism
import { Worker, isMainThread, parentPort } from 'worker_threads'

if (isMainThread) {
  const worker = new Worker(new URL(import.meta.url))
  worker.on('message', (msg) => console.log(msg))
  worker.postMessage('start')
} else {
  parentPort.on('message', () => {
    parentPort.postMessage('done')
  })
}

// Web Workers (browser) — similar API
// const worker = new Worker('worker.js')

Concurrency

Same event-loop model as JavaScript, with full type safety for async patterns.

// async/await with typed returns
async function fetchUser(id: number): Promise<User> {
  const res = await fetch(`/api/users/${id}`)
  if (!res.ok) throw new Error(`HTTP ${res.status}`)
  return res.json() as Promise<User>
}

// Promise.all — typed tuple return
const [users, posts] = await Promise.all([
  fetchUsers(),   // Promise<User[]>
  fetchPosts(),   // Promise<Post[]>
])
// users: User[], posts: Post[]

// AbortController — cancellation
const controller = new AbortController()
const res = await fetch('/api/data', {
  signal: controller.signal,
})
controller.abort() // Cancel the request

// Async iterators
async function* generateIds(): AsyncGenerator<number> {
  let id = 0
  while (true) {
    yield id++
    await new Promise(r => setTimeout(r, 100))
  }
}

for await (const id of generateIds()) {
  if (id > 10) break
  console.log(id)
}

Concurrency

PHP is traditionally single-threaded and request-scoped. Concurrency is achieved through process-level parallelism, async libraries, or Fibers (PHP 8.1+).

// Fibers (PHP 8.1+) — cooperative multitasking
$fiber = new Fiber(function (): void {
    $value = Fiber::suspend('paused');
    echo "Resumed with: $value";
});

$result = $fiber->start();    // 'paused'
$fiber->resume('hello');      // 'Resumed with: hello'

// curl_multi — concurrent HTTP requests
$handles = [];
$mh = curl_multi_init();

foreach ($urls as $url) {
    $ch = curl_init($url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_multi_add_handle($mh, $ch);
    $handles[] = $ch;
}

do {
    curl_multi_exec($mh, $running);
    curl_multi_select($mh);
} while ($running > 0);
// ReactPHP — event-driven async I/O
$loop = React\EventLoop\Loop::get();
$browser = new React\Http\Browser();

$browser->get('https://api.example.com/data')
    ->then(function ($response) {
        echo $response->getBody();
    });

// Parallel execution with promises
React\Async\parallel([
    fn() => $browser->get('/api/users'),
    fn() => $browser->get('/api/posts'),
])->then(function ($responses) { });

// AMPHP — alternative async framework
// Swoole / OpenSwoole — coroutine-based server
// Laravel Octane — high-performance app server (Swoole/RoadRunner)

Concurrency

GIL (GVL) limits true parallelism in CRuby. Ractors (Ruby 3.0+) provide actor-based parallelism. Fibers enable cooperative concurrency.

# Threads — concurrent but GVL-limited for CPU
threads = 5.times.map do |i|
  Thread.new { puts "Thread #{i}" }
end
threads.each(&:join)

# Mutex — thread safety
mutex = Mutex.new
counter = 0
10.times.map do
  Thread.new { mutex.synchronize { counter += 1 } }
end.each(&:join)

# Fibers — cooperative concurrency
fiber = Fiber.new do
  Fiber.yield 'first'
  Fiber.yield 'second'
  'third'
end
fiber.resume  # 'first'
fiber.resume  # 'second'
fiber.resume  # 'third'
# Ractors (Ruby 3.0+) — true parallelism
ractors = 4.times.map do |i|
  Ractor.new(i) do |n|
    (1..10000).sum * n
  end
end
results = ractors.map(&:take)

# Fiber Scheduler (Ruby 3.0+) — async I/O
# Used by async gem for non-blocking I/O
require 'async'

Async do |task|
  task.async { fetch_url('https://example.com/a') }
  task.async { fetch_url('https://example.com/b') }
end

# Sidekiq — background job processing
class HardWorker
  include Sidekiq::Job
  def perform(name, count)
    # Runs in a separate process
  end
end
HardWorker.perform_async('Bob', 5)

Concurrency

Goroutines and channels — Go’s concurrency model is built into the language. Lightweight green threads with CSP-style communication.

// Goroutines — lightweight concurrent functions
go func() {
    fmt.Println("running concurrently")
}()

// Channels — communicate between goroutines
ch := make(chan string)
go func() {
    ch <- "hello"  // Send
}()
msg := <-ch  // Receive

// Buffered channels
ch := make(chan int, 10)

// Select — multiplex channels
select {
case msg := <-ch1:
    fmt.Println(msg)
case msg := <-ch2:
    fmt.Println(msg)
case <-time.After(1 * time.Second):
    fmt.Println("timeout")
}
// sync.WaitGroup — wait for goroutines
var wg sync.WaitGroup
for _, url := range urls {
    wg.Add(1)
    go func(u string) {
        defer wg.Done()
        fetch(u)
    }(url)
}
wg.Wait()

// sync.Mutex — protect shared state
var mu sync.Mutex
mu.Lock()
counter++
mu.Unlock()

// errgroup — goroutines with error handling
g, ctx := errgroup.WithContext(ctx)
g.Go(func() error { return fetchA(ctx) })
g.Go(func() error { return fetchB(ctx) })
err := g.Wait()

Concurrency

Fearless concurrency — the borrow checker prevents data races at compile time. Supports threads, async/await, and message passing.

// Threads
use std::thread;

let handle = thread::spawn(|| {
    println!("Hello from thread!");
});
handle.join().unwrap();

// Channels (mpsc — multiple producer, single consumer)
use std::sync::mpsc;

let (tx, rx) = mpsc::channel();
thread::spawn(move || {
    tx.send("hello").unwrap();
});
println!("{}", rx.recv().unwrap());

// Shared state with Mutex + Arc
use std::sync::{Arc, Mutex};

let counter = Arc::new(Mutex::new(0));
let mut handles = vec![];
for _ in 0..10 {
    let counter = Arc::clone(&counter);
    handles.push(thread::spawn(move || {
        *counter.lock().unwrap() += 1;
    }));
}
for h in handles { h.join().unwrap(); }
// async/await (with Tokio runtime)
use tokio;

#[tokio::main]
async fn main() {
    let (a, b) = tokio::join!(
        fetch_data("url_a"),
        fetch_data("url_b"),
    );

    // Spawn concurrent tasks
    tokio::spawn(async { do_work().await });
}

// Rayon — data parallelism
use rayon::prelude::*;
let sum: i32 = (0..1000).into_par_iter().sum();

Concurrency

OS threads with std::thread, atomics, and mutexes. C++20 adds coroutines. No built-in async runtime.

#include <thread>
#include <mutex>
#include <future>

// Threads
std::thread t([] {
    std::cout << "Hello from thread\n";
});
t.join();

// Mutex — protect shared state
std::mutex mtx;
{
    std::lock_guard<std::mutex> lock(mtx);
    shared_data++;
}

// async/future — launch async tasks
auto future = std::async(std::launch::async, [] {
    return compute_result();
});
auto result = future.get();  // Blocks until ready
// Atomics — lock-free concurrency
#include <atomic>
std::atomic<int> counter{0};
counter.fetch_add(1);

// Condition variables
std::condition_variable cv;
std::unique_lock<std::mutex> lock(mtx);
cv.wait(lock, [] { return ready; });

// C++20 coroutines (low-level)
#include <coroutine>
// Requires a custom promise_type / awaitable
// Libraries: cppcoro, folly::coro

// Parallel algorithms (C++17)
#include <algorithm>
#include <execution>
std::sort(std::execution::par, v.begin(), v.end());

Concurrency

Task-based async/await with the Task Parallel Library (TPL). First-class async support throughout the framework.

// async/await — non-blocking I/O
async Task<string> FetchDataAsync(string url)
{
    using var client = new HttpClient();
    return await client.GetStringAsync(url);
}

// Concurrent tasks
var tasks = new[]
{
    FetchDataAsync("/api/a"),
    FetchDataAsync("/api/b"),
};
string[] results = await Task.WhenAll(tasks);

// Cancellation
var cts = new CancellationTokenSource(TimeSpan.FromSeconds(5));
await DoWorkAsync(cts.Token);
// Parallel — CPU parallelism
Parallel.ForEach(items, item =>
{
    Process(item);
});

// PLINQ — parallel LINQ
var results = data
    .AsParallel()
    .Where(x => x > 0)
    .Select(x => x * 2)
    .ToList();

// Channels — producer/consumer
var channel = Channel.CreateBounded<int>(100);
// Producer
await channel.Writer.WriteAsync(42);
// Consumer
var item = await channel.Reader.ReadAsync();

// Lock / SemaphoreSlim
private readonly SemaphoreSlim _semaphore = new(1, 1);
await _semaphore.WaitAsync();
try { /* critical section */ }
finally { _semaphore.Release(); }

Concurrency

Structured concurrency with async/await, actors, and task groups. Built into the language since Swift 5.5.

// async/await
func fetchData() async throws -> Data {
    let (data, _) = try await URLSession.shared.data(
        from: URL(string: "https://api.example.com")!
    )
    return data
}

// Concurrent tasks with async let
async let users = fetchUsers()
async let posts = fetchPosts()
let (u, p) = try await (users, posts)

// Task groups — dynamic concurrency
let results = try await withThrowingTaskGroup(of: String.self) { group in
    for url in urls {
        group.addTask { try await fetch(url) }
    }
    var collected: [String] = []
    for try await result in group {
        collected.append(result)
    }
    return collected
}
// Actors — safe shared mutable state
actor Counter {
    private var count = 0

    func increment() { count += 1 }
    func value() -> Int { count }
}

let counter = Counter()
await counter.increment()
print(await counter.value())

// MainActor — run on main thread (UI)
@MainActor
func updateUI() {
    label.text = "Updated"
}

// Task — launch unstructured concurrent work
Task {
    let data = try await fetchData()
    await updateUI(with: data)
}

Concurrency

Coroutines — lightweight, structured concurrency built on top of the JVM. First-class support via kotlinx.coroutines.

import kotlinx.coroutines.*

// Launch a coroutine
fun main() = runBlocking {
    launch {
        delay(1000)
        println("World!")
    }
    println("Hello,")
}

// async/await — concurrent decomposition
suspend fun fetchBoth(): Pair<User, Posts> = coroutineScope {
    val user = async { fetchUser() }
    val posts = async { fetchPosts() }
    Pair(user.await(), posts.await())
}

// Structured concurrency — parent waits for children
coroutineScope {
    launch { doTaskA() }
    launch { doTaskB() }
} // Both complete before continuing
// Flow — reactive streams (cold)
import kotlinx.coroutines.flow.*

fun numbers(): Flow<Int> = flow {
    for (i in 1..5) {
        delay(100)
        emit(i)
    }
}

numbers()
    .filter { it % 2 == 0 }
    .map { it * 10 }
    .collect { println(it) }

// Channels — hot communication between coroutines
val channel = Channel<Int>()
launch { channel.send(42) }
val value = channel.receive()

// Dispatchers — control thread pool
withContext(Dispatchers.IO) { readFile() }
withContext(Dispatchers.Default) { compute() }
withContext(Dispatchers.Main) { updateUI() }

Concurrency

GIL limits true thread parallelism for CPU work. Use asyncio for I/O concurrency, multiprocessing for CPU parallelism.

# asyncio — async/await for I/O concurrency
import asyncio

async def fetch_data(url: str) -> str:
    # simulated async I/O
    await asyncio.sleep(1)
    return f"data from {url}"

async def main():
    # Run concurrently
    results = await asyncio.gather(
        fetch_data("/api/a"),
        fetch_data("/api/b"),
        fetch_data("/api/c"),
    )
    print(results)

asyncio.run(main())
# Threading — concurrent I/O (GIL limits CPU work)
from concurrent.futures import ThreadPoolExecutor

with ThreadPoolExecutor(max_workers=4) as pool:
    futures = [pool.submit(fetch, url) for url in urls]
    results = [f.result() for f in futures]

# Multiprocessing — true CPU parallelism (separate processes)
from multiprocessing import Pool

with Pool(4) as pool:
    results = pool.map(cpu_heavy_task, data)

# Python 3.13+ free-threading (experimental)
# Run without GIL: python3.13t -X gil=0 script.py

Modules & Imports

ES Modules (ESM) are the standard. CommonJS (CJS) is legacy but still used in Node.js. Bundlers like Vite, esbuild, and webpack handle bundling for the browser.

// Named exports
export const PI = 3.14
export function add(a, b) { return a + b }

// Default export
export default class App {}

// Named imports
import { add, PI } from './math.js'

// Default import
import App from './App.js'

// Rename imports
import { add as sum } from './math.js'

// Import everything
import * as math from './math.js'

// Dynamic import (code splitting)
const module = await import('./heavy.js')

// Re-export
export { add } from './math.js'
export { default } from './App.js'

// CommonJS (Node.js legacy)
const fs = require('fs')
module.exports = { add }

Modules & Imports

Uses ES Modules with additional type-only imports. TypeScript compiles to CJS or ESM depending on tsconfig.json. Supports path aliases and declaration files.

// Named exports with types
export const PI: number = 3.14
export function add(a: number, b: number): number {
  return a + b
}
export interface User {
  name: string
  age: number
}

// Default export
export default class App {}

// Named imports
import { add, PI, type User } from './math.ts'

// Type-only import (erased at compile time)
import type { User } from './types.ts'

// Namespace import
import * as math from './math.ts'

// Dynamic import
const mod = await import('./heavy.ts')

// Re-export
export { add } from './math.ts'
export type { User } from './types.ts'

// Ambient module declarations (*.d.ts)
declare module '*.css' {
  const styles: Record<string, string>
  export default styles
}

Modules & Imports

PHP uses namespaces and autoloading (PSR-4) via Composer. Files are included with require/include.

// Defining a namespace
namespace App\Models;

class User {
    public string $name;
}

// Importing classes
use App\Models\User;
use App\Services\{AuthService, MailService};  // Group use

// Aliasing
use App\Models\User as AppUser;

// Functions and constants
use function App\Helpers\formatDate;
use const App\Config\MAX_RETRIES;
// File inclusion (legacy, rarely needed with autoloading)
require 'config.php';        // Fatal error if missing
require_once 'config.php';   // Include only once
include 'optional.php';      // Warning if missing
include_once 'optional.php';

// PSR-4 autoloading via Composer (composer.json)
// "autoload": { "psr-4": { "App\\": "src/" } }
// Then: composer dump-autoload

// Using autoloaded classes — just use/import them
use App\Models\User;
$user = new User();

Modules & Imports

Ruby uses require to load files and modules for namespacing. Bundler and autoloading (Zeitwerk in Rails) manage dependencies.

# require — load a file once
require 'json'
require 'net/http'

# require_relative — load relative to current file
require_relative 'lib/helper'
require_relative '../config/database'

# Modules as namespaces
module MyApp
  module Models
    class User
      attr_accessor :name
    end
  end
end
user = MyApp::Models::User.new

# Include module methods
module Greetable
  def greet
    "Hello, #{name}!"
  end
end

class User
  include Greetable
  attr_reader :name
  def initialize(name) = @name = name
end
# Zeitwerk autoloading (Rails default)
# File: app/models/user.rb → class User
# File: app/services/auth/login.rb → class Auth::Login
# No require needed — autoloaded by convention

# Bundler — loads gems from Gemfile
require 'bundler/setup'
Bundler.require(:default)

# load — always re-executes file (useful for reloading)
load 'config.rb'

Modules & Imports

Go uses packages and modules. Each directory is a package. A go.mod file defines a module. Imports use the full module path. No circular imports allowed.

// Import standard library
import "fmt"
import "os"

// Multiple imports
import (
    "fmt"
    "strings"
    "net/http"
)

// Import third-party packages
import "github.com/gorilla/mux"

// Import with alias
import (
    f "fmt"
    _ "image/png" // side-effect import
)

// Package declaration (every file starts with this)
package main // or package mylib

// Exported vs unexported (capitalization)
func PublicFunc() {}  // exported (uppercase)
func privateFunc() {} // unexported (lowercase)

// Internal packages (restricted visibility)
// internal/helper.go — only parent module can import

// go.mod defines the module
// module github.com/user/myapp
// go 1.22
// require github.com/gorilla/mux v1.8.1

Modules & Imports

Rust uses a module tree rooted at lib.rs or main.rs. Modules can be inline or in separate files. Crates are the unit of compilation and distribution.

// Declare a module (looks for math.rs or math/mod.rs)
mod math;

// Use items from a module
use crate::math::add;
use crate::math::{add, subtract};

// Use with alias
use std::collections::HashMap as Map;

// Glob import (discouraged)
use std::io::prelude::*;

// Re-export
pub use crate::math::add;

// Nested paths
use std::{
    fs::File,
    io::{self, Read, Write},
};

// External crate (from Cargo.toml)
use serde::{Serialize, Deserialize};
use tokio::runtime::Runtime;

// Inline module
mod inner {
    pub fn helper() -> i32 { 42 }
}

// Visibility modifiers
pub fn public() {}           // public
pub(crate) fn crate_only() {} // crate-visible
fn private() {}               // module-private
pub(super) fn parent_only() {} // parent module

Modules & Imports

Traditionally uses header files (#include) with a preprocessor. C++20 introduced modules for faster compilation and better encapsulation. Libraries are linked at build time.

// Header includes (traditional)
#include <iostream>       // standard library
#include <vector>
#include "myheader.h"     // project header

// Include guards (in header files)
#ifndef MY_HEADER_H
#define MY_HEADER_H
// declarations...
#endif

// Or pragma once (widely supported)
#pragma once

// Namespaces
namespace mylib {
    void helper();
}
using namespace std; // import all (discouraged)
using std::vector;   // import specific

// C++20 Modules
// math.cppm (module interface)
export module math;
export int add(int a, int b) { return a + b; }

// main.cpp (consumer)
import math;
import <iostream>; // header unit

// Forward declarations
class MyClass; // declare without defining

// Static/shared libraries
// Linked via CMake: target_link_libraries(app mylib)
// Or pkg-config: pkg-config --libs libfoo

Modules & Imports

C# uses namespaces to organize code and assemblies for distribution. using directives import namespaces. Projects produce DLLs or executables via MSBuild.

// Import namespaces
using System;
using System.Collections.Generic;
using System.Linq;

// Import with alias
using Json = System.Text.Json.JsonSerializer;
using static System.Math; // import static members

// Global usings (C# 10, apply to entire project)
global using System.Collections.Generic;

// File-scoped namespace (C# 10)
namespace MyApp.Models;

public class User {
    public string Name { get; set; }
}

// Traditional namespace
namespace MyApp.Services {
    public class UserService {
        public User GetUser() => new();
    }
}

// Internal vs public (assembly-level visibility)
public class PublicApi {}    // visible to other assemblies
internal class InternalOnly {} // same assembly only

// Assemblies: each .csproj produces a DLL
// Reference other projects in .csproj:
// <ProjectReference Include="../MyLib/MyLib.csproj" />

Modules & Imports

Swift uses modules (frameworks/packages) as the unit of code distribution. All files in a target share the same namespace. Access control governs visibility.

// Import a module
import Foundation
import UIKit
import SwiftUI

// Import specific symbol
import struct Foundation.URL
import func Darwin.sqrt

// All files in a module share scope — no need to
// import sibling files within the same target

// Access control
public class PublicAPI {}       // visible everywhere
internal class DefaultAccess {} // same module (default)
fileprivate class FileOnly {}   // same file only
private class ScopeOnly {}     // enclosing scope

// Package (SPM) structure:
// Sources/
//   MyLib/
//     Models/User.swift
//     Services/Auth.swift
//   MyApp/
//     main.swift

// Expose module API in Package.swift:
// .target(name: "MyLib"),
// .target(name: "MyApp", dependencies: ["MyLib"])

// @_exported re-exports a module
@_exported import Foundation

Modules & Imports

Kotlin uses packages (like Java) and Gradle modules for project structure. Files don’t need to match directory structure, but conventionally do. Visibility modifiers control access.

// Package declaration
package com.myapp.models

// Imports
import java.util.Date
import kotlinx.coroutines.launch
import com.myapp.utils.Helper

// Import with alias
import com.myapp.models.User as AppUser

// Wildcard import
import kotlin.math.*

// Top-level declarations (no class needed)
fun helper() = "I'm a top-level function"
val PI = 3.14159

// Visibility modifiers
public class PublicApi          // visible everywhere (default)
internal class ModuleOnly       // same Gradle module
private class FilePrivate       // same file
// protected — subclasses only (class members)

// Gradle multi-module structure:
// app/
//   build.gradle.kts
// core/
//   build.gradle.kts
// settings.gradle.kts:
//   include(":app", ":core")

// Depend on another module:
// dependencies {
//     implementation(project(":core"))
// }

// Kotlin Multiplatform (expect/actual)
expect fun platformName(): String // common
actual fun platformName() = "JVM" // jvm

Modules & Imports

Every .py file is a module. Directories with __init__.py are packages. Use import to bring in modules. Distribution is done via wheels/sdists uploaded to PyPI.

# Import entire module
import os
import json

# Import specific names
from os.path import join, exists

# Import with alias
import numpy as np
from collections import defaultdict as dd

# Relative imports (within a package)
from . import sibling_module
from ..utils import helper

# Import everything (discouraged)
from math import *

# Dynamic import
import importlib
mod = importlib.import_module('my_module')

# Conditional import
try:
    import ujson as json
except ImportError:
    import json

# __init__.py controls package exports
# my_package/__init__.py:
# from .core import App
# from .utils import helper
# __all__ = ['App', 'helper']

Error Handling

Use try/catch/finally for synchronous and async error handling.

// Try / catch
try {
  JSON.parse('invalid');
} catch (error) {
  console.error('Parse failed:', error.message);
} finally {
  console.log('always runs');
}

// Throwing errors
function divide(a, b) {
  if (b === 0) throw new Error('Division by zero');
  return a / b;
}

// Async error handling
try {
  const res = await fetch('/api');
  const data = await res.json();
} catch (err) {
  console.error('Fetch failed:', err);
}

// Promise catch
fetch('/api')
  .then((res) => res.json())
  .catch((err) => console.error(err));

Error Handling

Same try/catch as JavaScript. Caught errors are unknown by default in strict mode.

// Try / catch with unknown error
try {
  JSON.parse('invalid');
} catch (error: unknown) {
  if (error instanceof SyntaxError) {
    console.error('Parse failed:', error.message);
  }
}

// Custom error classes
class AppError extends Error {
  constructor(
    message: string,
    public code: number
  ) {
    super(message);
    this.name = 'AppError';
  }
}

// Result pattern (no exceptions)
type Result<T, E = Error> =
  | { ok: true; value: T }
  | { ok: false; error: E };

function safeParse(json: string): Result<unknown> {
  try {
    return { ok: true, value: JSON.parse(json) };
  } catch (e) {
    return { ok: false, error: e as Error };
  }
}

Error Handling

PHP uses try/catch/finally for exceptions. PHP 8 introduced union catch types and match for cleaner handling.

// Try / catch / finally
try {
    $data = json_decode($input, true, 512, JSON_THROW_ON_ERROR);
} catch (\JsonException $e) {
    echo "JSON error: {$e->getMessage()}";
} finally {
    echo 'always runs';
}

// Catching multiple exception types
try {
    riskyOperation();
} catch (InvalidArgumentException | RuntimeException $e) {
    echo "Error: {$e->getMessage()}";
} catch (\Throwable $e) {
    echo "Unexpected: {$e->getMessage()}";
}

// Throwing exceptions
function divide(float $a, float $b): float {
    if ($b == 0) {
        throw new \DivisionByZeroError('Cannot divide by zero');
    }
    return $a / $b;
}

// Custom exceptions
class ValidationException extends \RuntimeException {
    public function __construct(
        public readonly array $errors,
        string $message = 'Validation failed',
    ) {
        parent::__construct($message);
    }
}

// Global error handler
set_exception_handler(function (\Throwable $e) {
    error_log($e->getMessage());
    http_response_code(500);
});

Error Handling

Ruby uses begin/rescue/ensure for exception handling. raise throws exceptions.

# begin / rescue / ensure
begin
  data = JSON.parse(input)
rescue JSON::ParserError => e
  puts "JSON error: #{e.message}"
rescue StandardError => e
  puts "Error: #{e.message}"
ensure
  puts 'always runs'
end

# Inline rescue (simple cases)
value = Integer(input) rescue 0

# Method-level rescue
def divide(a, b)
  a / b
rescue ZeroDivisionError
  puts 'Cannot divide by zero'
  nil
end

# Raising exceptions
def validate(age)
  raise ArgumentError, 'Age must be positive' if age < 0
  raise 'Something went wrong'  # RuntimeError
end

# Custom exceptions
class ValidationError < StandardError
  attr_reader :errors

  def initialize(errors, message = 'Validation failed')
    @errors = errors
    super(message)
  end
end

# Retry
attempts = 0
begin
  attempts += 1
  make_request
rescue Net::TimeoutError
  retry if attempts < 3
end

Error Handling

Errors are values returned from functions. No exceptions — check errors explicitly.

// Return and check errors
result, err := strconv.Atoi("42")
if err != nil {
    log.Fatal(err)
}

// Custom errors
type AppError struct {
    Code    int
    Message string
}

func (e *AppError) Error() string {
    return fmt.Sprintf("%d: %s", e.Code, e.Message)
}

// Wrapping errors
if err != nil {
    return fmt.Errorf("failed to parse: %w", err)
}

// Checking wrapped errors
if errors.Is(err, os.ErrNotExist) {
    fmt.Println("file not found")
}

// Defer for cleanup
f, err := os.Open("file.txt")
if err != nil {
    return err
}
defer f.Close()

Error Handling

No exceptions. Uses Result<T, E> and Option<T> types with the ? operator.

// Result type
fn read_file(path: &str) -> Result<String, io::Error> {
    let content = fs::read_to_string(path)?; // ? propagates error
    Ok(content)
}

// Handling Results
match result {
    Ok(value) => println!("Got: {}", value),
    Err(e) => eprintln!("Error: {}", e),
}

// unwrap (panics on error — use sparingly)
let value = result.unwrap();
let value = result.unwrap_or(default);
let value = result.unwrap_or_else(|e| handle(e));

// Custom error types
#[derive(Debug)]
enum AppError {
    NotFound(String),
    ParseError(std::num::ParseIntError),
}

impl From<std::num::ParseIntError> for AppError {
    fn from(e: std::num::ParseIntError) -> Self {
        AppError::ParseError(e)
    }
}

Error Handling

Uses try/catch with exceptions, or error codes and std::expected (C++23).

// Try / catch
try {
    throw std::runtime_error("something failed");
} catch (const std::runtime_error& e) {
    std::cerr << "Error: " << e.what() << "\n";
} catch (...) {
    std::cerr << "Unknown error\n";
}

// Custom exception
class AppError : public std::exception {
    std::string msg;
public:
    AppError(const std::string& m) : msg(m) {}
    const char* what() const noexcept override {
        return msg.c_str();
    }
};

// RAII for cleanup (no finally needed)
{
    std::ofstream file("out.txt");
    file << "data";
} // file automatically closed

// std::optional for "no value"
std::optional<int> find(const std::vector<int>& v, int x) {
    auto it = std::find(v.begin(), v.end(), x);
    if (it != v.end()) return *it;
    return std::nullopt;
}

Error Handling

Uses try/catch/finally with typed exceptions.

// Try / catch
try {
    var result = int.Parse("not a number");
} catch (FormatException ex) {
    Console.WriteLine($"Parse error: {ex.Message}");
} catch (Exception ex) {
    Console.WriteLine($"Error: {ex.Message}");
} finally {
    Console.WriteLine("always runs");
}

// Throwing exceptions
void Divide(int a, int b) {
    if (b == 0)
        throw new DivideByZeroException();
    return a / b;
}

// Custom exceptions
class AppException : Exception {
    public int Code { get; }
    public AppException(string msg, int code)
        : base(msg) => Code = code;
}

// Exception filters
catch (Exception ex) when (ex.Message.Contains("timeout")) {
    // handle timeout specifically
}

Error Handling

Uses do/try/catch with typed errors conforming to the Error protocol.

// Define errors
enum AppError: Error {
    case notFound(String)
    case invalidInput
}

// Throwing function
func loadFile(name: String) throws -> String {
    guard !name.isEmpty else {
        throw AppError.invalidInput
    }
    return "contents"
}

// Do / try / catch
do {
    let data = try loadFile(name: "test.txt")
    print(data)
} catch AppError.notFound(let name) {
    print("Not found: \(name)")
} catch {
    print("Error: \(error)")
}

// try? (returns optional)
let maybe = try? loadFile(name: "test.txt")

// try! (force unwrap, crashes on error)
let forced = try! loadFile(name: "safe.txt")

// Defer for cleanup
func process() {
    let file = openFile()
    defer { closeFile(file) }
    // work with file...
}

Error Handling

Uses try/catch/finally. All exceptions are unchecked. Result type for functional error handling.

// Try / catch
try {
    val n = "abc".toInt()
} catch (e: NumberFormatException) {
    println("Parse error: ${e.message}")
} catch (e: Exception) {
    println("Error: ${e.message}")
} finally {
    println("always runs")
}

// Try as expression
val number = try {
    input.toInt()
} catch (e: NumberFormatException) {
    -1
}

// Throwing
fun divide(a: Int, b: Int): Int {
    require(b != 0) { "Cannot divide by zero" }
    return a / b
}

// Result type
fun safeParse(s: String): Result<Int> = runCatching {
    s.toInt()
}

val result = safeParse("42")
    .getOrDefault(0)

// Custom exception
class AppException(msg: String, val code: Int)
    : Exception(msg)

Error Handling

Use try/except/finally. Python uses exceptions extensively.

# Try / except
try:
    result = 10 / 0
except ZeroDivisionError as e:
    print(f"Error: {e}")
finally:
    print("always runs")

# Multiple exceptions
try:
    data = json.loads(raw)
except (ValueError, KeyError) as e:
    print(f"Bad data: {e}")

# Raising exceptions
def divide(a, b):
    if b == 0:
        raise ValueError("Cannot divide by zero")
    return a / b

# Custom exceptions
class AppError(Exception):
    def __init__(self, message, code):
        super().__init__(message)
        self.code = code

Memory Management

Garbage collected. V8 uses a generational GC (Scavenger for young gen, Mark-Sweep/Mark-Compact for old gen). No manual memory management.

// Memory is automatically allocated and freed
let obj = { name: 'Alice' }  // Allocated on heap
obj = null                     // Eligible for GC

// WeakRef — reference that doesn't prevent GC
let target = { data: 'important' }
const weak = new WeakRef(target)
weak.deref()  // { data: 'important' } or undefined

// FinalizationRegistry — callback when object is GC'd
const registry = new FinalizationRegistry((value) => {
  console.log(`${value} was garbage collected`)
})
registry.register(target, 'my-target')

// WeakMap / WeakSet — keys are weakly held
const cache = new WeakMap()
cache.set(someObj, expensiveResult)
// When someObj is GC'd, the entry is removed

Common memory issues:

  • Closures retaining references longer than needed
  • Event listeners not removed (use AbortController)
  • Detached DOM nodes still referenced in JS
  • Large arrays/buffers — use streaming or ArrayBuffer
  • Timers (setInterval) not cleared

Use Chrome DevTools → Memory tab to profile heap snapshots and detect leaks.

Memory Management

Same GC as JavaScript — TypeScript compiles to JS, so memory management is identical. Types help prevent some leak patterns.

// using declarations (TC39 Stage 3 / TS 5.2+)
// Automatic resource cleanup via Symbol.dispose
class FileHandle implements Disposable {
  handle: number
  constructor(path: string) { this.handle = openFile(path) }
  [Symbol.dispose]() { closeFile(this.handle) }
}

{
  using file = new FileHandle('/tmp/data')
  // file is automatically disposed at end of block
}

// AsyncDisposable
class Connection implements AsyncDisposable {
  async [Symbol.asyncDispose]() {
    await this.close()
  }
}
await using conn = new Connection()

TypeScript-specific patterns:

  • Types help catch null reference issues (strictNullChecks)
  • WeakRef<T> and WeakMap<K, V> are fully typed
  • using declarations prevent resource leak patterns
  • No additional memory overhead — types are erased at compile time
  • Same debugging tools as JavaScript (Chrome DevTools, Node.js --inspect)

Memory Management

Garbage collected with reference counting. PHP uses a reference-counting GC with a cycle collector. Memory is freed at the end of each request in traditional PHP-FPM setups.

// Memory is automatically managed
$data = range(1, 10000);  // Allocated
unset($data);               // Freed immediately (refcount → 0)

// Check memory usage
echo memory_get_usage();       // Current usage (bytes)
echo memory_get_peak_usage();  // Peak usage (bytes)
echo memory_get_usage(true);   // Real allocated memory

// Memory limit
ini_set('memory_limit', '256M');

// Generators — memory-efficient iteration
function bigRange(int $start, int $end): Generator {
    for ($i = $start; $i <= $end; $i++) {
        yield $i;
    }
}
// Yields one value at a time — O(1) memory
foreach (bigRange(1, 1000000) as $num) { }

// WeakMap (PHP 8.0+) — keys are weakly referenced
$cache = new WeakMap();
$obj = new stdClass();
$cache[$obj] = 'metadata';
// When $obj is unset, entry is automatically removed

PHP memory model:

  • Request-scoped: In PHP-FPM, all memory is freed at the end of each request
  • Reference counting: Objects freed when refcount hits 0
  • Cycle collector: Detects and frees circular references
  • Long-running processes (Swoole, RoadRunner): Must be careful about memory leaks since memory persists between requests

Memory Management

Garbage collected. CRuby uses a generational, incremental, compacting GC. Objects are allocated on the heap with automatic cleanup.

# Memory is automatically managed
data = (1..10000).to_a  # Allocated
data = nil               # Eligible for GC

# Check memory usage
puts "RSS: #{`ps -o rss= -p #{Process.pid}`.strip.to_i / 1024} MB"

# ObjectSpace — inspect live objects
require 'objspace'
ObjectSpace.count_objects
# => { TOTAL: 30000, FREE: 5000, T_OBJECT: 1200, ... }

ObjectSpace.memsize_of_all  # Total memory of all objects

# GC control
GC.start          # Force garbage collection
GC.disable         # Disable GC (use carefully)
GC.enable
GC.stat            # GC statistics

# WeakRef
require 'weakref'
obj = Object.new
weak = WeakRef.new(obj)
weak.weakref_alive?  # true

Ruby GC details:

  • Generational: Young objects collected more frequently than old ones
  • Incremental: GC work is spread across multiple steps to reduce pauses
  • Compacting (Ruby 2.7+): GC.compact reduces memory fragmentation
  • Variable Width Allocation (Ruby 3.2+): Objects can be embedded in heap slots
  • Tune via env vars: RUBY_GC_HEAP_INIT_SLOTS, RUBY_GC_MALLOC_LIMIT, etc.
  • Jemalloc: Alternative allocator that reduces memory fragmentation (LD_PRELOAD=libjemalloc.so)

Memory Management

Garbage collected with a concurrent, tri-color mark-and-sweep collector. Low-latency GC pauses (typically < 1ms).

// Memory is automatically managed
obj := &MyStruct{Name: "Alice"}
// No need to free — GC handles it

// Stack vs heap — compiler decides (escape analysis)
func createLocal() int {
    x := 42      // Stays on stack (doesn't escape)
    return x
}

func createHeap() *int {
    x := 42      // Escapes to heap (returned as pointer)
    return &x
}

// See escape analysis decisions
// go build -gcflags='-m' .
// sync.Pool — reuse temporary objects (reduce GC pressure)
var bufPool = sync.Pool{
    New: func() any { return new(bytes.Buffer) },
}

buf := bufPool.Get().(*bytes.Buffer)
buf.Reset()
// ... use buf ...
bufPool.Put(buf) // Return to pool

// runtime — GC control
import "runtime"
runtime.GC()                    // Force GC
runtime.ReadMemStats(&stats)    // Memory statistics

// GOGC — tune GC aggressiveness
// GOGC=100 (default): GC when heap doubles
// GOGC=50: GC more often (less memory, more CPU)
// GOMEMLIMIT=1GiB: soft memory limit (Go 1.19+)

// Finalizers (rarely needed)
runtime.SetFinalizer(obj, func(o *MyType) {
    o.Close()
})

Memory Management

Ownership and borrowing — no GC. Memory is freed deterministically when the owner goes out of scope. The borrow checker enforces safety at compile time.

// Ownership — each value has exactly one owner
let s1 = String::from("hello");
let s2 = s1;        // s1 is MOVED to s2
// println!("{}", s1); // ERROR: s1 is no longer valid

// Clone — explicit deep copy
let s3 = s2.clone();

// Borrowing — references without ownership
fn print_len(s: &String) {  // Immutable borrow
    println!("{}", s.len());
}

fn append(s: &mut String) {  // Mutable borrow
    s.push_str(" world");
}

// Rules:
// 1. Many immutable borrows OR one mutable borrow
// 2. References must always be valid (no dangling)
// Drop trait — deterministic cleanup (like RAII)
struct FileHandle { fd: i32 }

impl Drop for FileHandle {
    fn drop(&mut self) {
        close_fd(self.fd);  // Runs when value goes out of scope
    }
}

{
    let f = FileHandle { fd: 42 };
    // ... use f ...
} // f.drop() called here automatically

// Smart pointers
use std::rc::Rc;        // Reference counted (single-thread)
use std::sync::Arc;     // Atomic reference counted (multi-thread)
use std::cell::RefCell; // Interior mutability

let shared = Rc::new(vec![1, 2, 3]);
let clone = Rc::clone(&shared); // Cheap (increments count)

// Box — heap allocation
let boxed: Box<dyn Trait> = Box::new(MyStruct {});

// No GC pauses, no runtime overhead
// Memory bugs caught at compile time, not runtime

Memory Management

Manual memory management with RAII (Resource Acquisition Is Initialization). Smart pointers automate ownership. No garbage collector.

// RAII — resources tied to object lifetime
{
    std::string s = "hello";  // Allocated
    std::vector<int> v = {1, 2, 3};
} // Destructors called, memory freed automatically

// Smart pointers (prefer over raw new/delete)
#include <memory>

// unique_ptr — sole ownership
auto ptr = std::make_unique<MyClass>(args);
// Automatically deleted when ptr goes out of scope

// shared_ptr — reference counted
auto shared = std::make_shared<MyClass>(args);
auto copy = shared;  // refcount = 2
// Deleted when last shared_ptr is destroyed

// weak_ptr — non-owning reference
std::weak_ptr<MyClass> weak = shared;
if (auto locked = weak.lock()) {
    // Use locked (shared_ptr)
}
// Raw allocation (avoid in modern C++)
int* raw = new int(42);
delete raw;

int* arr = new int[100];
delete[] arr;

// Stack vs heap
int stack_var = 42;              // Stack (automatic)
auto heap_var = new int(42);     // Heap (manual)

// Move semantics — transfer ownership without copying
std::vector<int> v1 = {1, 2, 3};
std::vector<int> v2 = std::move(v1);
// v1 is now empty, v2 owns the data

// Custom RAII wrapper
class FileHandle {
    FILE* fp;
public:
    FileHandle(const char* path) : fp(fopen(path, "r")) {}
    ~FileHandle() { if (fp) fclose(fp); }
    // Delete copy, allow move
    FileHandle(const FileHandle&) = delete;
    FileHandle(FileHandle&& other) : fp(other.fp) { other.fp = nullptr; }
};

Memory Management

Generational garbage collector (Gen 0, 1, 2 + LOH). Supports IDisposable for deterministic cleanup and Span<T> for stack allocation.

// GC is automatic — no manual free
var list = new List<int> { 1, 2, 3 };
// GC collects when Gen 0 fills up

// IDisposable — deterministic cleanup
using var file = File.OpenRead("data.txt");
// file.Dispose() called at end of scope

// Classic using statement
using (var conn = new SqlConnection(connStr))
{
    conn.Open();
    // ...
} // Dispose() called here

// Implement IDisposable
class ManagedResource : IDisposable
{
    private bool _disposed;
    public void Dispose()
    {
        if (!_disposed)
        {
            // Release resources
            _disposed = true;
        }
    }
}
// Stack allocation with Span<T> and stackalloc
Span<int> numbers = stackalloc int[100];
// No heap allocation, no GC pressure

// ArrayPool — reuse arrays
var pool = ArrayPool<byte>.Shared;
byte[] buffer = pool.Rent(1024);
// ... use buffer ...
pool.Return(buffer);

// WeakReference
var weak = new WeakReference<MyObject>(obj);
if (weak.TryGetTarget(out var target))
    target.DoSomething();

// GC control
GC.Collect();                    // Force collection
GC.GetTotalMemory(true);        // Total managed memory
GC.TryStartNoGCRegion(1024);    // Suppress GC temporarily

// Value types (struct) live on stack — no GC
struct Point { public int X, Y; }

// ref struct — guaranteed stack-only
ref struct StackOnly { public Span<int> Data; }

Memory Management

Automatic Reference Counting (ARC) — deterministic, compile-time inserted retain/release. No GC pauses.

// ARC automatically manages reference counts
class Person {
    let name: String
    init(name: String) { self.name = name }
    deinit { print("\(name) is being deinitialized") }
}

var person: Person? = Person(name: "Alice") // refcount = 1
var another = person   // refcount = 2
person = nil           // refcount = 1
another = nil          // refcount = 0 → deinit called

// Strong reference cycles — use weak/unowned to break
class Parent {
    var child: Child?
}
class Child {
    weak var parent: Parent?   // Weak — can be nil
    unowned let owner: Parent  // Unowned — never nil (crash if wrong)
}
// Closures and capture lists
class ViewController {
    var name = "Main"

    func setup() {
        // Strong capture (default) — can cause retain cycle
        // fetchData { self.name }

        // Weak capture — breaks cycle
        fetchData { [weak self] in
            guard let self else { return }
            print(self.name)
        }

        // Unowned capture — when you know self outlives closure
        fetchData { [unowned self] in
            print(self.name)
        }
    }
}

// Value types (struct, enum) — stack allocated, no ARC
struct Point { var x: Double; var y: Double }
// Copied on assignment, no reference counting needed

// Autoreleasepool (for Objective-C interop)
autoreleasepool {
    // Heavy temporary object creation
}

Memory Management

JVM garbage collector — generational GC with multiple collector options (G1, ZGC, Shenandoah). Kotlin/Native uses its own GC.

// Memory is automatically managed by the JVM GC
val list = mutableListOf(1, 2, 3)
// GC collects when objects are unreachable

// Closeable — deterministic cleanup (like IDisposable)
import java.io.Closeable

class ManagedResource : Closeable {
    override fun close() { /* release resources */ }
}

// use — auto-close (like try-with-resources)
FileReader("data.txt").use { reader ->
    reader.readText()
} // reader.close() called automatically

// BufferedReader
File("data.txt").bufferedReader().use { it.readText() }
// Value classes — avoid boxing overhead
@JvmInline
value class UserId(val id: Long)
// No heap allocation at runtime (inlined)

// Sequences — lazy, avoids intermediate collections
val result = (1..1_000_000).asSequence()
    .filter { it % 2 == 0 }
    .map { it * it }
    .take(10)
    .toList()  // Only one list allocated

// WeakReference
import java.lang.ref.WeakReference
val weak = WeakReference(heavyObject)
weak.get()  // Returns object or null if GC'd

// JVM GC tuning
// -XX:+UseG1GC (default since JDK 9)
// -XX:+UseZGC (low-latency, JDK 15+)
// -Xmx512m (max heap size)
// -XX:+PrintGCDetails (GC logging)

// Kotlin/Native — uses tracing GC (since 1.7.20)
// Previously used reference counting with cycle detection

Memory Management

Reference counting + cyclic garbage collector. CPython uses reference counting as the primary mechanism, with a cycle detector for circular references.

import sys
import gc

# Reference counting
a = [1, 2, 3]
sys.getrefcount(a)  # Shows reference count

# When refcount drops to 0, memory is freed immediately
b = a       # refcount = 2
del b       # refcount = 1
a = None    # refcount = 0 → freed

# Context managers — deterministic cleanup
with open('file.txt') as f:
    data = f.read()
# File is closed here, regardless of exceptions

# Custom context manager
class ManagedResource:
    def __enter__(self):
        self.acquire()
        return self
    def __exit__(self, *args):
        self.release()

# __del__ — destructor (not guaranteed to run)
class MyClass:
    def __del__(self):
        print("Cleaning up")
# Garbage collector control
gc.collect()            # Force collection
gc.disable()            # Disable automatic GC
gc.get_stats()          # GC statistics
gc.get_referrers(obj)   # What references this object?

# weakref — references that don't prevent GC
import weakref
obj = SomeClass()
weak = weakref.ref(obj)
weak()  # Returns obj or None if GC'd

# Slots — reduce per-instance memory
class Point:
    __slots__ = ('x', 'y')
    def __init__(self, x, y):
        self.x = x
        self.y = y
# Uses ~40% less memory than regular class

Performance Profiling

Chrome DevTools and Node.js built-in profiler are the primary tools. performance.now() for manual timing.

// Manual timing
const start = performance.now()
doExpensiveWork()
console.log(`Took ${performance.now() - start}ms`)

// console.time / console.timeEnd
console.time('fetch')
await fetch('/api/data')
console.timeEnd('fetch')  // fetch: 142.3ms

// Performance API (browser)
performance.mark('start')
doWork()
performance.mark('end')
performance.measure('work', 'start', 'end')
console.log(performance.getEntriesByName('work'))
# Node.js built-in profiler
node --prof app.js
node --prof-process isolate-*.log > profile.txt

# Node.js inspector (CPU + heap profiling)
node --inspect app.js
# Open chrome://inspect in Chrome

# Clinic.js — Node.js performance toolkit
npx clinic doctor -- node app.js
npx clinic flame -- node app.js
npx clinic bubbleprof -- node app.js

# Chrome DevTools
# Performance tab: CPU flame chart, call tree
# Memory tab: heap snapshots, allocation timeline
# Lighthouse: web performance auditing

Performance Profiling

Same runtime profiling as JavaScript. TypeScript adds compile-time performance tools for type checking.

# Runtime profiling — same as JavaScript
node --inspect dist/app.js
# Chrome DevTools, Clinic.js, etc.

# TypeScript compiler performance
npx tsc --generateTrace ./trace
# Open trace in chrome://tracing or
# https://ui.perfetto.dev/

# Measure type-check time
npx tsc --extendedDiagnostics
# Files:            150
# Lines:          25000
# Check time:      2.5s
# Total time:      3.1s

# @typescript/analyze-trace — analyze slow types
npx @typescript/analyze-trace ./trace
// Performance-aware TypeScript patterns
// Avoid deep conditional types (slow type checking)
// Use interface extends over intersection types (&)
// Prefer type aliases for unions over complex mapped types

// Benchmark with Vitest
import { bench, describe } from 'vitest'

describe('sort', () => {
  bench('Array.sort', () => {
    [3, 1, 2].sort()
  })
  bench('custom sort', () => {
    customSort([3, 1, 2])
  })
})
// Run: npx vitest bench

Performance Profiling

Xdebug and Blackfire are the primary profiling tools. SPX is a lightweight alternative.

// Manual timing
$start = microtime(true);
doExpensiveWork();
$elapsed = microtime(true) - $start;
echo "Took {$elapsed}s";

// Memory profiling
$before = memory_get_usage();
$data = processLargeDataset();
$used = memory_get_usage() - $before;
echo "Used " . ($used / 1024 / 1024) . " MB";
# Xdebug profiling (generates cachegrind files)
# php.ini: xdebug.mode=profile
# php.ini: xdebug.output_dir=/tmp/xdebug
php script.php
# Open cachegrind file with KCacheGrind / QCacheGrind / Webgrind

# Blackfire.io — production-safe profiler
blackfire run php script.php
# Or profile via browser extension

# SPX — lightweight profiler (built-in web UI)
# php.ini: extension=spx.so
# Access /?SPX_KEY=dev&SPX_UI_URI=/ in browser

# Tideways — production monitoring + profiling
# XHProf — Facebook's hierarchical profiler
pecl install xhprof
# Laravel-specific
php artisan route:list        # Check registered routes
php artisan optimize          # Cache config, routes, views
composer dump-autoload -o     # Optimized autoloader

# Benchmark with Apache Bench
ab -n 1000 -c 10 http://localhost:8000/

Performance Profiling

ruby-prof, stackprof, and benchmark are the main profiling tools. rack-mini-profiler for web apps.

# Benchmark (stdlib)
require 'benchmark'

Benchmark.bm do |x|
  x.report('sort') { (1..10000).to_a.shuffle.sort }
  x.report('sort!') { (1..10000).to_a.shuffle.sort! }
end

# Benchmark.measure
result = Benchmark.measure { expensive_operation }
puts result  # user, system, total, real time

# Benchmark/ips — iterations per second
require 'benchmark/ips'
Benchmark.ips do |x|
  x.report('map') { [1,2,3].map { |i| i * 2 } }
  x.report('each') { r = []; [1,2,3].each { |i| r << i * 2 }; r }
  x.compare!
end
# StackProf — sampling profiler
gem install stackprof
# In code: StackProf.run(mode: :cpu, out: 'tmp/stackprof.dump') { work }
stackprof tmp/stackprof.dump --text

# ruby-prof — deterministic profiler
gem install ruby-prof
ruby-prof script.rb

# rack-mini-profiler — web request profiling
gem 'rack-mini-profiler'
# Shows timing badge on every page

# memory_profiler — memory allocation tracking
gem install memory_profiler
# MemoryProfiler.report { work }.pretty_print

# derailed_benchmarks — Rails memory/speed benchmarks
gem install derailed_benchmarks
bundle exec derailed exec perf:mem
bundle exec derailed exec perf:ips

Performance Profiling

Built-in profiling via pprof and the testing package. Go has excellent profiling tools out of the box.

// Benchmarks in test files
func BenchmarkSort(b *testing.B) {
    data := generateData(1000)
    b.ResetTimer()
    for i := 0; i < b.N; i++ {
        sort.Ints(data)
    }
}

// Memory benchmarks
func BenchmarkAlloc(b *testing.B) {
    b.ReportAllocs()
    for i := 0; i < b.N; i++ {
        _ = make([]int, 1000)
    }
}
# CPU profiling
go test -bench . -cpuprofile cpu.prof
go tool pprof cpu.prof
# (pprof) top10
# (pprof) web       # Opens flame graph in browser

# Memory profiling
go test -bench . -memprofile mem.prof
go tool pprof -alloc_space mem.prof

# HTTP pprof — profile running servers
import _ "net/http/pprof"
# Visit http://localhost:6060/debug/pprof/

# Trace — goroutine scheduling, GC, syscalls
go test -trace trace.out
go tool trace trace.out

# Flame graphs
go tool pprof -http=:8080 cpu.prof

# Benchstat — compare benchmark results
go install golang.org/x/perf/cmd/benchstat@latest
benchstat old.txt new.txt

Performance Profiling

Use cargo bench for benchmarks, perf/flamegraph for CPU profiling, and DHAT/Valgrind for memory.

// Criterion.rs — statistical benchmarking
// Cargo.toml: criterion = { version = "0.5", features = ["html_reports"] }
use criterion::{criterion_group, criterion_main, Criterion};

fn bench_sort(c: &mut Criterion) {
    c.bench_function("sort 1000", |b| {
        b.iter(|| {
            let mut v: Vec<i32> = (0..1000).rev().collect();
            v.sort();
        })
    });
}

criterion_group!(benches, bench_sort);
criterion_main!(benches);
# Built-in benchmarks (nightly only)
cargo bench

# Criterion benchmarks (stable Rust)
cargo bench  # with criterion in Cargo.toml

# Flame graphs
cargo install flamegraph
cargo flamegraph          # Generates flamegraph.svg

# perf (Linux)
perf record --call-graph dwarf ./target/release/myapp
perf report

# Valgrind / Cachegrind
valgrind --tool=callgrind ./target/release/myapp
# Visualize with kcachegrind

# DHAT — heap profiler
valgrind --tool=dhat ./target/release/myapp

# cargo-instruments (macOS)
cargo install cargo-instruments
cargo instruments -t "CPU Profiler"

# Compile time profiling
cargo build --timings    # HTML report of compile times

Performance Profiling

Use perf (Linux), Instruments (macOS), gprof, Valgrind, and Google Benchmark for micro-benchmarks.

// Google Benchmark
#include <benchmark/benchmark.h>

static void BM_Sort(benchmark::State& state) {
    for (auto _ : state) {
        std::vector<int> v(1000);
        std::iota(v.begin(), v.end(), 0);
        std::ranges::reverse(v);
        std::ranges::sort(v);
    }
}
BENCHMARK(BM_Sort);
BENCHMARK_MAIN();
# perf (Linux) — sampling profiler
perf record -g ./myapp
perf report
perf stat ./myapp         # Quick summary

# Flame graphs
perf script | stackcollapse-perf.pl | flamegraph.pl > flame.svg

# gprof — GNU profiler
g++ -pg -o myapp main.cpp
./myapp
gprof myapp gmon.out > analysis.txt

# Valgrind — memory + cache profiling
valgrind --tool=callgrind ./myapp
kcachegrind callgrind.out.*

valgrind --tool=massif ./myapp    # Heap profiler
ms_print massif.out.*

# AddressSanitizer / MemorySanitizer
g++ -fsanitize=address -g -o myapp main.cpp
./myapp  # Reports memory errors

# Instruments (macOS)
xcrun xctrace record --template 'CPU Profiler' --launch ./myapp

# Quick timing
#include <chrono>
auto start = std::chrono::high_resolution_clock::now();
doWork();
auto end = std::chrono::high_resolution_clock::now();
auto ms = std::chrono::duration_cast<std::chrono::milliseconds>(end - start);

Performance Profiling

BenchmarkDotNet for benchmarks, dotnet-trace/dotnet-counters for runtime profiling, Visual Studio Profiler for GUI.

// BenchmarkDotNet — micro-benchmarking
using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Running;

[MemoryDiagnoser]
public class SortBenchmark
{
    private int[] _data = Enumerable.Range(0, 1000).Reverse().ToArray();

    [Benchmark]
    public void ArraySort() => Array.Sort((int[])_data.Clone());

    [Benchmark]
    public void LinqOrderBy() => _data.OrderBy(x => x).ToArray();
}

// Run: BenchmarkRunner.Run<SortBenchmark>();
# dotnet-counters — real-time metrics
dotnet tool install -g dotnet-counters
dotnet counters monitor --process-id 12345

# dotnet-trace — collect traces
dotnet tool install -g dotnet-trace
dotnet trace collect --process-id 12345
# Open .nettrace file in Visual Studio or PerfView

# dotnet-dump — memory analysis
dotnet tool install -g dotnet-dump
dotnet dump collect --process-id 12345
dotnet dump analyze dump.dmp

# dotnet-gcdump — GC heap analysis
dotnet gcdump collect --process-id 12345

# Visual Studio: Debug > Performance Profiler
# - CPU Usage, Memory Usage, .NET Object Allocation
# - Async tool, Database, Events

# JetBrains dotTrace / dotMemory
# Rider: built-in profiling tools

Performance Profiling

Instruments (Xcode) is the primary profiling tool. Swift also supports XCTest performance tests and swift-benchmark.

// XCTest performance measurement
import XCTest

class PerformanceTests: XCTestCase {
    func testSortPerformance() {
        let data = (0..<10000).shuffled()
        measure {
            _ = data.sorted()
        }
    }

    // Clock-based measurement (Xcode 14+)
    func testWithClock() {
        measure(metrics: [XCTClockMetric()]) {
            doExpensiveWork()
        }
    }
}
# Instruments (Xcode)
# Product > Profile (Cmd+I) in Xcode
# Templates:
# - Time Profiler: CPU flame chart
# - Allocations: heap memory
# - Leaks: memory leak detection
# - Network: HTTP request profiling
# - Core Animation: UI rendering

# Command-line Instruments
xcrun xctrace record --template 'Time Profiler' \
  --launch ./MyApp

# swift-benchmark (for library/CLI benchmarking)
# Package: google/swift-benchmark
import Benchmark

benchmark("sort") {
    var array = (0..<1000).shuffled()
    array.sort()
}
Benchmark.main()

# os_signpost — custom performance markers
import os
let log = OSLog(subsystem: "com.app", category: "perf")
os_signpost(.begin, log: log, name: "fetch")
// ... work ...
os_signpost(.end, log: log, name: "fetch")
# Visible in Instruments > os_signpost

Performance Profiling

JVM profiling tools: JMH for benchmarks, VisualVM/JFR for runtime profiling, Android Profiler for mobile.

// JMH (Java Microbenchmark Harness) via kotlinx-benchmark
// build.gradle.kts:
// plugins { id("org.jetbrains.kotlinx.benchmark") version "0.4.10" }

import org.openjdk.jmh.annotations.*

@State(Scope.Benchmark)
class SortBenchmark {
    private val data = (0 until 1000).shuffled()

    @Benchmark
    fun sortList(): List<Int> = data.sorted()

    @Benchmark
    fun sortArray(): IntArray = data.toIntArray().also { it.sort() }
}
# JFR (Java Flight Recorder) — low-overhead profiling
java -XX:StartFlightRecording=duration=60s,filename=rec.jfr -jar app.jar
# Analyze with JDK Mission Control (jmc)

# VisualVM — GUI profiler
visualvm  # CPU, memory, threads, heap dump

# async-profiler — sampling profiler (low overhead)
# https://github.com/async-profiler/async-profiler
./profiler.sh -d 30 -f flame.html <pid>

# IntelliJ IDEA Profiler
# Run > Profile (built-in CPU + memory profiler)
# Generates flame charts and call trees

# Android Profiler (Android Studio)
# CPU, Memory, Network, Energy profiling
# System Trace for detailed thread analysis

# Kotlin-specific: measure time
import kotlin.time.measureTime
val duration = measureTime {
    doExpensiveWork()
}
println("Took $duration")

# Gradle build profiling
./gradlew build --scan  # Build scan
./gradlew build --profile  # HTML report

Performance Profiling

Built-in cProfile and timeit. Third-party tools: py-spy, scalene, line_profiler.

# timeit — quick benchmarks
import timeit
timeit.timeit('sum(range(1000))', number=10000)

# cProfile — built-in profiler
import cProfile
cProfile.run('my_function()')

# Profile to file + visualize
python -m cProfile -o output.prof script.py
# Visualize with snakeviz:
pip install snakeviz
snakeviz output.prof
# py-spy — sampling profiler (no code changes)
pip install py-spy
py-spy top --pid 12345           # Live top-like view
py-spy record -o profile.svg -- python app.py  # Flame graph

# Scalene — CPU + memory + GPU profiler
pip install scalene
scalene script.py

# line_profiler — line-by-line timing
pip install line_profiler
# Decorate function with @profile, then:
kernprof -l -v script.py

# memory_profiler — line-by-line memory
pip install memory-profiler
python -m memory_profiler script.py

# tracemalloc — built-in memory tracing
import tracemalloc
tracemalloc.start()
# ... code ...
snapshot = tracemalloc.take_snapshot()
for stat in snapshot.statistics('lineno')[:10]:
    print(stat)

Interop

JavaScript interops with native code via N-API/node-addon-api (Node.js), WebAssembly, and Web APIs (browser).

// WebAssembly — run compiled code in JS
const wasmModule = await WebAssembly.instantiateStreaming(
  fetch('module.wasm')
)
const result = wasmModule.instance.exports.add(1, 2)

// Node.js native addons (N-API)
// Written in C/C++, compiled with node-gyp
const addon = require('./build/Release/myaddon.node')
addon.hello() // Calls native C++ function

// Node.js FFI with ffi-napi
const ffi = require('ffi-napi')
const libm = ffi.Library('libm', {
  ceil: ['double', ['double']],
})
libm.ceil(1.5) // 2

// Child process — call any system command
import { execSync, spawn } from 'child_process'
const output = execSync('ls -la').toString()
// Browser Web APIs
navigator.geolocation.getCurrentPosition(pos => { })
const stream = await navigator.mediaDevices.getUserMedia({ video: true })

// postMessage — cross-origin / worker communication
worker.postMessage({ type: 'compute', data })
window.parent.postMessage('done', 'https://parent.com')

// JSON — universal data interchange
const data = JSON.parse(jsonString)
const json = JSON.stringify(data)

Interop

Same runtime interop as JavaScript, plus type declaration files (.d.ts) for typing external libraries and APIs.

// Type declarations for untyped JS libraries
// @types/node, @types/express, etc.
npm install --save-dev @types/node

// Declare types for a JS module without types
declare module 'untyped-lib' {
  export function doStuff(input: string): number
}

// Declare global variables (e.g., injected by scripts)
declare global {
  interface Window {
    analytics: { track(event: string): void }
  }
}

// WebAssembly with types
const wasm = await WebAssembly.instantiateStreaming(
  fetch('module.wasm')
)
const add = wasm.instance.exports.add as (a: number, b: number) => number
// JSON import (with resolveJsonModule)
import data from './config.json'
// data is fully typed based on JSON structure

// Import assertions
import schema from './schema.json' with { type: 'json' }

// Interop with JSDoc-typed JavaScript
// TypeScript can check .js files with JSDoc annotations
/** @param {string} name */
function greet(name) { return `Hello ${name}` }

// Ambient declarations (*.d.ts files)
// Describe the shape of existing JS code
// without rewriting it in TypeScript

Interop

PHP interops with C via FFI (PHP 7.4+), system commands, and various protocol integrations.

// FFI — call C libraries directly (PHP 7.4+)
$ffi = FFI::cdef("
    double sqrt(double x);
    int abs(int x);
", "libm.so.6");  // Or "libm.dylib" on macOS

echo $ffi->sqrt(16.0);  // 4.0
echo $ffi->abs(-42);    // 42

// FFI with struct
$ffi = FFI::cdef("
    typedef struct { int x; int y; } Point;
");
$point = $ffi->new("Point");
$point->x = 10;
$point->y = 20;

// System commands
$output = shell_exec('ls -la');
$output = exec('whoami', $lines, $exitCode);
$handle = popen('tail -f /var/log/syslog', 'r');

// Process control
$process = proc_open(
    'python3 script.py',
    [['pipe', 'r'], ['pipe', 'w'], ['pipe', 'w']],
    $pipes
);
fwrite($pipes[0], "input data");
$result = stream_get_contents($pipes[1]);
proc_close($process);
// Database interop
$pdo = new PDO('mysql:host=localhost;dbname=app', 'user', 'pass');
$pdo = new PDO('pgsql:host=localhost;dbname=app', 'user', 'pass');
$pdo = new PDO('sqlite:/path/to/db.sqlite');

// REST / SOAP / gRPC
$client = new SoapClient('https://example.com/api?wsdl');
// gRPC via grpc/grpc PHP extension

// Redis, Memcached — native extensions
$redis = new Redis();
$redis->connect('127.0.0.1');

Interop

Ruby interops with C via native extensions, FFI, and system commands. JRuby provides Java interop.

# FFI — call C libraries
require 'ffi'

module LibM
  extend FFI::Library
  ffi_lib 'libm'  # Or FFI::Library::LIBC
  attach_function :sqrt, [:double], :double
  attach_function :ceil, [:double], :double
end

LibM.sqrt(16.0)  # 4.0
LibM.ceil(1.3)   # 2.0

# System commands
output = `ls -la`               # Backticks
output = %x(ls -la)             # %x syntax
system('echo', 'hello')         # Returns true/false
result = IO.popen('ls') { |io| io.read }

# Open3 — capture stdout, stderr, status
require 'open3'
stdout, stderr, status = Open3.capture3('git', 'status')
# C extensions (native)
# extconf.rb:
require 'mkmf'
create_makefile('my_extension')

# JRuby — Java interop
# java_import java.util.ArrayList
# list = ArrayList.new
# list.add('hello')

# Inline C (rice gem for C++ / fiddle for C)
require 'fiddle'
libm = Fiddle.dlopen('libm.so.6')
sqrt = Fiddle::Function.new(
  libm['sqrt'],
  [Fiddle::TYPE_DOUBLE],
  Fiddle::TYPE_DOUBLE
)
sqrt.call(16.0)  # 4.0

# JSON / YAML / CSV — stdlib
require 'json'
require 'yaml'
require 'csv'
data = JSON.parse(File.read('data.json'))

Interop

cgo enables calling C code from Go. Go can also be compiled as a C-shared library. Plugin system for dynamic loading.

// cgo — call C from Go
/*
#include <math.h>
*/
import "C"
import "fmt"

func main() {
    result := C.sqrt(16.0)
    fmt.Println(result) // 4
}

// Pass strings between Go and C
/*
#include <stdlib.h>
#include <string.h>
*/
import "C"
import "unsafe"

cs := C.CString("hello")
defer C.free(unsafe.Pointer(cs))
length := C.strlen(cs)
// Build Go as a C shared library
// export Add
func Add(a, b C.int) C.int {
    return a + b
}
// Build: go build -buildmode=c-shared -o libmylib.so

// os/exec — call system commands
import "os/exec"
out, err := exec.Command("ls", "-la").Output()

// Plugin system (Linux/macOS only)
import "plugin"
p, _ := plugin.Open("myplugin.so")
sym, _ := p.Lookup("Hello")
sym.(func())()

// WASM — compile Go to WebAssembly
// GOOS=js GOARCH=wasm go build -o main.wasm

// gRPC — cross-language RPC
// Go is a primary language for gRPC
// protoc --go_out=. --go-grpc_out=. service.proto

Interop

Excellent C FFI (zero overhead). Rust can call C and be called from C. wasm-bindgen for JavaScript interop.

// Call C from Rust
extern "C" {
    fn sqrt(x: f64) -> f64;
    fn printf(fmt: *const i8, ...) -> i32;
}

fn main() {
    unsafe {
        let result = sqrt(16.0);
        println!("{}", result); // 4.0
    }
}

// Expose Rust to C
#[no_mangle]
pub extern "C" fn add(a: i32, b: i32) -> i32 {
    a + b
}
// Build: cargo build --release (produces .so/.dylib/.dll)

// bindgen — auto-generate Rust bindings from C headers
// build.rs:
// bindgen::Builder::default()
//     .header("wrapper.h")
//     .generate()
// wasm-bindgen — Rust ↔ JavaScript
use wasm_bindgen::prelude::*;

#[wasm_bindgen]
pub fn greet(name: &str) -> String {
    format!("Hello, {}!", name)
}

// Called from JS:
// import { greet } from './pkg/mylib.js'
// greet("World")

// PyO3 — Rust ↔ Python
use pyo3::prelude::*;

#[pyfunction]
fn sum_as_string(a: usize, b: usize) -> String {
    (a + b).to_string()
}

// Neon — Rust ↔ Node.js
// uniffi — cross-language bindings (Kotlin, Swift, Python)

Interop

C++ has native C ABI compatibility. Widely used as the “lingua franca” for interop. Bindings exist for most languages.

// extern "C" — expose C-compatible functions
extern "C" {
    int add(int a, int b) { return a + b; }
    double my_sqrt(double x) { return std::sqrt(x); }
}
// Callable from C, Python (ctypes), Rust (FFI), etc.

// Call C libraries from C++
extern "C" {
    #include <sqlite3.h>
}

// dlopen — load shared libraries at runtime
#include <dlfcn.h>
void* handle = dlopen("libplugin.so", RTLD_LAZY);
auto fn = (int(*)(int))dlsym(handle, "compute");
int result = fn(42);
dlclose(handle);
// pybind11 — C++ ↔ Python
#include <pybind11/pybind11.h>
namespace py = pybind11;

int add(int a, int b) { return a + b; }

PYBIND11_MODULE(mymodule, m) {
    m.def("add", &add, "Add two numbers");
}

// Embind — C++ ↔ JavaScript (Emscripten/WASM)
#include <emscripten/bind.h>
EMSCRIPTEN_BINDINGS(my_module) {
    emscripten::function("add", &add);
}

// SWIG — auto-generate bindings for many languages
// swig -python -c++ mylib.i

// System commands
#include <cstdlib>
std::system("ls -la");

Interop

P/Invoke for native C calls, COM interop, and strong .NET interop across languages (F#, VB.NET). NativeAOT enables C-compatible exports.

// P/Invoke — call native C libraries
using System.Runtime.InteropServices;

[DllImport("libc", EntryPoint = "sqrt")]
static extern double Sqrt(double x);

double result = Sqrt(16.0); // 4.0

// Windows API
[DllImport("user32.dll")]
static extern int MessageBox(IntPtr hWnd, string text, string caption, uint type);

// LibraryImport (source-generated, .NET 7+)
[LibraryImport("libm")]
private static partial double sqrt(double x);
// NativeAOT — export C-compatible functions
[UnmanagedCallersOnly(EntryPoint = "add")]
public static int Add(int a, int b) => a + b;
// Build: dotnet publish /p:PublishAot=true
// Produces .so/.dylib/.dll callable from C

// COM interop (Windows)
dynamic excel = Activator.CreateInstance(
    Type.GetTypeFromProgID("Excel.Application")!);
excel.Visible = true;

// Process — call system commands
using System.Diagnostics;
var output = Process.Start(new ProcessStartInfo("ls", "-la") {
    RedirectStandardOutput = true
})!.StandardOutput.ReadToEnd();

// .NET languages interop seamlessly
// C# can call F#, VB.NET, and vice versa
// All compile to the same IL

Interop

Seamless Objective-C interop and C interop built in. Swift can import C headers directly. Bridging to other languages via C ABI.

// C interop — import C functions directly
import Darwin  // or Glibc on Linux

let result = sqrt(16.0)  // C math function
let str = strdup("hello")
free(str)

// Import a C library via module map
// module MyCLib [system] {
//   header "mylib.h"
//   link "mylib"
// }
import MyCLib
myCFunction()

// Unsafe pointers (for C interop)
let ptr = UnsafeMutablePointer<Int>.allocate(capacity: 1)
ptr.pointee = 42
ptr.deallocate()
// Objective-C interop (automatic bridging)
import Foundation
let str = NSString(string: "Hello")
let url = NSURL(string: "https://example.com")

// @objc — expose Swift to Objective-C
@objc class MyClass: NSObject {
    @objc func doSomething() { }
}

// Swift ↔ Kotlin (via Skip framework)
// Compiles Swift to Kotlin for Android

// Swift ↔ C++ (Swift 5.9+)
// Enable in build settings: C++ Interoperability = Enabled
// Import C++ headers directly in Swift

// Process — call system commands
import Foundation
let process = Process()
process.executableURL = URL(fileURLWithPath: "/bin/ls")
process.arguments = ["-la"]
try process.run()

Interop

100% Java interop — call any Java library from Kotlin and vice versa. Kotlin/Native has C interop. KMP shares code across platforms.

// Java interop — seamless, no wrappers needed
import java.util.ArrayList
import java.io.File

val list = ArrayList<String>()  // Java class
list.add("hello")

val file = File("data.txt")
val content = file.readText()  // Kotlin extension on Java class

// Kotlin is fully callable from Java
// @JvmStatic, @JvmField, @JvmOverloads for better Java API
class MyClass {
    companion object {
        @JvmStatic fun create(): MyClass = MyClass()
    }

    @JvmOverloads
    fun greet(name: String, greeting: String = "Hello") =
        "$greeting, $name!"
}
// Kotlin/Native — C interop
// Define in .def file:
// headers = mylib.h
// Build: generates Kotlin bindings from C headers
import mylib.*
val result = my_c_function(42)

// Kotlin Multiplatform — shared code
// expect/actual pattern
expect fun platformName(): String

// In JVM module:
actual fun platformName(): String = "JVM"
// In iOS module:
actual fun platformName(): String = "iOS"

// Platform-specific calls
import platform.Foundation.NSDate  // iOS/macOS
import kotlinx.cinterop.*         // C interop

// Process — call system commands (JVM)
val process = Runtime.getRuntime().exec("ls -la")
val output = process.inputStream.bufferedReader().readText()

Interop

Python excels at interop via ctypes, cffi, Cython, and pybind11 for C/C++. Also strong at subprocess and REST/HTTP integration.

# ctypes — call C shared libraries directly
import ctypes

libc = ctypes.CDLL("libc.so.6")  # or "libc.dylib" on macOS
libc.printf(b"Hello from C!\n")

libm = ctypes.CDLL("libm.so.6")
libm.sqrt.restype = ctypes.c_double
libm.sqrt(ctypes.c_double(16.0))  # 4.0

# cffi — cleaner C FFI
from cffi import FFI
ffi = FFI()
ffi.cdef("double sqrt(double x);")
lib = ffi.dlopen("libm.so.6")
lib.sqrt(16.0)  # 4.0
# subprocess — call any system command
import subprocess

result = subprocess.run(
    ["ls", "-la"],
    capture_output=True, text=True
)
print(result.stdout)

# pybind11 — C++ ↔ Python binding
# C++ side:
# #include <pybind11/pybind11.h>
# int add(int a, int b) { return a + b; }
# PYBIND11_MODULE(mymod, m) { m.def("add", &add); }
# Python side:
import mymod
mymod.add(1, 2)  # 3

# Cython — write C extensions in Python-like syntax
# .pyx files compiled to C for performance

# REST / HTTP — universal interop
import requests
resp = requests.get("https://api.example.com/data")
data = resp.json()

Packaging & Distribution

Publish libraries to npm. Distribute apps as Docker containers, serverless functions, or static sites.

# Publish a library to npm
npm login
npm publish               # Public package
npm publish --access public  # Scoped package (@org/pkg)

# package.json essentials
{
  "name": "my-lib",
  "version": "1.0.0",
  "main": "dist/index.cjs",
  "module": "dist/index.mjs",
  "types": "dist/index.d.ts",
  "exports": {
    ".": {
      "import": "./dist/index.mjs",
      "require": "./dist/index.cjs"
    }
  },
  "files": ["dist"]
}

# Build before publishing
npm run build
npm pack --dry-run  # Preview what gets published
# CLI distribution
# Add "bin" field to package.json
# "bin": { "mycli": "./dist/cli.js" }
npm publish
# Users: npx mycli or npm install -g mycli

# Docker
FROM node:22-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --production
COPY dist/ ./dist/
CMD ["node", "dist/index.js"]

# Static site deployment
# Vercel, Netlify, Cloudflare Pages — auto-deploy from Git
# npx vercel deploy

Packaging & Distribution

Same npm distribution as JavaScript. Ship .js + .d.ts (type declarations). Use tsup or unbuild for library builds.

# Build a library with tsup (zero-config)
npx tsup src/index.ts --format cjs,esm --dts
# Output: dist/index.js, dist/index.mjs, dist/index.d.ts

# package.json for a TypeScript library
{
  "name": "@myorg/lib",
  "version": "1.0.0",
  "exports": {
    ".": {
      "import": { "types": "./dist/index.d.mts", "default": "./dist/index.mjs" },
      "require": { "types": "./dist/index.d.ts", "default": "./dist/index.js" }
    }
  },
  "files": ["dist"],
  "scripts": {
    "build": "tsup src/index.ts --format cjs,esm --dts",
    "prepublishOnly": "npm run build"
  }
}

# Publish
npm publish --access public
# JSR — TypeScript-native registry (Deno/Node.js)
# Publish TypeScript source directly (no build step)
npx jsr publish

# Monorepo publishing
# Turborepo, Nx, or changesets
npx changeset         # Create a changeset
npx changeset version # Bump versions
npx changeset publish # Publish to npm

Packaging & Distribution

Publish libraries to Packagist (Composer registry). Deploy apps via Docker, PHP-FPM, or platform services.

# Publish a library to Packagist
# 1. Create a GitHub repo with composer.json
# 2. Register at https://packagist.org
# 3. Submit the repo URL — auto-updates via webhook

# composer.json for a library
{
  "name": "vendor/my-library",
  "type": "library",
  "autoload": {
    "psr-4": { "Vendor\\MyLib\\": "src/" }
  },
  "require": { "php": "^8.2" }
}

# Tag a release
git tag v1.0.0
git push --tags
# Docker deployment
FROM php:8.3-fpm-alpine
RUN docker-php-ext-install pdo_mysql opcache
COPY --from=composer:latest /usr/bin/composer /usr/bin/composer
WORKDIR /app
COPY composer.json composer.lock ./
RUN composer install --no-dev --optimize-autoloader
COPY . .
CMD ["php-fpm"]

# Laravel Forge / Vapor — managed deployment
# Platform.sh, Render, Railway — PaaS deployment

# Phar archive — single-file distribution
php -d phar.readonly=0 create-phar.php
# Creates my-tool.phar — run with: php my-tool.phar

# Static binary (experimental)
# FrankenPHP can embed PHP app into a single Go binary

Packaging & Distribution

Publish gems to RubyGems.org. Deploy apps via Docker, Heroku, or platform services.

# Create a gem
bundle gem my-gem
# Edit my-gem.gemspec, add code to lib/

# Build and publish
gem build my-gem.gemspec
gem push my-gem-1.0.0.gem

# Or with bundler
bundle exec rake release
# Tags, builds, and pushes to RubyGems.org
# my-gem.gemspec
Gem::Specification.new do |spec|
  spec.name          = 'my-gem'
  spec.version       = '1.0.0'
  spec.authors       = ['Your Name']
  spec.summary       = 'A useful gem'
  spec.files         = Dir['lib/**/*']
  spec.require_paths = ['lib']

  spec.add_dependency 'httparty', '~> 0.21'
  spec.add_development_dependency 'rspec', '~> 3.12'
end
# Docker deployment
FROM ruby:3.3-alpine
RUN apk add --no-cache build-base postgresql-dev
WORKDIR /app
COPY Gemfile Gemfile.lock ./
RUN bundle install --without development test
COPY . .
CMD ["bundle", "exec", "puma", "-C", "config/puma.rb"]

# Heroku
heroku create my-app
git push heroku main

# Kamal — Rails deployment tool (Docker-based)
gem install kamal
kamal setup
kamal deploy

Packaging & Distribution

Go produces single static binaries — no runtime needed. Publish modules to any Git host. Cross-compile trivially.

# Publish a Go module — just push to a Git repo
# Users: go get github.com/user/mylib@v1.0.0

# Semantic versioning via Git tags
git tag v1.0.0
git push origin v1.0.0

# Major version paths (v2+)
# module github.com/user/mylib/v2

# Build for multiple platforms
GOOS=linux   GOARCH=amd64 go build -o myapp-linux-amd64
GOOS=darwin  GOARCH=arm64 go build -o myapp-darwin-arm64
GOOS=windows GOARCH=amd64 go build -o myapp-windows.exe

# Strip debug info for smaller binaries
go build -ldflags="-s -w" -o myapp
# GoReleaser — automated release pipeline
# goreleaser.yaml config, then:
goreleaser release --clean
# Builds for all platforms, creates GitHub release,
# generates checksums, Homebrew formula, Docker images

# Install via go install
go install github.com/user/mycli@latest
# Binary placed in $GOPATH/bin

# Docker (tiny images with scratch)
FROM golang:1.22 AS builder
WORKDIR /app
COPY . .
RUN CGO_ENABLED=0 go build -o /app/myapp

FROM scratch
COPY --from=builder /app/myapp /myapp
ENTRYPOINT ["/myapp"]
# Final image: ~5-10MB

Packaging & Distribution

Publish libraries to crates.io. Distribute binaries via cargo install, GitHub releases, or package managers.

# Publish a crate to crates.io
cargo login <token>
cargo publish

# Cargo.toml metadata
[package]
name = "my-crate"
version = "1.0.0"
edition = "2021"
description = "My awesome library"
license = "MIT"
repository = "https://github.com/user/my-crate"

# Install a binary crate
cargo install ripgrep

# Build for release
cargo build --release
# Output: target/release/myapp
# Cross-compilation
rustup target add x86_64-unknown-linux-musl
cargo build --release --target x86_64-unknown-linux-musl
# Produces fully static binary

# cargo-dist — automated release pipeline
cargo install cargo-dist
cargo dist init
cargo dist build
# Creates GitHub releases with binaries for all platforms

# cargo-binstall — binary installation
cargo binstall ripgrep  # Downloads pre-built binary

# Docker (tiny images)
FROM rust:1.78 AS builder
WORKDIR /app
COPY . .
RUN cargo build --release

FROM debian:bookworm-slim
COPY --from=builder /app/target/release/myapp /usr/local/bin/
CMD ["myapp"]

# WASM distribution
wasm-pack build --target web
# Publish to npm: wasm-pack publish

Packaging & Distribution

No central package registry. Distribute via vcpkg/Conan, system package managers, or pre-built binaries. CMake is the build standard.

# CMakeLists.txt — install targets for distribution
install(TARGETS mylib
  EXPORT mylib-targets
  LIBRARY DESTINATION lib
  ARCHIVE DESTINATION lib
  RUNTIME DESTINATION bin
  INCLUDES DESTINATION include
)
install(DIRECTORY include/ DESTINATION include)
install(EXPORT mylib-targets
  FILE mylib-config.cmake
  NAMESPACE mylib::
  DESTINATION lib/cmake/mylib
)
# vcpkg — publish a port
# Create: ports/mylib/portfile.cmake + vcpkg.json
# Submit PR to microsoft/vcpkg

# Conan — publish a package
conan create .
conan upload mylib/1.0 --remote=myremote

# CPack — create installers from CMake
cmake -B build -DCMAKE_BUILD_TYPE=Release
cmake --build build
cd build && cpack
# Generates: .deb, .rpm, .tar.gz, .zip, NSIS installer

# Static linking for portable binaries
g++ -static -o myapp main.cpp

# Docker
FROM ubuntu:22.04 AS builder
RUN apt-get update && apt-get install -y build-essential cmake
COPY . /app
WORKDIR /app
RUN cmake -B build -DCMAKE_BUILD_TYPE=Release && cmake --build build

FROM ubuntu:22.04
COPY --from=builder /app/build/myapp /usr/local/bin/
CMD ["myapp"]

Packaging & Distribution

Publish libraries to NuGet. Distribute apps as self-contained executables, Docker containers, or native AOT binaries.

# Create a NuGet package
dotnet pack -c Release
# Output: bin/Release/MyLib.1.0.0.nupkg

# Publish to NuGet.org
dotnet nuget push MyLib.1.0.0.nupkg --api-key <key> \
  --source https://api.nuget.org/v3/index.json

# .csproj package metadata
# <PackageId>MyLib</PackageId>
# <Version>1.0.0</Version>
# <Authors>Me</Authors>
# <Description>My library</Description>
# <PackageLicenseExpression>MIT</PackageLicenseExpression>
# Self-contained deployment (includes .NET runtime)
dotnet publish -c Release --self-contained -r linux-x64
dotnet publish -c Release --self-contained -r osx-arm64
dotnet publish -c Release --self-contained -r win-x64

# Single file
dotnet publish -c Release -r linux-x64 \
  /p:PublishSingleFile=true /p:IncludeNativeLibrariesForSelfExtract=true

# Native AOT (no .NET runtime, fast startup)
dotnet publish -c Release -r linux-x64 /p:PublishAot=true

# .NET CLI tools
dotnet pack
dotnet tool install -g my-tool
# Users: dotnet tool install -g my-tool

# Docker
FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build
WORKDIR /app
COPY . .
RUN dotnet publish -c Release -o /out

FROM mcr.microsoft.com/dotnet/aspnet:8.0
COPY --from=build /out .
ENTRYPOINT ["dotnet", "MyApp.dll"]

Packaging & Distribution

Libraries via Swift Package Manager. Apps via App Store (Xcode), Homebrew, or direct binary distribution.

// Package.swift — library distribution
// swift-tools-version:5.9
import PackageDescription

let package = Package(
    name: "MyLib",
    platforms: [.macOS(.v13), .iOS(.v16)],
    products: [
        .library(name: "MyLib", targets: ["MyLib"]),
        .executable(name: "mycli", targets: ["CLI"]),
    ],
    targets: [
        .target(name: "MyLib"),
        .executableTarget(name: "CLI", dependencies: ["MyLib"]),
        .testTarget(name: "MyLibTests", dependencies: ["MyLib"]),
    ]
)
# Publish — push to any Git repo with a tag
git tag 1.0.0
git push origin 1.0.0
# Users: .package(url: "https://github.com/user/MyLib", from: "1.0.0")

# Swift Package Index — discovery
# https://swiftpackageindex.com/

# Build release binary
swift build -c release
# Output: .build/release/mycli

# App Store distribution (Xcode)
# Product > Archive > Distribute App

# Homebrew formula
# Create a formula pointing to the release binary/tarball
brew tap user/tap
brew install mycli

# Notarization (macOS)
xcrun notarytool submit MyApp.zip --apple-id <email> --team-id <team>

Packaging & Distribution

Libraries to Maven Central. Android apps to Google Play. Kotlin/Native produces standalone binaries.

// build.gradle.kts — library publishing
plugins {
    `maven-publish`
    signing
}

publishing {
    publications {
        create<MavenPublication>("release") {
            groupId = "com.example"
            artifactId = "my-lib"
            version = "1.0.0"
            from(components["kotlin"])
        }
    }
    repositories {
        maven {
            url = uri("https://s01.oss.sonatype.org/service/local/staging/deploy/maven2/")
            credentials {
                username = project.findProperty("ossrhUsername") as String
                password = project.findProperty("ossrhPassword") as String
            }
        }
    }
}
# Publish to Maven Central
./gradlew publish

# Fat JAR (all dependencies included)
# plugins { id("com.github.johnrengelman.shadow") }
./gradlew shadowJar
java -jar build/libs/app-all.jar

# Kotlin/Native binary
./gradlew linkReleaseExecutableNative
# Output: build/bin/native/releaseExecutable/app.kexe

# Android — Google Play
# Build > Generate Signed Bundle/APK in Android Studio
# Upload .aab to Play Console

# Docker (JVM)
FROM eclipse-temurin:21-jre-alpine
COPY build/libs/app-all.jar /app.jar
ENTRYPOINT ["java", "-jar", "/app.jar"]

# Kotlin scripting distribution
# .main.kts files can be run directly: kotlin script.main.kts

Packaging & Distribution

Publish libraries to PyPI. Distribute apps as Docker containers, pip-installable packages, or standalone executables.

# pyproject.toml — modern package config
[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"

[project]
name = "my-package"
version = "1.0.0"
description = "My awesome library"
requires-python = ">=3.10"
dependencies = ["requests>=2.28"]

[project.scripts]
mycli = "my_package.cli:main"

[project.optional-dependencies]
dev = ["pytest", "ruff"]
# Build
python -m build  # Creates dist/*.whl and dist/*.tar.gz

# Publish to PyPI
pip install twine
twine upload dist/*

# Or use uv
uv build
uv publish

# Standalone executable
pip install pyinstaller
pyinstaller --onefile app.py
# Output: dist/app (single binary)

# Docker
FROM python:3.12-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
CMD ["python", "app.py"]

Resources

Popular learning and reference links:

Resources

Resources

Popular learning and reference links:

Resources

Popular learning and reference links:

Resources

Popular learning and reference links:

Resources

Popular learning and reference links:

Resources

Popular learning and reference links:

Resources

Resources

Resources

Resources

Popular learning and reference links: