JavaScript vs Go: A Deep Dive into Syntax and Philosophy

JavaScript vs Go: A Deep Dive into Syntax and Philosophy

Source: Dev.to

Table of Contents ## 1. Variable Declaration and Type Systems ## JavaScript: Dynamic and Flexible ## Go: Explicit and Type-Safe ## 2. Functions and Their Flavors ## JavaScript: First-Class and Flexible ## Go: Typed and Structured ## 3. Error Handling: Exceptions vs Explicit Errors ## JavaScript: Try-Catch Exceptions ## Go: Explicit Error Values ## 4. Asynchronous Programming and Concurrency ## JavaScript: Async/Await and Promises ## Go: Goroutines and Channels ## 5. Data Structures: Objects vs Structs ## JavaScript: Prototypal Objects and Classes ## Go: Structs and Composition ## 6. Control Flow and Conditionals ## JavaScript ## 7. Loops and Iteration ## JavaScript ## 8. Interfaces and Polymorphism ## JavaScript: Duck Typing ## Go: Implicit Interfaces ## 9. Package Management and Modules ## JavaScript: NPM and ES Modules ## Go: Go Modules ## 10. Philosophy and Real-World Implications ## JavaScript Philosophy ## Go Philosophy ## When to Choose Which? ## Practical Example: Web API ## Conclusion As developers, we often find ourselves jumping between languages, and the syntax differences can be jarring. JavaScript and Go represent two very different philosophies in programming language design. JavaScript evolved from a browser scripting language into a full-stack powerhouse, while Go was designed from scratch by Google to solve modern distributed systems problems. Let's explore how these languages handle common programming tasks and what these differences reveal about their design philosophies. JavaScript's type system is dynamic—variables can hold any type of value and change types at runtime: Go is statically typed—every variable has a specific type that's checked at compile time: JavaScript treats functions as first-class citizens—they're just values that can be passed around: Go functions are more rigid but offer unique features like multiple return values: This is where the philosophies diverge most dramatically. JavaScript uses exceptions that can bubble up the call stack: Go treats errors as values that must be explicitly checked: This is perhaps the most controversial difference. JavaScript developers often find Go's error handling repetitive. Go developers argue it makes error paths visible and forces you to think about failure cases. Coming from Django/Python, you'll recognize this as the "explicit is better than implicit" philosophy taken to an extreme. JavaScript is single-threaded with an event loop, using async/await for non-blocking operations: Go has built-in concurrency primitives—goroutines (lightweight threads) and channels: For CPU-bound tasks, Go's goroutines can utilize multiple cores natively. JavaScript would need worker threads (which are clunky) or child processes. For I/O-bound tasks (like your Django REST Framework apps), both work well, but Go's approach scales better for high-concurrency scenarios like handling thousands of WebSocket connections. JavaScript is object-oriented with prototypal inheritance: Go uses structs with composition instead of inheritance: JavaScript uses structural typing—if it looks like a duck and quacks like a duck: Go has interfaces, but they're satisfied implicitly (structural typing): Flexibility and Expression JavaScript embraces multiple paradigms—object-oriented, functional, imperative. You can solve problems in many ways: Dynamic and Forgiving Ecosystem: Fast-Moving The JavaScript ecosystem moves quickly. New frameworks appear constantly. This is both a strength (innovation) and weakness (fatigue). Simplicity and Clarity Go deliberately limits features. There's often "one way" to do things: Ecosystem: Stability-Focused Go values backwards compatibility. The language changes slowly. Standard library is comprehensive. Fewer but more stable third-party packages. Choose JavaScript when: JavaScript (Express): JavaScript and Go represent different philosophies: JavaScript says: "Be flexible, move fast, express yourself freely." It's the language of rapid iteration, rich ecosystems, and creative solutions. Perfect for web development where requirements change rapidly. Go says: "Be explicit, be simple, be maintainable." It's the language of clarity, performance, and long-term reliability. Perfect for backend services where stability matters. Neither is "better"—they solve different problems. Coming from Django and Python, you'll appreciate Go's explicitness and find JavaScript's dynamism both liberating and occasionally frustrating. The best developers understand both paradigms and choose the right tool for the job. JavaScript for dynamic, user-facing applications. Go for reliable, concurrent backend services. What matters is understanding the trade-offs and using each language's strengths effectively. Want to dive deeper? Check out my other posts on language comparisons, or follow along as I continue exploring "What's wrong with..." various programming paradigms. Templates let you quickly answer FAQs or store snippets for re-use. Are you sure you want to hide this comment? It will become hidden in your post, but will still be visible via the comment's permalink. Hide child comments as well For further actions, you may consider blocking this person and/or reporting abuse CODE_BLOCK: // Multiple ways to declare variables let username = "Mephesto"; // Block-scoped, reassignable const MAX_RETRIES = 3; // Block-scoped, immutable binding var legacy = "avoid this"; // Function-scoped (pre-ES6) // Dynamic typing let data = 42; // number data = "now I'm a string"; // totally fine data = { key: "value" }; // also fine data = [1, 2, 3]; // no problem // Type coercion happens implicitly console.log("5" + 5); // "55" (string) console.log("5" - 5); // 0 (number) console.log(true + 1); // 2 Enter fullscreen mode Exit fullscreen mode CODE_BLOCK: // Multiple ways to declare variables let username = "Mephesto"; // Block-scoped, reassignable const MAX_RETRIES = 3; // Block-scoped, immutable binding var legacy = "avoid this"; // Function-scoped (pre-ES6) // Dynamic typing let data = 42; // number data = "now I'm a string"; // totally fine data = { key: "value" }; // also fine data = [1, 2, 3]; // no problem // Type coercion happens implicitly console.log("5" + 5); // "55" (string) console.log("5" - 5); // 0 (number) console.log(true + 1); // 2 CODE_BLOCK: // Multiple ways to declare variables let username = "Mephesto"; // Block-scoped, reassignable const MAX_RETRIES = 3; // Block-scoped, immutable binding var legacy = "avoid this"; // Function-scoped (pre-ES6) // Dynamic typing let data = 42; // number data = "now I'm a string"; // totally fine data = { key: "value" }; // also fine data = [1, 2, 3]; // no problem // Type coercion happens implicitly console.log("5" + 5); // "55" (string) console.log("5" - 5); // 0 (number) console.log(true + 1); // 2 CODE_BLOCK: package main import "fmt" func main() { // Explicit type declaration var username string = "Mephesto" var count int = 42 var isActive bool = true // Type inference with := message := "Go infers this is a string" port := 8080 // inferred as int // Constants const MaxRetries = 3 const Pi = 3.14159 // Multiple declarations var ( host string = "localhost" timeout int = 30 ) // This would be a compile error: // count = "string" // cannot use "string" as int // Zero values (no undefined!) var emptyString string // "" var emptyInt int // 0 var emptyBool bool // false var emptySlice []int // nil } Enter fullscreen mode Exit fullscreen mode CODE_BLOCK: package main import "fmt" func main() { // Explicit type declaration var username string = "Mephesto" var count int = 42 var isActive bool = true // Type inference with := message := "Go infers this is a string" port := 8080 // inferred as int // Constants const MaxRetries = 3 const Pi = 3.14159 // Multiple declarations var ( host string = "localhost" timeout int = 30 ) // This would be a compile error: // count = "string" // cannot use "string" as int // Zero values (no undefined!) var emptyString string // "" var emptyInt int // 0 var emptyBool bool // false var emptySlice []int // nil } CODE_BLOCK: package main import "fmt" func main() { // Explicit type declaration var username string = "Mephesto" var count int = 42 var isActive bool = true // Type inference with := message := "Go infers this is a string" port := 8080 // inferred as int // Constants const MaxRetries = 3 const Pi = 3.14159 // Multiple declarations var ( host string = "localhost" timeout int = 30 ) // This would be a compile error: // count = "string" // cannot use "string" as int // Zero values (no undefined!) var emptyString string // "" var emptyInt int // 0 var emptyBool bool // false var emptySlice []int // nil } COMMAND_BLOCK: // Traditional function declaration function calculateTotal(price, quantity) { return price * quantity; } // Function expression const calculateDiscount = function(price, rate) { return price * (1 - rate); }; // Arrow function (ES6+) const calculateTax = (price, taxRate) => price * taxRate; // Arrow function with block body const processOrder = (order) => { const total = order.price * order.quantity; const tax = total * 0.2; return { total, tax }; }; // Default parameters function greet(name = "Guest", greeting = "Hello") { return `${greeting}, ${name}!`; } // Rest parameters function sum(...numbers) { return numbers.reduce((acc, n) => acc + n, 0); } // Destructuring parameters function createUser({ name, email, age = 18 }) { return { name, email, age, createdAt: new Date() }; } // Higher-order functions function withLogging(fn) { return function(...args) { console.log(`Calling with:`, args); const result = fn(...args); console.log(`Result:`, result); return result; }; } const loggedSum = withLogging(sum); loggedSum(1, 2, 3); // Logs inputs and output Enter fullscreen mode Exit fullscreen mode COMMAND_BLOCK: // Traditional function declaration function calculateTotal(price, quantity) { return price * quantity; } // Function expression const calculateDiscount = function(price, rate) { return price * (1 - rate); }; // Arrow function (ES6+) const calculateTax = (price, taxRate) => price * taxRate; // Arrow function with block body const processOrder = (order) => { const total = order.price * order.quantity; const tax = total * 0.2; return { total, tax }; }; // Default parameters function greet(name = "Guest", greeting = "Hello") { return `${greeting}, ${name}!`; } // Rest parameters function sum(...numbers) { return numbers.reduce((acc, n) => acc + n, 0); } // Destructuring parameters function createUser({ name, email, age = 18 }) { return { name, email, age, createdAt: new Date() }; } // Higher-order functions function withLogging(fn) { return function(...args) { console.log(`Calling with:`, args); const result = fn(...args); console.log(`Result:`, result); return result; }; } const loggedSum = withLogging(sum); loggedSum(1, 2, 3); // Logs inputs and output COMMAND_BLOCK: // Traditional function declaration function calculateTotal(price, quantity) { return price * quantity; } // Function expression const calculateDiscount = function(price, rate) { return price * (1 - rate); }; // Arrow function (ES6+) const calculateTax = (price, taxRate) => price * taxRate; // Arrow function with block body const processOrder = (order) => { const total = order.price * order.quantity; const tax = total * 0.2; return { total, tax }; }; // Default parameters function greet(name = "Guest", greeting = "Hello") { return `${greeting}, ${name}!`; } // Rest parameters function sum(...numbers) { return numbers.reduce((acc, n) => acc + n, 0); } // Destructuring parameters function createUser({ name, email, age = 18 }) { return { name, email, age, createdAt: new Date() }; } // Higher-order functions function withLogging(fn) { return function(...args) { console.log(`Calling with:`, args); const result = fn(...args); console.log(`Result:`, result); return result; }; } const loggedSum = withLogging(sum); loggedSum(1, 2, 3); // Logs inputs and output COMMAND_BLOCK: package main import ( "errors" "fmt" ) // Basic function with typed parameters and return func calculateTotal(price float64, quantity int) float64 { return price * float64(quantity) } // Multiple return values (idiomatic for error handling) func divide(a, b float64) (float64, error) { if b == 0 { return 0, errors.New("division by zero") } return a / b, nil } // Named return values func calculateStats(numbers []int) (sum int, avg float64, count int) { count = len(numbers) for _, n := range numbers { sum += n } if count > 0 { avg = float64(sum) / float64(count) } return // naked return uses named values } // Variadic functions (like JavaScript's rest parameters) func sum(numbers ...int) int { total := 0 for _, n := range numbers { total += n } return total } // Functions as values func applyOperation(a, b int, op func(int, int) int) int { return op(a, b) } // Closures func counter() func() int { count := 0 return func() int { count++ return count } } // Methods (functions with receivers) type Rectangle struct { Width float64 Height float64 } func (r Rectangle) Area() float64 { return r.Width * r.Height } // Pointer receivers for mutation func (r *Rectangle) Scale(factor float64) { r.Width *= factor r.Height *= factor } func main() { // Using multiple return values result, err := divide(10, 2) if err != nil { fmt.Println("Error:", err) return } fmt.Println("Result:", result) // Variadic function total := sum(1, 2, 3, 4, 5) // Function as value multiply := func(a, b int) int { return a * b } result = applyOperation(5, 3, multiply) } Enter fullscreen mode Exit fullscreen mode COMMAND_BLOCK: package main import ( "errors" "fmt" ) // Basic function with typed parameters and return func calculateTotal(price float64, quantity int) float64 { return price * float64(quantity) } // Multiple return values (idiomatic for error handling) func divide(a, b float64) (float64, error) { if b == 0 { return 0, errors.New("division by zero") } return a / b, nil } // Named return values func calculateStats(numbers []int) (sum int, avg float64, count int) { count = len(numbers) for _, n := range numbers { sum += n } if count > 0 { avg = float64(sum) / float64(count) } return // naked return uses named values } // Variadic functions (like JavaScript's rest parameters) func sum(numbers ...int) int { total := 0 for _, n := range numbers { total += n } return total } // Functions as values func applyOperation(a, b int, op func(int, int) int) int { return op(a, b) } // Closures func counter() func() int { count := 0 return func() int { count++ return count } } // Methods (functions with receivers) type Rectangle struct { Width float64 Height float64 } func (r Rectangle) Area() float64 { return r.Width * r.Height } // Pointer receivers for mutation func (r *Rectangle) Scale(factor float64) { r.Width *= factor r.Height *= factor } func main() { // Using multiple return values result, err := divide(10, 2) if err != nil { fmt.Println("Error:", err) return } fmt.Println("Result:", result) // Variadic function total := sum(1, 2, 3, 4, 5) // Function as value multiply := func(a, b int) int { return a * b } result = applyOperation(5, 3, multiply) } COMMAND_BLOCK: package main import ( "errors" "fmt" ) // Basic function with typed parameters and return func calculateTotal(price float64, quantity int) float64 { return price * float64(quantity) } // Multiple return values (idiomatic for error handling) func divide(a, b float64) (float64, error) { if b == 0 { return 0, errors.New("division by zero") } return a / b, nil } // Named return values func calculateStats(numbers []int) (sum int, avg float64, count int) { count = len(numbers) for _, n := range numbers { sum += n } if count > 0 { avg = float64(sum) / float64(count) } return // naked return uses named values } // Variadic functions (like JavaScript's rest parameters) func sum(numbers ...int) int { total := 0 for _, n := range numbers { total += n } return total } // Functions as values func applyOperation(a, b int, op func(int, int) int) int { return op(a, b) } // Closures func counter() func() int { count := 0 return func() int { count++ return count } } // Methods (functions with receivers) type Rectangle struct { Width float64 Height float64 } func (r Rectangle) Area() float64 { return r.Width * r.Height } // Pointer receivers for mutation func (r *Rectangle) Scale(factor float64) { r.Width *= factor r.Height *= factor } func main() { // Using multiple return values result, err := divide(10, 2) if err != nil { fmt.Println("Error:", err) return } fmt.Println("Result:", result) // Variadic function total := sum(1, 2, 3, 4, 5) // Function as value multiply := func(a, b int) int { return a * b } result = applyOperation(5, 3, multiply) } COMMAND_BLOCK: // Traditional try-catch function readConfig(filename) { try { const data = fs.readFileSync(filename, 'utf8'); return JSON.parse(data); } catch (error) { console.error(`Failed to read config: ${error.message}`); throw error; // Re-throw or handle } finally { console.log('Cleanup code runs regardless'); } } // Async error handling with promises async function fetchUserData(userId) { try { const response = await fetch(`/api/users/${userId}`); if (!response.ok) { throw new Error(`HTTP ${response.status}: ${response.statusText}`); } const data = await response.json(); return data; } catch (error) { if (error.name === 'NetworkError') { console.error('Network error:', error); } else if (error.name === 'SyntaxError') { console.error('Invalid JSON:', error); } else { console.error('Unknown error:', error); } throw error; } } // Promise-based error handling fetchUserData(123) .then(user => console.log(user)) .catch(error => console.error(error)) .finally(() => console.log('Done')); // Custom error types class ValidationError extends Error { constructor(field, message) { super(message); this.name = 'ValidationError'; this.field = field; } } function validateUser(user) { if (!user.email) { throw new ValidationError('email', 'Email is required'); } if (user.age < 0) { throw new ValidationError('age', 'Age must be positive'); } } Enter fullscreen mode Exit fullscreen mode COMMAND_BLOCK: // Traditional try-catch function readConfig(filename) { try { const data = fs.readFileSync(filename, 'utf8'); return JSON.parse(data); } catch (error) { console.error(`Failed to read config: ${error.message}`); throw error; // Re-throw or handle } finally { console.log('Cleanup code runs regardless'); } } // Async error handling with promises async function fetchUserData(userId) { try { const response = await fetch(`/api/users/${userId}`); if (!response.ok) { throw new Error(`HTTP ${response.status}: ${response.statusText}`); } const data = await response.json(); return data; } catch (error) { if (error.name === 'NetworkError') { console.error('Network error:', error); } else if (error.name === 'SyntaxError') { console.error('Invalid JSON:', error); } else { console.error('Unknown error:', error); } throw error; } } // Promise-based error handling fetchUserData(123) .then(user => console.log(user)) .catch(error => console.error(error)) .finally(() => console.log('Done')); // Custom error types class ValidationError extends Error { constructor(field, message) { super(message); this.name = 'ValidationError'; this.field = field; } } function validateUser(user) { if (!user.email) { throw new ValidationError('email', 'Email is required'); } if (user.age < 0) { throw new ValidationError('age', 'Age must be positive'); } } COMMAND_BLOCK: // Traditional try-catch function readConfig(filename) { try { const data = fs.readFileSync(filename, 'utf8'); return JSON.parse(data); } catch (error) { console.error(`Failed to read config: ${error.message}`); throw error; // Re-throw or handle } finally { console.log('Cleanup code runs regardless'); } } // Async error handling with promises async function fetchUserData(userId) { try { const response = await fetch(`/api/users/${userId}`); if (!response.ok) { throw new Error(`HTTP ${response.status}: ${response.statusText}`); } const data = await response.json(); return data; } catch (error) { if (error.name === 'NetworkError') { console.error('Network error:', error); } else if (error.name === 'SyntaxError') { console.error('Invalid JSON:', error); } else { console.error('Unknown error:', error); } throw error; } } // Promise-based error handling fetchUserData(123) .then(user => console.log(user)) .catch(error => console.error(error)) .finally(() => console.log('Done')); // Custom error types class ValidationError extends Error { constructor(field, message) { super(message); this.name = 'ValidationError'; this.field = field; } } function validateUser(user) { if (!user.email) { throw new ValidationError('email', 'Email is required'); } if (user.age < 0) { throw new ValidationError('age', 'Age must be positive'); } } CODE_BLOCK: package main import ( "encoding/json" "errors" "fmt" "os" ) // Errors are just values func readConfig(filename string) (map[string]interface{}, error) { data, err := os.ReadFile(filename) if err != nil { return nil, fmt.Errorf("failed to read config: %w", err) } var config map[string]interface{} if err := json.Unmarshal(data, &config); err != nil { return nil, fmt.Errorf("failed to parse JSON: %w", err) } return config, nil } // Multiple error checking func processUser(userID int) error { user, err := fetchUser(userID) if err != nil { return fmt.Errorf("fetch failed: %w", err) } if err := validateUser(user); err != nil { return fmt.Errorf("validation failed: %w", err) } if err := saveUser(user); err != nil { return fmt.Errorf("save failed: %w", err) } return nil } // Custom error types type ValidationError struct { Field string Message string } func (e *ValidationError) Error() string { return fmt.Sprintf("validation error on %s: %s", e.Field, e.Message) } func validateUser(user *User) error { if user.Email == "" { return &ValidationError{ Field: "email", Message: "email is required", } } if user.Age < 0 { return &ValidationError{ Field: "age", Message: "age must be positive", } } return nil } // Error wrapping and unwrapping (Go 1.13+) func fetchAndProcess(id int) error { data, err := fetchFromAPI(id) if err != nil { // Wrap error with context return fmt.Errorf("processing user %d: %w", id, err) } return processData(data) } // Checking for specific errors func handleError(err error) { var validationErr *ValidationError if errors.As(err, &validationErr) { fmt.Printf("Validation failed on field: %s\n", validationErr.Field) return } if errors.Is(err, os.ErrNotExist) { fmt.Println("File not found") return } fmt.Println("Unknown error:", err) } // Defer for cleanup (like finally) func processFile(filename string) error { file, err := os.Open(filename) if err != nil { return err } defer file.Close() // Guaranteed to run // Process file... return nil } Enter fullscreen mode Exit fullscreen mode CODE_BLOCK: package main import ( "encoding/json" "errors" "fmt" "os" ) // Errors are just values func readConfig(filename string) (map[string]interface{}, error) { data, err := os.ReadFile(filename) if err != nil { return nil, fmt.Errorf("failed to read config: %w", err) } var config map[string]interface{} if err := json.Unmarshal(data, &config); err != nil { return nil, fmt.Errorf("failed to parse JSON: %w", err) } return config, nil } // Multiple error checking func processUser(userID int) error { user, err := fetchUser(userID) if err != nil { return fmt.Errorf("fetch failed: %w", err) } if err := validateUser(user); err != nil { return fmt.Errorf("validation failed: %w", err) } if err := saveUser(user); err != nil { return fmt.Errorf("save failed: %w", err) } return nil } // Custom error types type ValidationError struct { Field string Message string } func (e *ValidationError) Error() string { return fmt.Sprintf("validation error on %s: %s", e.Field, e.Message) } func validateUser(user *User) error { if user.Email == "" { return &ValidationError{ Field: "email", Message: "email is required", } } if user.Age < 0 { return &ValidationError{ Field: "age", Message: "age must be positive", } } return nil } // Error wrapping and unwrapping (Go 1.13+) func fetchAndProcess(id int) error { data, err := fetchFromAPI(id) if err != nil { // Wrap error with context return fmt.Errorf("processing user %d: %w", id, err) } return processData(data) } // Checking for specific errors func handleError(err error) { var validationErr *ValidationError if errors.As(err, &validationErr) { fmt.Printf("Validation failed on field: %s\n", validationErr.Field) return } if errors.Is(err, os.ErrNotExist) { fmt.Println("File not found") return } fmt.Println("Unknown error:", err) } // Defer for cleanup (like finally) func processFile(filename string) error { file, err := os.Open(filename) if err != nil { return err } defer file.Close() // Guaranteed to run // Process file... return nil } CODE_BLOCK: package main import ( "encoding/json" "errors" "fmt" "os" ) // Errors are just values func readConfig(filename string) (map[string]interface{}, error) { data, err := os.ReadFile(filename) if err != nil { return nil, fmt.Errorf("failed to read config: %w", err) } var config map[string]interface{} if err := json.Unmarshal(data, &config); err != nil { return nil, fmt.Errorf("failed to parse JSON: %w", err) } return config, nil } // Multiple error checking func processUser(userID int) error { user, err := fetchUser(userID) if err != nil { return fmt.Errorf("fetch failed: %w", err) } if err := validateUser(user); err != nil { return fmt.Errorf("validation failed: %w", err) } if err := saveUser(user); err != nil { return fmt.Errorf("save failed: %w", err) } return nil } // Custom error types type ValidationError struct { Field string Message string } func (e *ValidationError) Error() string { return fmt.Sprintf("validation error on %s: %s", e.Field, e.Message) } func validateUser(user *User) error { if user.Email == "" { return &ValidationError{ Field: "email", Message: "email is required", } } if user.Age < 0 { return &ValidationError{ Field: "age", Message: "age must be positive", } } return nil } // Error wrapping and unwrapping (Go 1.13+) func fetchAndProcess(id int) error { data, err := fetchFromAPI(id) if err != nil { // Wrap error with context return fmt.Errorf("processing user %d: %w", id, err) } return processData(data) } // Checking for specific errors func handleError(err error) { var validationErr *ValidationError if errors.As(err, &validationErr) { fmt.Printf("Validation failed on field: %s\n", validationErr.Field) return } if errors.Is(err, os.ErrNotExist) { fmt.Println("File not found") return } fmt.Println("Unknown error:", err) } // Defer for cleanup (like finally) func processFile(filename string) error { file, err := os.Open(filename) if err != nil { return err } defer file.Close() // Guaranteed to run // Process file... return nil } COMMAND_BLOCK: // Promises function fetchUser(id) { return fetch(`/api/users/${id}`) .then(response => response.json()) .then(data => { console.log('User:', data); return data; }) .catch(error => { console.error('Error:', error); throw error; }); } // Async/await (syntactic sugar over promises) async function getUserProfile(userId) { try { const user = await fetchUser(userId); const posts = await fetchUserPosts(userId); const followers = await fetchFollowers(userId); return { user, posts, followers }; } catch (error) { console.error('Failed to get profile:', error); throw error; } } // Parallel execution async function getMultipleUsers(ids) { // Sequential (slow) const users = []; for (const id of ids) { users.push(await fetchUser(id)); } // Parallel (fast) const promises = ids.map(id => fetchUser(id)); const usersParallel = await Promise.all(promises); return usersParallel; } // Race conditions async function fetchWithTimeout(url, timeout = 5000) { const timeoutPromise = new Promise((_, reject) => { setTimeout(() => reject(new Error('Timeout')), timeout); }); return Promise.race([ fetch(url), timeoutPromise ]); } // Promise combinators async function complexFlow() { // All must succeed const [user, config, stats] = await Promise.all([ fetchUser(1), fetchConfig(), fetchStats() ]); // First to succeed const fastestServer = await Promise.race([ fetch('https://server1.com/data'), fetch('https://server2.com/data') ]); // All must settle (succeed or fail) const results = await Promise.allSettled([ riskyOperation1(), riskyOperation2(), riskyOperation3() ]); results.forEach((result, index) => { if (result.status === 'fulfilled') { console.log(`Op ${index} succeeded:`, result.value); } else { console.log(`Op ${index} failed:`, result.reason); } }); } Enter fullscreen mode Exit fullscreen mode COMMAND_BLOCK: // Promises function fetchUser(id) { return fetch(`/api/users/${id}`) .then(response => response.json()) .then(data => { console.log('User:', data); return data; }) .catch(error => { console.error('Error:', error); throw error; }); } // Async/await (syntactic sugar over promises) async function getUserProfile(userId) { try { const user = await fetchUser(userId); const posts = await fetchUserPosts(userId); const followers = await fetchFollowers(userId); return { user, posts, followers }; } catch (error) { console.error('Failed to get profile:', error); throw error; } } // Parallel execution async function getMultipleUsers(ids) { // Sequential (slow) const users = []; for (const id of ids) { users.push(await fetchUser(id)); } // Parallel (fast) const promises = ids.map(id => fetchUser(id)); const usersParallel = await Promise.all(promises); return usersParallel; } // Race conditions async function fetchWithTimeout(url, timeout = 5000) { const timeoutPromise = new Promise((_, reject) => { setTimeout(() => reject(new Error('Timeout')), timeout); }); return Promise.race([ fetch(url), timeoutPromise ]); } // Promise combinators async function complexFlow() { // All must succeed const [user, config, stats] = await Promise.all([ fetchUser(1), fetchConfig(), fetchStats() ]); // First to succeed const fastestServer = await Promise.race([ fetch('https://server1.com/data'), fetch('https://server2.com/data') ]); // All must settle (succeed or fail) const results = await Promise.allSettled([ riskyOperation1(), riskyOperation2(), riskyOperation3() ]); results.forEach((result, index) => { if (result.status === 'fulfilled') { console.log(`Op ${index} succeeded:`, result.value); } else { console.log(`Op ${index} failed:`, result.reason); } }); } COMMAND_BLOCK: // Promises function fetchUser(id) { return fetch(`/api/users/${id}`) .then(response => response.json()) .then(data => { console.log('User:', data); return data; }) .catch(error => { console.error('Error:', error); throw error; }); } // Async/await (syntactic sugar over promises) async function getUserProfile(userId) { try { const user = await fetchUser(userId); const posts = await fetchUserPosts(userId); const followers = await fetchFollowers(userId); return { user, posts, followers }; } catch (error) { console.error('Failed to get profile:', error); throw error; } } // Parallel execution async function getMultipleUsers(ids) { // Sequential (slow) const users = []; for (const id of ids) { users.push(await fetchUser(id)); } // Parallel (fast) const promises = ids.map(id => fetchUser(id)); const usersParallel = await Promise.all(promises); return usersParallel; } // Race conditions async function fetchWithTimeout(url, timeout = 5000) { const timeoutPromise = new Promise((_, reject) => { setTimeout(() => reject(new Error('Timeout')), timeout); }); return Promise.race([ fetch(url), timeoutPromise ]); } // Promise combinators async function complexFlow() { // All must succeed const [user, config, stats] = await Promise.all([ fetchUser(1), fetchConfig(), fetchStats() ]); // First to succeed const fastestServer = await Promise.race([ fetch('https://server1.com/data'), fetch('https://server2.com/data') ]); // All must settle (succeed or fail) const results = await Promise.allSettled([ riskyOperation1(), riskyOperation2(), riskyOperation3() ]); results.forEach((result, index) => { if (result.status === 'fulfilled') { console.log(`Op ${index} succeeded:`, result.value); } else { console.log(`Op ${index} failed:`, result.reason); } }); } CODE_BLOCK: package main import ( "fmt" "sync" "time" ) // Basic goroutine func sayHello() { fmt.Println("Hello from goroutine") } func basicGoroutine() { go sayHello() // Runs concurrently time.Sleep(time.Second) // Wait for goroutine (bad practice, use sync) } // Channels for communication func fetchUser(id int, ch chan<- User) { // Simulate API call time.Sleep(100 * time.Millisecond) user := User{ID: id, Name: fmt.Sprintf("User%d", id)} ch <- user // Send to channel } func useChannels() { userChan := make(chan User) go fetchUser(1, userChan) user := <-userChan // Receive from channel (blocks until data available) fmt.Println("Received:", user) } // Concurrent fetching (like Promise.all) func fetchMultipleUsers(ids []int) []User { users := make([]User, len(ids)) var wg sync.WaitGroup for i, id := range ids { wg.Add(1) go func(index, userID int) { defer wg.Done() users[index] = fetchUserSync(userID) }(i, id) } wg.Wait() // Wait for all goroutines return users } // Channel patterns func channelPatterns() { // Buffered channel ch := make(chan int, 3) // Can hold 3 items without blocking ch <- 1 ch <- 2 ch <- 3 // ch <- 4 // Would block until something is received // Select for multiple channels (like Promise.race) ch1 := make(chan string) ch2 := make(chan string) go func() { time.Sleep(100 * time.Millisecond) ch1 <- "from ch1" }() go func() { time.Sleep(200 * time.Millisecond) ch2 <- "from ch2" }() select { case msg1 := <-ch1: fmt.Println("Received:", msg1) case msg2 := <-ch2: fmt.Println("Received:", msg2) case <-time.After(500 * time.Millisecond): fmt.Println("Timeout") } } // Worker pool pattern func workerPool() { jobs := make(chan int, 100) results := make(chan int, 100) // Start workers for w := 1; w <= 3; w++ { go worker(w, jobs, results) } // Send jobs for j := 1; j <= 9; j++ { jobs <- j } close(jobs) // Collect results for a := 1; a <= 9; a++ { <-results } } func worker(id int, jobs <-chan int, results chan<- int) { for j := range jobs { fmt.Printf("Worker %d processing job %d\n", id, j) time.Sleep(time.Second) results <- j * 2 } } // Context for cancellation (like AbortController) import "context" func fetchWithContext(ctx context.Context, id int) (User, error) { resultChan := make(chan User) errChan := make(chan error) go func() { // Simulate long operation time.Sleep(2 * time.Second) resultChan <- User{ID: id} }() select { case user := <-resultChan: return user, nil case err := <-errChan: return User{}, err case <-ctx.Done(): return User{}, ctx.Err() // Cancelled or timed out } } func useContext() { ctx, cancel := context.WithTimeout(context.Background(), 1*time.Second) defer cancel() user, err := fetchWithContext(ctx, 1) if err != nil { fmt.Println("Error:", err) // Will timeout } } // Mutex for shared state type SafeCounter struct { mu sync.Mutex count int } func (c *SafeCounter) Increment() { c.mu.Lock() defer c.mu.Unlock() c.count++ } func (c *SafeCounter) Value() int { c.mu.Lock() defer c.mu.Unlock() return c.count } Enter fullscreen mode Exit fullscreen mode CODE_BLOCK: package main import ( "fmt" "sync" "time" ) // Basic goroutine func sayHello() { fmt.Println("Hello from goroutine") } func basicGoroutine() { go sayHello() // Runs concurrently time.Sleep(time.Second) // Wait for goroutine (bad practice, use sync) } // Channels for communication func fetchUser(id int, ch chan<- User) { // Simulate API call time.Sleep(100 * time.Millisecond) user := User{ID: id, Name: fmt.Sprintf("User%d", id)} ch <- user // Send to channel } func useChannels() { userChan := make(chan User) go fetchUser(1, userChan) user := <-userChan // Receive from channel (blocks until data available) fmt.Println("Received:", user) } // Concurrent fetching (like Promise.all) func fetchMultipleUsers(ids []int) []User { users := make([]User, len(ids)) var wg sync.WaitGroup for i, id := range ids { wg.Add(1) go func(index, userID int) { defer wg.Done() users[index] = fetchUserSync(userID) }(i, id) } wg.Wait() // Wait for all goroutines return users } // Channel patterns func channelPatterns() { // Buffered channel ch := make(chan int, 3) // Can hold 3 items without blocking ch <- 1 ch <- 2 ch <- 3 // ch <- 4 // Would block until something is received // Select for multiple channels (like Promise.race) ch1 := make(chan string) ch2 := make(chan string) go func() { time.Sleep(100 * time.Millisecond) ch1 <- "from ch1" }() go func() { time.Sleep(200 * time.Millisecond) ch2 <- "from ch2" }() select { case msg1 := <-ch1: fmt.Println("Received:", msg1) case msg2 := <-ch2: fmt.Println("Received:", msg2) case <-time.After(500 * time.Millisecond): fmt.Println("Timeout") } } // Worker pool pattern func workerPool() { jobs := make(chan int, 100) results := make(chan int, 100) // Start workers for w := 1; w <= 3; w++ { go worker(w, jobs, results) } // Send jobs for j := 1; j <= 9; j++ { jobs <- j } close(jobs) // Collect results for a := 1; a <= 9; a++ { <-results } } func worker(id int, jobs <-chan int, results chan<- int) { for j := range jobs { fmt.Printf("Worker %d processing job %d\n", id, j) time.Sleep(time.Second) results <- j * 2 } } // Context for cancellation (like AbortController) import "context" func fetchWithContext(ctx context.Context, id int) (User, error) { resultChan := make(chan User) errChan := make(chan error) go func() { // Simulate long operation time.Sleep(2 * time.Second) resultChan <- User{ID: id} }() select { case user := <-resultChan: return user, nil case err := <-errChan: return User{}, err case <-ctx.Done(): return User{}, ctx.Err() // Cancelled or timed out } } func useContext() { ctx, cancel := context.WithTimeout(context.Background(), 1*time.Second) defer cancel() user, err := fetchWithContext(ctx, 1) if err != nil { fmt.Println("Error:", err) // Will timeout } } // Mutex for shared state type SafeCounter struct { mu sync.Mutex count int } func (c *SafeCounter) Increment() { c.mu.Lock() defer c.mu.Unlock() c.count++ } func (c *SafeCounter) Value() int { c.mu.Lock() defer c.mu.Unlock() return c.count } CODE_BLOCK: package main import ( "fmt" "sync" "time" ) // Basic goroutine func sayHello() { fmt.Println("Hello from goroutine") } func basicGoroutine() { go sayHello() // Runs concurrently time.Sleep(time.Second) // Wait for goroutine (bad practice, use sync) } // Channels for communication func fetchUser(id int, ch chan<- User) { // Simulate API call time.Sleep(100 * time.Millisecond) user := User{ID: id, Name: fmt.Sprintf("User%d", id)} ch <- user // Send to channel } func useChannels() { userChan := make(chan User) go fetchUser(1, userChan) user := <-userChan // Receive from channel (blocks until data available) fmt.Println("Received:", user) } // Concurrent fetching (like Promise.all) func fetchMultipleUsers(ids []int) []User { users := make([]User, len(ids)) var wg sync.WaitGroup for i, id := range ids { wg.Add(1) go func(index, userID int) { defer wg.Done() users[index] = fetchUserSync(userID) }(i, id) } wg.Wait() // Wait for all goroutines return users } // Channel patterns func channelPatterns() { // Buffered channel ch := make(chan int, 3) // Can hold 3 items without blocking ch <- 1 ch <- 2 ch <- 3 // ch <- 4 // Would block until something is received // Select for multiple channels (like Promise.race) ch1 := make(chan string) ch2 := make(chan string) go func() { time.Sleep(100 * time.Millisecond) ch1 <- "from ch1" }() go func() { time.Sleep(200 * time.Millisecond) ch2 <- "from ch2" }() select { case msg1 := <-ch1: fmt.Println("Received:", msg1) case msg2 := <-ch2: fmt.Println("Received:", msg2) case <-time.After(500 * time.Millisecond): fmt.Println("Timeout") } } // Worker pool pattern func workerPool() { jobs := make(chan int, 100) results := make(chan int, 100) // Start workers for w := 1; w <= 3; w++ { go worker(w, jobs, results) } // Send jobs for j := 1; j <= 9; j++ { jobs <- j } close(jobs) // Collect results for a := 1; a <= 9; a++ { <-results } } func worker(id int, jobs <-chan int, results chan<- int) { for j := range jobs { fmt.Printf("Worker %d processing job %d\n", id, j) time.Sleep(time.Second) results <- j * 2 } } // Context for cancellation (like AbortController) import "context" func fetchWithContext(ctx context.Context, id int) (User, error) { resultChan := make(chan User) errChan := make(chan error) go func() { // Simulate long operation time.Sleep(2 * time.Second) resultChan <- User{ID: id} }() select { case user := <-resultChan: return user, nil case err := <-errChan: return User{}, err case <-ctx.Done(): return User{}, ctx.Err() // Cancelled or timed out } } func useContext() { ctx, cancel := context.WithTimeout(context.Background(), 1*time.Second) defer cancel() user, err := fetchWithContext(ctx, 1) if err != nil { fmt.Println("Error:", err) // Will timeout } } // Mutex for shared state type SafeCounter struct { mu sync.Mutex count int } func (c *SafeCounter) Increment() { c.mu.Lock() defer c.mu.Unlock() c.count++ } func (c *SafeCounter) Value() int { c.mu.Lock() defer c.mu.Unlock() return c.count } COMMAND_BLOCK: // Object literals const user = { name: "Mephesto", email: "[email protected]", age: 25, greet() { return `Hello, I'm ${this.name}`; } }; // Dynamic properties user.location = "Ukraine"; delete user.age; // ES6 Classes (syntactic sugar over prototypes) class User { constructor(name, email) { this.name = name; this.email = email; this.createdAt = new Date(); } greet() { return `Hello, I'm ${this.name}`; } static fromJSON(json) { const data = JSON.parse(json); return new User(data.name, data.email); } get displayName() { return this.name.toUpperCase(); } set displayName(value) { this.name = value.toLowerCase(); } } // Inheritance class AdminUser extends User { constructor(name, email, permissions) { super(name, email); this.permissions = permissions; } greet() { return `Hello, I'm ${this.name} (Admin)`; } hasPermission(perm) { return this.permissions.includes(perm); } } // Private fields (ES2022) class BankAccount { #balance = 0; deposit(amount) { this.#balance += amount; } getBalance() { return this.#balance; } } // Mixing concerns const withLogging = (BaseClass) => { return class extends BaseClass { log(message) { console.log(`[${this.constructor.name}] ${message}`); } }; }; const LoggedUser = withLogging(User); Enter fullscreen mode Exit fullscreen mode COMMAND_BLOCK: // Object literals const user = { name: "Mephesto", email: "[email protected]", age: 25, greet() { return `Hello, I'm ${this.name}`; } }; // Dynamic properties user.location = "Ukraine"; delete user.age; // ES6 Classes (syntactic sugar over prototypes) class User { constructor(name, email) { this.name = name; this.email = email; this.createdAt = new Date(); } greet() { return `Hello, I'm ${this.name}`; } static fromJSON(json) { const data = JSON.parse(json); return new User(data.name, data.email); } get displayName() { return this.name.toUpperCase(); } set displayName(value) { this.name = value.toLowerCase(); } } // Inheritance class AdminUser extends User { constructor(name, email, permissions) { super(name, email); this.permissions = permissions; } greet() { return `Hello, I'm ${this.name} (Admin)`; } hasPermission(perm) { return this.permissions.includes(perm); } } // Private fields (ES2022) class BankAccount { #balance = 0; deposit(amount) { this.#balance += amount; } getBalance() { return this.#balance; } } // Mixing concerns const withLogging = (BaseClass) => { return class extends BaseClass { log(message) { console.log(`[${this.constructor.name}] ${message}`); } }; }; const LoggedUser = withLogging(User); COMMAND_BLOCK: // Object literals const user = { name: "Mephesto", email: "[email protected]", age: 25, greet() { return `Hello, I'm ${this.name}`; } }; // Dynamic properties user.location = "Ukraine"; delete user.age; // ES6 Classes (syntactic sugar over prototypes) class User { constructor(name, email) { this.name = name; this.email = email; this.createdAt = new Date(); } greet() { return `Hello, I'm ${this.name}`; } static fromJSON(json) { const data = JSON.parse(json); return new User(data.name, data.email); } get displayName() { return this.name.toUpperCase(); } set displayName(value) { this.name = value.toLowerCase(); } } // Inheritance class AdminUser extends User { constructor(name, email, permissions) { super(name, email); this.permissions = permissions; } greet() { return `Hello, I'm ${this.name} (Admin)`; } hasPermission(perm) { return this.permissions.includes(perm); } } // Private fields (ES2022) class BankAccount { #balance = 0; deposit(amount) { this.#balance += amount; } getBalance() { return this.#balance; } } // Mixing concerns const withLogging = (BaseClass) => { return class extends BaseClass { log(message) { console.log(`[${this.constructor.name}] ${message}`); } }; }; const LoggedUser = withLogging(User); CODE_BLOCK: package main import ( "encoding/json" "fmt" "strings" "time" ) // Struct definition type User struct { Name string `json:"name"` Email string `json:"email"` CreatedAt time.Time `json:"created_at"` } // Constructor pattern (not built-in) func NewUser(name, email string) *User { return &User{ Name: name, Email: email, CreatedAt: time.Now(), } } // Methods with receivers func (u User) Greet() string { return fmt.Sprintf("Hello, I'm %s", u.Name) } // Pointer receivers for mutation func (u *User) UpdateEmail(email string) { u.Email = email } // "Getters" (not idiomatic to call them GetX) func (u User) DisplayName() string { return strings.ToUpper(u.Name) } // Embedded structs (composition, not inheritance) type AdminUser struct { User // Embedded field Permissions []string } func NewAdminUser(name, email string, perms []string) *AdminUser { return &AdminUser{ User: *NewUser(name, email), Permissions: perms, } } // Method overriding through embedding func (a AdminUser) Greet() string { return fmt.Sprintf("Hello, I'm %s (Admin)", a.Name) } func (a AdminUser) HasPermission(perm string) bool { for _, p := range a.Permissions { if p == perm { return true } } return false } // Unexported fields (private) type bankAccount struct { balance int } func NewBankAccount() *bankAccount { return &bankAccount{balance: 0} } func (b *bankAccount) Deposit(amount int) { b.balance += amount } func (b *bankAccount) Balance() int { return b.balance } // JSON marshaling/unmarshaling func jsonExample() { user := NewUser("Mephesto", "[email protected]") // Marshal to JSON data, err := json.Marshal(user) if err != nil { panic(err) } fmt.Println(string(data)) // Unmarshal from JSON var newUser User if err := json.Unmarshal(data, &newUser); err != nil { panic(err) } } // Struct tags for metadata type APIUser struct { ID int `json:"id" db:"user_id"` Username string `json:"username" db:"username" validate:"required"` Email string `json:"email,omitempty" db:"email"` CreatedAt time.Time `json:"created_at" db:"created_at"` password string // unexported, won't be marshaled } // Anonymous structs for one-off use func anonymousStructs() { config := struct { Host string Port int }{ Host: "localhost", Port: 8080, } fmt.Printf("Server: %s:%d\n", config.Host, config.Port) } Enter fullscreen mode Exit fullscreen mode CODE_BLOCK: package main import ( "encoding/json" "fmt" "strings" "time" ) // Struct definition type User struct { Name string `json:"name"` Email string `json:"email"` CreatedAt time.Time `json:"created_at"` } // Constructor pattern (not built-in) func NewUser(name, email string) *User { return &User{ Name: name, Email: email, CreatedAt: time.Now(), } } // Methods with receivers func (u User) Greet() string { return fmt.Sprintf("Hello, I'm %s", u.Name) } // Pointer receivers for mutation func (u *User) UpdateEmail(email string) { u.Email = email } // "Getters" (not idiomatic to call them GetX) func (u User) DisplayName() string { return strings.ToUpper(u.Name) } // Embedded structs (composition, not inheritance) type AdminUser struct { User // Embedded field Permissions []string } func NewAdminUser(name, email string, perms []string) *AdminUser { return &AdminUser{ User: *NewUser(name, email), Permissions: perms, } } // Method overriding through embedding func (a AdminUser) Greet() string { return fmt.Sprintf("Hello, I'm %s (Admin)", a.Name) } func (a AdminUser) HasPermission(perm string) bool { for _, p := range a.Permissions { if p == perm { return true } } return false } // Unexported fields (private) type bankAccount struct { balance int } func NewBankAccount() *bankAccount { return &bankAccount{balance: 0} } func (b *bankAccount) Deposit(amount int) { b.balance += amount } func (b *bankAccount) Balance() int { return b.balance } // JSON marshaling/unmarshaling func jsonExample() { user := NewUser("Mephesto", "[email protected]") // Marshal to JSON data, err := json.Marshal(user) if err != nil { panic(err) } fmt.Println(string(data)) // Unmarshal from JSON var newUser User if err := json.Unmarshal(data, &newUser); err != nil { panic(err) } } // Struct tags for metadata type APIUser struct { ID int `json:"id" db:"user_id"` Username string `json:"username" db:"username" validate:"required"` Email string `json:"email,omitempty" db:"email"` CreatedAt time.Time `json:"created_at" db:"created_at"` password string // unexported, won't be marshaled } // Anonymous structs for one-off use func anonymousStructs() { config := struct { Host string Port int }{ Host: "localhost", Port: 8080, } fmt.Printf("Server: %s:%d\n", config.Host, config.Port) } CODE_BLOCK: package main import ( "encoding/json" "fmt" "strings" "time" ) // Struct definition type User struct { Name string `json:"name"` Email string `json:"email"` CreatedAt time.Time `json:"created_at"` } // Constructor pattern (not built-in) func NewUser(name, email string) *User { return &User{ Name: name, Email: email, CreatedAt: time.Now(), } } // Methods with receivers func (u User) Greet() string { return fmt.Sprintf("Hello, I'm %s", u.Name) } // Pointer receivers for mutation func (u *User) UpdateEmail(email string) { u.Email = email } // "Getters" (not idiomatic to call them GetX) func (u User) DisplayName() string { return strings.ToUpper(u.Name) } // Embedded structs (composition, not inheritance) type AdminUser struct { User // Embedded field Permissions []string } func NewAdminUser(name, email string, perms []string) *AdminUser { return &AdminUser{ User: *NewUser(name, email), Permissions: perms, } } // Method overriding through embedding func (a AdminUser) Greet() string { return fmt.Sprintf("Hello, I'm %s (Admin)", a.Name) } func (a AdminUser) HasPermission(perm string) bool { for _, p := range a.Permissions { if p == perm { return true } } return false } // Unexported fields (private) type bankAccount struct { balance int } func NewBankAccount() *bankAccount { return &bankAccount{balance: 0} } func (b *bankAccount) Deposit(amount int) { b.balance += amount } func (b *bankAccount) Balance() int { return b.balance } // JSON marshaling/unmarshaling func jsonExample() { user := NewUser("Mephesto", "[email protected]") // Marshal to JSON data, err := json.Marshal(user) if err != nil { panic(err) } fmt.Println(string(data)) // Unmarshal from JSON var newUser User if err := json.Unmarshal(data, &newUser); err != nil { panic(err) } } // Struct tags for metadata type APIUser struct { ID int `json:"id" db:"user_id"` Username string `json:"username" db:"username" validate:"required"` Email string `json:"email,omitempty" db:"email"` CreatedAt time.Time `json:"created_at" db:"created_at"` password string // unexported, won't be marshaled } // Anonymous structs for one-off use func anonymousStructs() { config := struct { Host string Port int }{ Host: "localhost", Port: 8080, } fmt.Printf("Server: %s:%d\n", config.Host, config.Port) } CODE_BLOCK: // If-else if (user.age >= 18) { console.log("Adult"); } else if (user.age >= 13) { console.log("Teenager"); } else { console.log("Child"); } // Ternary operator const status = user.isActive ? "Active" : "Inactive"; // Switch switch (user.role) { case "admin": grantAdminAccess(); break; case "moderator": grantModeratorAccess(); break; default: grantUserAccess(); } // Truthy/falsy if (user.email) { // truthy check sendEmail(user.email); } // Nullish coalescing const port = config.port ?? 8080; // Only for null/undefined // Optional chaining const city = user?.address?.city; // Won't throw if undefined // Short-circuit evaluation const name = user.name || "Anonymous"; const value = user.value && user.value.trim(); Enter fullscreen mode Exit fullscreen mode CODE_BLOCK: // If-else if (user.age >= 18) { console.log("Adult"); } else if (user.age >= 13) { console.log("Teenager"); } else { console.log("Child"); } // Ternary operator const status = user.isActive ? "Active" : "Inactive"; // Switch switch (user.role) { case "admin": grantAdminAccess(); break; case "moderator": grantModeratorAccess(); break; default: grantUserAccess(); } // Truthy/falsy if (user.email) { // truthy check sendEmail(user.email); } // Nullish coalescing const port = config.port ?? 8080; // Only for null/undefined // Optional chaining const city = user?.address?.city; // Won't throw if undefined // Short-circuit evaluation const name = user.name || "Anonymous"; const value = user.value && user.value.trim(); CODE_BLOCK: // If-else if (user.age >= 18) { console.log("Adult"); } else if (user.age >= 13) { console.log("Teenager"); } else { console.log("Child"); } // Ternary operator const status = user.isActive ? "Active" : "Inactive"; // Switch switch (user.role) { case "admin": grantAdminAccess(); break; case "moderator": grantModeratorAccess(); break; default: grantUserAccess(); } // Truthy/falsy if (user.email) { // truthy check sendEmail(user.email); } // Nullish coalescing const port = config.port ?? 8080; // Only for null/undefined // Optional chaining const city = user?.address?.city; // Won't throw if undefined // Short-circuit evaluation const name = user.name || "Anonymous"; const value = user.value && user.value.trim(); CODE_BLOCK: package main import "fmt" func controlFlow() { // If-else (no parentheses!) age := 25 if age >= 18 { fmt.Println("Adult") } else if age >= 13 { fmt.Println("Teenager") } else { fmt.Println("Child") } // If with initialization if err := someOperation(); err != nil { fmt.Println("Error:", err) return } // No ternary operator! Use if-else var status string if user.IsActive { status = "Active" } else { status = "Inactive" } // Switch (no break needed!) switch role := user.Role; role { case "admin": grantAdminAccess() case "moderator": grantModeratorAccess() default: grantUserAccess() } // Switch without expression (like if-else chain) switch { case age < 13: fmt.Println("Child") case age < 18: fmt.Println("Teenager") default: fmt.Println("Adult") } // Switch with multiple cases switch day { case "Saturday", "Sunday": fmt.Println("Weekend") case "Monday", "Tuesday", "Wednesday", "Thursday", "Friday": fmt.Println("Weekday") } // Fallthrough (explicit, unlike JavaScript) switch num { case 1: fmt.Println("One") fallthrough case 2: fmt.Println("Two or less") } // Type switch var i interface{} = "hello" switch v := i.(type) { case int: fmt.Printf("Integer: %d\n", v) case string: fmt.Printf("String: %s\n", v) default: fmt.Printf("Unknown type: %T\n", v) } } Enter fullscreen mode Exit fullscreen mode CODE_BLOCK: package main import "fmt" func controlFlow() { // If-else (no parentheses!) age := 25 if age >= 18 { fmt.Println("Adult") } else if age >= 13 { fmt.Println("Teenager") } else { fmt.Println("Child") } // If with initialization if err := someOperation(); err != nil { fmt.Println("Error:", err) return } // No ternary operator! Use if-else var status string if user.IsActive { status = "Active" } else { status = "Inactive" } // Switch (no break needed!) switch role := user.Role; role { case "admin": grantAdminAccess() case "moderator": grantModeratorAccess() default: grantUserAccess() } // Switch without expression (like if-else chain) switch { case age < 13: fmt.Println("Child") case age < 18: fmt.Println("Teenager") default: fmt.Println("Adult") } // Switch with multiple cases switch day { case "Saturday", "Sunday": fmt.Println("Weekend") case "Monday", "Tuesday", "Wednesday", "Thursday", "Friday": fmt.Println("Weekday") } // Fallthrough (explicit, unlike JavaScript) switch num { case 1: fmt.Println("One") fallthrough case 2: fmt.Println("Two or less") } // Type switch var i interface{} = "hello" switch v := i.(type) { case int: fmt.Printf("Integer: %d\n", v) case string: fmt.Printf("String: %s\n", v) default: fmt.Printf("Unknown type: %T\n", v) } } CODE_BLOCK: package main import "fmt" func controlFlow() { // If-else (no parentheses!) age := 25 if age >= 18 { fmt.Println("Adult") } else if age >= 13 { fmt.Println("Teenager") } else { fmt.Println("Child") } // If with initialization if err := someOperation(); err != nil { fmt.Println("Error:", err) return } // No ternary operator! Use if-else var status string if user.IsActive { status = "Active" } else { status = "Inactive" } // Switch (no break needed!) switch role := user.Role; role { case "admin": grantAdminAccess() case "moderator": grantModeratorAccess() default: grantUserAccess() } // Switch without expression (like if-else chain) switch { case age < 13: fmt.Println("Child") case age < 18: fmt.Println("Teenager") default: fmt.Println("Adult") } // Switch with multiple cases switch day { case "Saturday", "Sunday": fmt.Println("Weekend") case "Monday", "Tuesday", "Wednesday", "Thursday", "Friday": fmt.Println("Weekday") } // Fallthrough (explicit, unlike JavaScript) switch num { case 1: fmt.Println("One") fallthrough case 2: fmt.Println("Two or less") } // Type switch var i interface{} = "hello" switch v := i.(type) { case int: fmt.Printf("Integer: %d\n", v) case string: fmt.Printf("String: %s\n", v) default: fmt.Printf("Unknown type: %T\n", v) } } COMMAND_BLOCK: // For loop for (let i = 0; i < 10; i++) { console.log(i); } // For...of (values) const numbers = [1, 2, 3, 4, 5]; for (const num of numbers) { console.log(num); } // For...in (keys/indices) const user = { name: "John", age: 30 }; for (const key in user) { console.log(`${key}: ${user[key]}`); } // While let count = 0; while (count < 10) { console.log(count); count++; } // Do-while do { console.log(count); count--; } while (count > 0); // Array methods (functional style) const doubled = numbers.map(n => n * 2); const evens = numbers.filter(n => n % 2 === 0); const sum = numbers.reduce((acc, n) => acc + n, 0); numbers.forEach((num, index) => { console.log(`${index}: ${num}`); }); // Break and continue for (let i = 0; i < 10; i++) { if (i === 3) continue; if (i === 7) break; console.log(i); } // Labeled loops outer: for (let i = 0; i < 3; i++) { for (let j = 0; j < 3; j++) { if (i === 1 && j === 1) break outer; console.log(i, j); } } Enter fullscreen mode Exit fullscreen mode COMMAND_BLOCK: // For loop for (let i = 0; i < 10; i++) { console.log(i); } // For...of (values) const numbers = [1, 2, 3, 4, 5]; for (const num of numbers) { console.log(num); } // For...in (keys/indices) const user = { name: "John", age: 30 }; for (const key in user) { console.log(`${key}: ${user[key]}`); } // While let count = 0; while (count < 10) { console.log(count); count++; } // Do-while do { console.log(count); count--; } while (count > 0); // Array methods (functional style) const doubled = numbers.map(n => n * 2); const evens = numbers.filter(n => n % 2 === 0); const sum = numbers.reduce((acc, n) => acc + n, 0); numbers.forEach((num, index) => { console.log(`${index}: ${num}`); }); // Break and continue for (let i = 0; i < 10; i++) { if (i === 3) continue; if (i === 7) break; console.log(i); } // Labeled loops outer: for (let i = 0; i < 3; i++) { for (let j = 0; j < 3; j++) { if (i === 1 && j === 1) break outer; console.log(i, j); } } COMMAND_BLOCK: // For loop for (let i = 0; i < 10; i++) { console.log(i); } // For...of (values) const numbers = [1, 2, 3, 4, 5]; for (const num of numbers) { console.log(num); } // For...in (keys/indices) const user = { name: "John", age: 30 }; for (const key in user) { console.log(`${key}: ${user[key]}`); } // While let count = 0; while (count < 10) { console.log(count); count++; } // Do-while do { console.log(count); count--; } while (count > 0); // Array methods (functional style) const doubled = numbers.map(n => n * 2); const evens = numbers.filter(n => n % 2 === 0); const sum = numbers.reduce((acc, n) => acc + n, 0); numbers.forEach((num, index) => { console.log(`${index}: ${num}`); }); // Break and continue for (let i = 0; i < 10; i++) { if (i === 3) continue; if (i === 7) break; console.log(i); } // Labeled loops outer: for (let i = 0; i < 3; i++) { for (let j = 0; j < 3; j++) { if (i === 1 && j === 1) break outer; console.log(i, j); } } CODE_BLOCK: package main import "fmt" func loops() { // For loop (only loop keyword in Go!) for i := 0; i < 10; i++ { fmt.Println(i) } // While-style loop count := 0 for count < 10 { fmt.Println(count) count++ } // Infinite loop for { // Must have break somewhere if someCondition { break } } // Range over slice (like for...of) numbers := []int{1, 2, 3, 4, 5} for index, value := range numbers { fmt.Printf("%d: %d\n", index, value) } // Ignore index with _ for _, value := range numbers { fmt.Println(value) } // Only index for index := range numbers { fmt.Println(index) } // Range over map user := map[string]interface{}{ "name": "John", "age": 30, } for key, value := range user { fmt.Printf("%s: %v\n", key, value) } // Range over string (iterates over runes/characters) for index, char := range "Привіт" { fmt.Printf("%d: %c\n", index, char) } // Range over channel ch := make(chan int, 5) go func() { for i := 0; i < 5; i++ { ch <- i } close(ch) }() for value := range ch { fmt.Println(value) } // Break and continue for i := 0; i < 10; i++ { if i == 3 { continue } if i == 7 { break } fmt.Println(i) } // Labeled loops outer: for i := 0; i < 3; i++ { for j := 0; j < 3; j++ { if i == 1 && j == 1 { break outer } fmt.Println(i, j) } } } // No built-in map/filter/reduce, but easy to implement func Map(slice []int, fn func(int) int) []int { result := make([]int, len(slice)) for i, v := range slice { result[i] = fn(v) } return result } func Filter(slice []int, fn func(int) bool) []int { result := []int{} for _, v := range slice { if fn(v) { result = append(result, v) } } return result } func Reduce(slice []int, fn func(int, int) int, initial int) int { result := initial for _, v := range slice { result = fn(result, v) } return result } Enter fullscreen mode Exit fullscreen mode CODE_BLOCK: package main import "fmt" func loops() { // For loop (only loop keyword in Go!) for i := 0; i < 10; i++ { fmt.Println(i) } // While-style loop count := 0 for count < 10 { fmt.Println(count) count++ } // Infinite loop for { // Must have break somewhere if someCondition { break } } // Range over slice (like for...of) numbers := []int{1, 2, 3, 4, 5} for index, value := range numbers { fmt.Printf("%d: %d\n", index, value) } // Ignore index with _ for _, value := range numbers { fmt.Println(value) } // Only index for index := range numbers { fmt.Println(index) } // Range over map user := map[string]interface{}{ "name": "John", "age": 30, } for key, value := range user { fmt.Printf("%s: %v\n", key, value) } // Range over string (iterates over runes/characters) for index, char := range "Привіт" { fmt.Printf("%d: %c\n", index, char) } // Range over channel ch := make(chan int, 5) go func() { for i := 0; i < 5; i++ { ch <- i } close(ch) }() for value := range ch { fmt.Println(value) } // Break and continue for i := 0; i < 10; i++ { if i == 3 { continue } if i == 7 { break } fmt.Println(i) } // Labeled loops outer: for i := 0; i < 3; i++ { for j := 0; j < 3; j++ { if i == 1 && j == 1 { break outer } fmt.Println(i, j) } } } // No built-in map/filter/reduce, but easy to implement func Map(slice []int, fn func(int) int) []int { result := make([]int, len(slice)) for i, v := range slice { result[i] = fn(v) } return result } func Filter(slice []int, fn func(int) bool) []int { result := []int{} for _, v := range slice { if fn(v) { result = append(result, v) } } return result } func Reduce(slice []int, fn func(int, int) int, initial int) int { result := initial for _, v := range slice { result = fn(result, v) } return result } CODE_BLOCK: package main import "fmt" func loops() { // For loop (only loop keyword in Go!) for i := 0; i < 10; i++ { fmt.Println(i) } // While-style loop count := 0 for count < 10 { fmt.Println(count) count++ } // Infinite loop for { // Must have break somewhere if someCondition { break } } // Range over slice (like for...of) numbers := []int{1, 2, 3, 4, 5} for index, value := range numbers { fmt.Printf("%d: %d\n", index, value) } // Ignore index with _ for _, value := range numbers { fmt.Println(value) } // Only index for index := range numbers { fmt.Println(index) } // Range over map user := map[string]interface{}{ "name": "John", "age": 30, } for key, value := range user { fmt.Printf("%s: %v\n", key, value) } // Range over string (iterates over runes/characters) for index, char := range "Привіт" { fmt.Printf("%d: %c\n", index, char) } // Range over channel ch := make(chan int, 5) go func() { for i := 0; i < 5; i++ { ch <- i } close(ch) }() for value := range ch { fmt.Println(value) } // Break and continue for i := 0; i < 10; i++ { if i == 3 { continue } if i == 7 { break } fmt.Println(i) } // Labeled loops outer: for i := 0; i < 3; i++ { for j := 0; j < 3; j++ { if i == 1 && j == 1 { break outer } fmt.Println(i, j) } } } // No built-in map/filter/reduce, but easy to implement func Map(slice []int, fn func(int) int) []int { result := make([]int, len(slice)) for i, v := range slice { result[i] = fn(v) } return result } func Filter(slice []int, fn func(int) bool) []int { result := []int{} for _, v := range slice { if fn(v) { result = append(result, v) } } return result } func Reduce(slice []int, fn func(int, int) int, initial int) int { result := initial for _, v := range slice { result = fn(result, v) } return result } CODE_BLOCK: // No explicit interface, just conventions class FileStorage { save(data) { // Save to file } load() { // Load from file } } class DatabaseStorage { save(data) { // Save to database } load() { // Load from database } } // Works with anything that has save/load function backup(storage, data) { storage.save(data); } backup(new FileStorage(), data); backup(new DatabaseStorage(), data); // TypeScript interfaces (compile-time only) interface Storage { save(data: any): void; load(): any; } class CloudStorage implements Storage { save(data: any) { /* ... */ } load() { /* ... */ } } Enter fullscreen mode Exit fullscreen mode CODE_BLOCK: // No explicit interface, just conventions class FileStorage { save(data) { // Save to file } load() { // Load from file } } class DatabaseStorage { save(data) { // Save to database } load() { // Load from database } } // Works with anything that has save/load function backup(storage, data) { storage.save(data); } backup(new FileStorage(), data); backup(new DatabaseStorage(), data); // TypeScript interfaces (compile-time only) interface Storage { save(data: any): void; load(): any; } class CloudStorage implements Storage { save(data: any) { /* ... */ } load() { /* ... */ } } CODE_BLOCK: // No explicit interface, just conventions class FileStorage { save(data) { // Save to file } load() { // Load from file } } class DatabaseStorage { save(data) { // Save to database } load() { // Load from database } } // Works with anything that has save/load function backup(storage, data) { storage.save(data); } backup(new FileStorage(), data); backup(new DatabaseStorage(), data); // TypeScript interfaces (compile-time only) interface Storage { save(data: any): void; load(): any; } class CloudStorage implements Storage { save(data: any) { /* ... */ } load() { /* ... */ } } CODE_BLOCK: package main import "fmt" // Interface definition type Storage interface { Save(data []byte) error Load() ([]byte, error) } // Types implement interfaces implicitly type FileStorage struct { path string } func (f *FileStorage) Save(data []byte) error { // Save to file fmt.Println("Saving to file:", f.path) return nil } func (f *FileStorage) Load() ([]byte, error) { // Load from file return []byte("file data"), nil } type DatabaseStorage struct { connStr string } func (d *DatabaseStorage) Save(data []byte) error { // Save to database fmt.Println("Saving to database") return nil } func (d *DatabaseStorage) Load() ([]byte, error) { // Load from database return []byte("db data"), nil } // Function accepts interface func Backup(storage Storage, data []byte) error { return storage.Save(data) } func main() { file := &FileStorage{path: "/tmp/data"} db := &DatabaseStorage{connStr: "postgres://..."} Backup(file, []byte("data")) // Works Backup(db, []byte("data")) // Works } // Multiple interfaces type Reader interface { Read(p []byte) (n int, err error) } type Writer interface { Write(p []byte) (n int, err error) } type ReadWriter interface { Reader Writer } // Empty interface (like any in TypeScript) func PrintAnything(v interface{}) { fmt.Println(v) } // Type assertions func processValue(v interface{}) { // Type assertion if str, ok := v.(string); ok { fmt.Println("String:", str) } // Type switch switch val := v.(type) { case int: fmt.Println("Int:", val) case string: fmt.Println("String:", val) case Storage: fmt.Println("Storage implementation") default: fmt.Println("Unknown type") } } // Common standard interfaces import "io" // io.Reader is everywhere in Go func ProcessReader(r io.Reader) { data := make([]byte, 100) n, err := r.Read(data) // Process data } // Works with files, network connections, buffers, etc. Enter fullscreen mode Exit fullscreen mode CODE_BLOCK: package main import "fmt" // Interface definition type Storage interface { Save(data []byte) error Load() ([]byte, error) } // Types implement interfaces implicitly type FileStorage struct { path string } func (f *FileStorage) Save(data []byte) error { // Save to file fmt.Println("Saving to file:", f.path) return nil } func (f *FileStorage) Load() ([]byte, error) { // Load from file return []byte("file data"), nil } type DatabaseStorage struct { connStr string } func (d *DatabaseStorage) Save(data []byte) error { // Save to database fmt.Println("Saving to database") return nil } func (d *DatabaseStorage) Load() ([]byte, error) { // Load from database return []byte("db data"), nil } // Function accepts interface func Backup(storage Storage, data []byte) error { return storage.Save(data) } func main() { file := &FileStorage{path: "/tmp/data"} db := &DatabaseStorage{connStr: "postgres://..."} Backup(file, []byte("data")) // Works Backup(db, []byte("data")) // Works } // Multiple interfaces type Reader interface { Read(p []byte) (n int, err error) } type Writer interface { Write(p []byte) (n int, err error) } type ReadWriter interface { Reader Writer } // Empty interface (like any in TypeScript) func PrintAnything(v interface{}) { fmt.Println(v) } // Type assertions func processValue(v interface{}) { // Type assertion if str, ok := v.(string); ok { fmt.Println("String:", str) } // Type switch switch val := v.(type) { case int: fmt.Println("Int:", val) case string: fmt.Println("String:", val) case Storage: fmt.Println("Storage implementation") default: fmt.Println("Unknown type") } } // Common standard interfaces import "io" // io.Reader is everywhere in Go func ProcessReader(r io.Reader) { data := make([]byte, 100) n, err := r.Read(data) // Process data } // Works with files, network connections, buffers, etc. CODE_BLOCK: package main import "fmt" // Interface definition type Storage interface { Save(data []byte) error Load() ([]byte, error) } // Types implement interfaces implicitly type FileStorage struct { path string } func (f *FileStorage) Save(data []byte) error { // Save to file fmt.Println("Saving to file:", f.path) return nil } func (f *FileStorage) Load() ([]byte, error) { // Load from file return []byte("file data"), nil } type DatabaseStorage struct { connStr string } func (d *DatabaseStorage) Save(data []byte) error { // Save to database fmt.Println("Saving to database") return nil } func (d *DatabaseStorage) Load() ([]byte, error) { // Load from database return []byte("db data"), nil } // Function accepts interface func Backup(storage Storage, data []byte) error { return storage.Save(data) } func main() { file := &FileStorage{path: "/tmp/data"} db := &DatabaseStorage{connStr: "postgres://..."} Backup(file, []byte("data")) // Works Backup(db, []byte("data")) // Works } // Multiple interfaces type Reader interface { Read(p []byte) (n int, err error) } type Writer interface { Write(p []byte) (n int, err error) } type ReadWriter interface { Reader Writer } // Empty interface (like any in TypeScript) func PrintAnything(v interface{}) { fmt.Println(v) } // Type assertions func processValue(v interface{}) { // Type assertion if str, ok := v.(string); ok { fmt.Println("String:", str) } // Type switch switch val := v.(type) { case int: fmt.Println("Int:", val) case string: fmt.Println("String:", val) case Storage: fmt.Println("Storage implementation") default: fmt.Println("Unknown type") } } // Common standard interfaces import "io" // io.Reader is everywhere in Go func ProcessReader(r io.Reader) { data := make([]byte, 100) n, err := r.Read(data) // Process data } // Works with files, network connections, buffers, etc. CODE_BLOCK: // package.json { "name": "my-app", "version": "1.0.0", "type": "module", "dependencies": { "express": "^4.18.0", "lodash": "^4.17.21" }, "devDependencies": { "jest": "^29.0.0" } } // Importing import express from 'express'; import { debounce } from 'lodash'; import * as utils from './utils.js'; // Named exports export function helper() { } export const CONSTANT = 42; // Default export export default class MyClass { } // Re-exporting export { something } from './other.js'; export * from './module.js'; // Dynamic imports const module = await import('./dynamic.js'); // CommonJS (older style) const fs = require('fs'); module.exports = { helper }; Enter fullscreen mode Exit fullscreen mode CODE_BLOCK: // package.json { "name": "my-app", "version": "1.0.0", "type": "module", "dependencies": { "express": "^4.18.0", "lodash": "^4.17.21" }, "devDependencies": { "jest": "^29.0.0" } } // Importing import express from 'express'; import { debounce } from 'lodash'; import * as utils from './utils.js'; // Named exports export function helper() { } export const CONSTANT = 42; // Default export export default class MyClass { } // Re-exporting export { something } from './other.js'; export * from './module.js'; // Dynamic imports const module = await import('./dynamic.js'); // CommonJS (older style) const fs = require('fs'); module.exports = { helper }; CODE_BLOCK: // package.json { "name": "my-app", "version": "1.0.0", "type": "module", "dependencies": { "express": "^4.18.0", "lodash": "^4.17.21" }, "devDependencies": { "jest": "^29.0.0" } } // Importing import express from 'express'; import { debounce } from 'lodash'; import * as utils from './utils.js'; // Named exports export function helper() { } export const CONSTANT = 42; // Default export export default class MyClass { } // Re-exporting export { something } from './other.js'; export * from './module.js'; // Dynamic imports const module = await import('./dynamic.js'); // CommonJS (older style) const fs = require('fs'); module.exports = { helper }; CODE_BLOCK: // go.mod module github.com/mephesto/myapp go 1.21 require ( github.com/gin-gonic/gin v1.9.0 github.com/lib/pq v1.10.7 ) // Importing package main import ( "fmt" // Standard library "net/http" // Standard library "github.com/gin-gonic/gin" // External package "github.com/mephesto/myapp/internal" // Internal package ) // Exporting (capitalization!) package utils // Exported (public) func Helper() { // ... } const PublicConstant = 42 type PublicStruct struct { PublicField string privateField string // Not exported } // Not exported (private) func helper() { // ... } // Package initialization func init() { // Runs when package is imported fmt.Println("Package initialized") } // Internal packages (Go specific) // github.com/mephesto/myapp/internal can only be imported // by packages under github.com/mephesto/myapp Enter fullscreen mode Exit fullscreen mode CODE_BLOCK: // go.mod module github.com/mephesto/myapp go 1.21 require ( github.com/gin-gonic/gin v1.9.0 github.com/lib/pq v1.10.7 ) // Importing package main import ( "fmt" // Standard library "net/http" // Standard library "github.com/gin-gonic/gin" // External package "github.com/mephesto/myapp/internal" // Internal package ) // Exporting (capitalization!) package utils // Exported (public) func Helper() { // ... } const PublicConstant = 42 type PublicStruct struct { PublicField string privateField string // Not exported } // Not exported (private) func helper() { // ... } // Package initialization func init() { // Runs when package is imported fmt.Println("Package initialized") } // Internal packages (Go specific) // github.com/mephesto/myapp/internal can only be imported // by packages under github.com/mephesto/myapp CODE_BLOCK: // go.mod module github.com/mephesto/myapp go 1.21 require ( github.com/gin-gonic/gin v1.9.0 github.com/lib/pq v1.10.7 ) // Importing package main import ( "fmt" // Standard library "net/http" // Standard library "github.com/gin-gonic/gin" // External package "github.com/mephesto/myapp/internal" // Internal package ) // Exporting (capitalization!) package utils // Exported (public) func Helper() { // ... } const PublicConstant = 42 type PublicStruct struct { PublicField string privateField string // Not exported } // Not exported (private) func helper() { // ... } // Package initialization func init() { // Runs when package is imported fmt.Println("Package initialized") } // Internal packages (Go specific) // github.com/mephesto/myapp/internal can only be imported // by packages under github.com/mephesto/myapp COMMAND_BLOCK: // Object-oriented class UserService { findUser(id) { } } // Functional const findUser = (id) => fetch(`/users/${id}`); // Prototype-based function UserService() { } UserService.prototype.findUser = function(id) { }; Enter fullscreen mode Exit fullscreen mode COMMAND_BLOCK: // Object-oriented class UserService { findUser(id) { } } // Functional const findUser = (id) => fetch(`/users/${id}`); // Prototype-based function UserService() { } UserService.prototype.findUser = function(id) { }; COMMAND_BLOCK: // Object-oriented class UserService { findUser(id) { } } // Functional const findUser = (id) => fetch(`/users/${id}`); // Prototype-based function UserService() { } UserService.prototype.findUser = function(id) { }; CODE_BLOCK: // Type coercion "5" - 3; // 2 "5" + 3; // "53" [] + {}; // "[object Object]" {} + []; // 0 (in some contexts) // Undefined behavior const obj = {}; obj.deeply.nested.property; // TypeError obj?.deeply?.nested?.property; // undefined (with optional chaining) Enter fullscreen mode Exit fullscreen mode CODE_BLOCK: // Type coercion "5" - 3; // 2 "5" + 3; // "53" [] + {}; // "[object Object]" {} + []; // 0 (in some contexts) // Undefined behavior const obj = {}; obj.deeply.nested.property; // TypeError obj?.deeply?.nested?.property; // undefined (with optional chaining) CODE_BLOCK: // Type coercion "5" - 3; // 2 "5" + 3; // "53" [] + {}; // "[object Object]" {} + []; // 0 (in some contexts) // Undefined behavior const obj = {}; obj.deeply.nested.property; // TypeError obj?.deeply?.nested?.property; // undefined (with optional chaining) CODE_BLOCK: // One loop construct for i := 0; i < 10; i++ { } // No ternary operator // No generics (until Go 1.18) // No inheritance // No overloading Enter fullscreen mode Exit fullscreen mode CODE_BLOCK: // One loop construct for i := 0; i < 10; i++ { } // No ternary operator // No generics (until Go 1.18) // No inheritance // No overloading CODE_BLOCK: // One loop construct for i := 0; i < 10; i++ { } // No ternary operator // No generics (until Go 1.18) // No inheritance // No overloading CODE_BLOCK: // No implicit conversions var i int = 42 var f float64 = i // Compile error var f float64 = float64(i) // Must be explicit // Unused imports are errors import "fmt" // If not used, won't compile // All errors must be handled result, err := doSomething() // Ignoring err is bad practice Enter fullscreen mode Exit fullscreen mode CODE_BLOCK: // No implicit conversions var i int = 42 var f float64 = i // Compile error var f float64 = float64(i) // Must be explicit // Unused imports are errors import "fmt" // If not used, won't compile // All errors must be handled result, err := doSomething() // Ignoring err is bad practice CODE_BLOCK: // No implicit conversions var i int = 42 var f float64 = i // Compile error var f float64 = float64(i) // Must be explicit // Unused imports are errors import "fmt" // If not used, won't compile // All errors must be handled result, err := doSomething() // Ignoring err is bad practice COMMAND_BLOCK: const express = require('express'); const app = express(); app.get('/users/:id', async (req, res) => { try { const user = await db.findUser(req.params.id); res.json(user); } catch (error) { res.status(500).json({ error: error.message }); } }); app.listen(3000); Enter fullscreen mode Exit fullscreen mode COMMAND_BLOCK: const express = require('express'); const app = express(); app.get('/users/:id', async (req, res) => { try { const user = await db.findUser(req.params.id); res.json(user); } catch (error) { res.status(500).json({ error: error.message }); } }); app.listen(3000); COMMAND_BLOCK: const express = require('express'); const app = express(); app.get('/users/:id', async (req, res) => { try { const user = await db.findUser(req.params.id); res.json(user); } catch (error) { res.status(500).json({ error: error.message }); } }); app.listen(3000); CODE_BLOCK: package main import ( "net/http" "github.com/gin-gonic/gin" ) func main() { r := gin.Default() r.GET("/users/:id", func(c *gin.Context) { id := c.Param("id") user, err := db.FindUser(id) if err != nil { c.JSON(http.StatusInternalServerError, gin.H{ "error": err.Error(), }) return } c.JSON(http.StatusOK, user) }) r.Run(":3000") } Enter fullscreen mode Exit fullscreen mode CODE_BLOCK: package main import ( "net/http" "github.com/gin-gonic/gin" ) func main() { r := gin.Default() r.GET("/users/:id", func(c *gin.Context) { id := c.Param("id") user, err := db.FindUser(id) if err != nil { c.JSON(http.StatusInternalServerError, gin.H{ "error": err.Error(), }) return } c.JSON(http.StatusOK, user) }) r.Run(":3000") } CODE_BLOCK: package main import ( "net/http" "github.com/gin-gonic/gin" ) func main() { r := gin.Default() r.GET("/users/:id", func(c *gin.Context) { id := c.Param("id") user, err := db.FindUser(id) if err != nil { c.JSON(http.StatusInternalServerError, gin.H{ "error": err.Error(), }) return } c.JSON(http.StatusOK, user) }) r.Run(":3000") } - Variable Declaration and Type Systems - Functions and Their Flavors - Error Handling: Exceptions vs Explicit Errors - Asynchronous Programming and Concurrency - Data Structures: Objects vs Structs - Control Flow and Conditionals - Loops and Iteration - Interfaces and Polymorphism - Package Management and Modules - Philosophy and Real-World Implications - JavaScript lets you reassign variables to different types; Go doesn't - Go has zero values (default initialization), JavaScript has undefined - Go's := short declaration is convenient but only works inside functions - JavaScript has three declaration keywords (var, let, const); Go primarily uses var and := - Go requires explicit types for all parameters and return values - Go's multiple return values eliminate the need for objects/tuples in many cases - JavaScript has more syntactic sugar (arrow functions, default params, destructuring) - Go's receiver functions replace JavaScript's method syntax - Both support closures and first-class functions, but Go's are more verbose - JavaScript errors bubble up automatically; Go errors must be explicitly returned and checked - Go's if err != nil pattern is ubiquitous—critics call it verbose, advocates call it explicit - Go's defer provides cleanup guarantees similar to JavaScript's finally - JavaScript can throw any value; Go errors implement the error interface - Go 1.13+ added error wrapping with %w, similar to error causes in JavaScript - JavaScript: single-threaded with async I/O; Go: multi-threaded with goroutines - JavaScript uses promises/async-await; Go uses channels and goroutines - Go's select is more powerful than Promise.race for complex coordination - JavaScript's event loop handles concurrency implicitly; Go makes it explicit - Go has built-in primitives (channels, mutexes); JavaScript relies on the event loop - JavaScript has prototypal inheritance; Go has composition via embedding - JavaScript classes are syntactic sugar; Go structs are data containers with attached methods - Go doesn't have constructors—use factory functions by convention - JavaScript properties can be added/removed dynamically; Go structs are fixed at compile time - Go uses struct tags for metadata (like Django model field options) - Privacy in JavaScript uses # or closures; Go uses capitalization (Upper = public, lower = private) - Go doesn't have ternary operators—use if-else - Go's switch doesn't fall through by default (needs explicit fallthrough) - Go's switch can operate on types and arbitrary conditions - JavaScript has truthy/falsy; Go requires explicit boolean expressions - Go's if can include an initialization statement - Go has only for (replaces while, do-while, foreach) - Go's range is like JavaScript's for...of but more powerful - JavaScript has rich array methods; Go requires manual implementation or libraries - Both support labeled breaks for nested loops - Go's range over strings gives you runes (Unicode code points), not bytes - Both use structural typing (duck typing), but Go makes it explicit with the interface keyword - JavaScript has no runtime interfaces; TypeScript interfaces are compile-time only - Go's interface satisfaction is implicit—no implements keyword needed - Go's empty interface interface{} is like JavaScript's any - Go has powerful standard interfaces (io.Reader, io.Writer, etc.) - JavaScript uses package.json; Go uses go.mod - JavaScript has explicit export/import; Go uses capitalization for visibility - Go's import creates a namespace; JavaScript can destructure imports - Go has internal/ package convention for truly private code - JavaScript has dynamic imports; Go imports are static (compile-time) - Go's standard library is more comprehensive - Building web frontends (React, Vue, Angular) - Rapid prototyping with flexibility - Rich ecosystem of libraries needed - Team familiar with dynamic typing - Quick iteration more important than compile-time safety - Building microservices or APIs - Performance and concurrency critical - System-level programming - Deployment simplicity matters (single binary) - Long-term maintainability priority - Team values explicit error handling - JavaScript: More concise, async/await cleaner, dynamic - Go: More verbose, explicit error handling, typed parameters - JavaScript: Dependency on framework conventions - Go: Strong standard library, explicit control flow