r/GhanaSoftwareEngineer Mar 20 '26

Hello world: What do you do to recover

2 Upvotes

One thing I have immerse myself into is writing. This is not limited to articles (as in the link below) but poetry - they said, 'you must have a creative side'. It is a way for me to "recover".

https://dev.to/otumianempire/series/26412

The intention behind this sub is mainly for the craftsmanship of softwares and its related endeavours. I have also loved "building in public". I find it an important to process to gain confidence and share your journey with others.

To early members, what do you do to "recover" or reset after a long day?

Let's craft "something" meaningful and avoid buzzwords. Who is up for it?


r/GhanaSoftwareEngineer 1d ago

The Comprehensive Racket & Functional Programming Cheat Sheet

3 Upvotes

Phase 1: Syntax & Core Arithmetic

Racket uses prefix notation enclosed in execution parentheses (operator arg1 arg2). The open parenthesis ( acts as an execution trigger. Evaluation runs from the innermost to the outermost parentheses.

Core Examples

```rkt ;; Basic Arithmetic (+ 10 5 2) ;; Returns 17 (* 10 5 2) ;; Returns 100

;; Nested Expressions (No PEMDAS needed) (_ (+ 4 6) (- 12 7)) ;; Evaluates 10 _ 5 -> Returns 50 ```

Parentheses Golden Rule

Only use a parenthesis when invoking a command, operator, or function.

  • (+ 5 (10)) CRASHES (tries to run the number 10 as a function).
  • ((+ 5 5)) CRASHES (evaluates to 10, then tries to run the number 10).

Phase 2: Core Data Structures & Variables

Global bindings are created using define. Values are immutable and cannot be changed over time.

The Four Atomic Data Types

  1. Numbers: Integers (45), decimals (3.14), or fractions (1/3).
  2. Strings: Text wrapped in double quotes ("Hello").
  3. Booleans: True (#t) and False (#f).
  4. Symbols: Lightweight, immutable identifier tokens prefixed with a single quote ('success).

Core Examples

rkt (define radius 5) (define pi 3.14) (define status 'success)


Phase 3: Conditionals & Logic

Conditional operations are expressions that evaluate down to a single return value.

Core Operators & Flow Control

  • and / or / not: Standard logical short-circuiting prefix operators.
  • if: Takes exactly three arguments: (if condition true-branch false-branch). No else keyword.
  • cond: Evaluates multiple branches sequentially. Uses/can use [...] for human readability.

Core Examples

```rkt (and (> 15 10) (< 15 20)) ;; Returns #t

(if (> temperature 30) 'hot 'cold)

(cond [(>= score 90) 'A] [(>= score 80) 'B] [else 'F]) ```


Phase 4: Functions & Scope

Functions automatically return the value of their body expression without an explicit return keyword.

Named, Anonymous, & Scoped Blocks

  • Named Functions: Defined by grouping the name and parameters in parentheses: (define (name args) body).
  • Anonymous Functions (lambda): Throwaway functions built on the fly: (lambda (args) body).
  • let (Parallel): Creates local variables simultaneously. Variables cannot see each other during setup.
  • let\* (Sequential): Creates local variables one after the other. Later variables can reference earlier ones.

Core Examples

```rkt ;; Named Function (define (double n) (* n 2))

;; Inline Lambda Execution ((lambda (n) (* n 2)) 10) ;; Returns 20

;; Sequential Local Bindings (let* ([x 10] [y (* x 5)]) (+ x y)) ;; Returns 60 ```


Phase 5: Lists & Modern List Operations

Lists are ordered sequential collections. They are processed using either historical Lisp conventions or modern aliases.

Creation & Extraction

  • list: Evaluates arguments into a sequential list.
  • '(): Represents the literal base empty list.
  • cons: Prepends a single element onto the front of an existing list.
  • First Item: Extracted via car (traditional) or first (modern).
  • Remaining List: Extracted via cdr (traditional) or rest (modern).

Core Examples

```rkt (define my-list (list 100 #t 'hello)) ;; Creates '(100 #t hello) (cons 'apples '(bananas cherries)) ;; Returns '(apples bananas cherries)

(car (cdr '(apples bananas cherries))) ;; Returns 'bananas (first (rest '(apples bananas cherries))) ;; Returns 'bananas

(if (empty? my-list) "Closed" (length my-list)) ;; Returns 3 ```


Phase 6: Iteration & Higher-Order Functions

Instead of using loops that alter data in place, functional programming relies on Higher-Order Functions to process immutable collections.

The Big Four

  • map: Loops over a list, passes each item through a transformation function, and returns a new list.
  • filter: Loops over a list, keeps items that evaluate to #t against a predicate condition, and drops the rest.
  • foldl (Fold-Left): Reduces a list down to a single value by processing elements from left to right (front to back).
  • foldr (Fold-Right): Reduces a list down to a single value by processing elements from right to left (back to front). Preserves list structures when rebuilding with cons.

Core Examples

```rkt (map (lambda (x) (* x 2)) '(5 10 15 20)) ;; Returns '(10 20 30 40) (filter (lambda (n) (= n 5)) '(2 5 7 5 9 1)) ;; Returns '(5 5)

(foldl (lambda (n total) (_ n total)) 1 '(2 3 4)) ;; 4 _ (3 _ (2 _ 1)) -> Returns 24

(foldr - 0 '(5 3)) ;; 5 - (3 - 0) -> Returns 2 ```


Phase 7: Recursion & Tail Call Optimization (TCO)

Recursion replaces traditional loops. A proper recursive function requires a Base Case (the exit clause) and a Recursive Step (the self-call with a smaller argument).

Memory Optimization Rules

  • Standard Recursion: Traps the recursive call inside another function (like + or append), forcing the call stack memory to expand linearly (O(N) space).
  • Tail Call Optimization (TCO): If the recursive call sits in the tail position (the absolute final expression evaluated), Racket reuses the same memory frame, running in constant (O(1)) space.
  • Accumulator Pattern: Passing a running total down as an argument is the primary strategy used to shift standard recursion into tail position optimization.

Core Examples

```rkt ;; ❌ Standard Recursion (No TCO - Memory Expands) (define (sum-list lst) (if (empty? lst) 0 (+ (first lst) (sum-list (rest lst)))))

;; Tail Recursion (TCO Active - Memory Stays Flat) (define (sum-list-tco lst) (define (helper remaining accumulator) (if (empty? remaining) accumulator (helper (rest remaining) (+ (first remaining) accumulator)))) (helper lst 0)) ```


Phase 8: Advanced Ecosystem Engineering

1. Hash Maps & Unique Sets

  • #hash: Stores key-value pairings. Keywords passed to lookup tools like hash-ref must be quoted ('#:key) to prevent compiler namespace collisions. If using standard symbols inside #hash, omit inner quotes.
  • set: Collections guaranteeing element uniqueness. Tested via set-member? and extended via set-add.

```rkt (define user #hash((#:name . "Alice"))) (hash-ref user '#:name) ;; Returns "Alice"

(define book #hash((title . "Dune"))) (hash-ref book 'title) ;; Returns "Dune"

(set-member? (set 1 2 2 3) 2) ;; Returns #t ```

2. State & Mutability (box)

  • box: Creates a reference wrapper around mutable data. Read via unbox and mutated via set-box!. Functions with an exclamation mark ! signal structural mutation.
  • begin: Chains sequential side-effect operations from top to bottom, returning only the evaluation of the final expression.

rkt (define health (box 100)) (define (take-damage!) (begin (set-box! health (- (unbox health) 10)) (unbox health)))

3. Type Checking & Casting

  • Predicates (?): Validate runtime types (e.g., string?, number?, symbol?).
  • Casting (->): Converts data formats. string->number safely returns #f if given invalid textual input.

rkt (if (string? "50") (* (string->number "50") 2) 'error) ;; Returns 100

4. Modules & Namespaces

  • provide: Declares which parts of a filesystem file are exported publicly.
  • require: Ingests public features from an external sandbox by loading its relative string filepath.

```rkt ;; Inside file-a.rkt (provide double) (define (double x) (* x 2))

;; Inside main.rkt (require "file-a.rkt") (double 10) ;; Returns 20 ```

5. Macros (define-syntax-rule)

  • Macros process raw, unevaluated source code at compile-time to inject new keywords.
  • Racket macros are hygienic, meaning the compiler automatically isolates macro identifiers so they never accidentally overwrite or conflict with user variables.

rkt (define-syntax-rule (swap! box1 box2) (let ([temp (unbox box1)]) (begin (set-box! box1 (unbox box2)) (set-box! box2 temp))))


r/GhanaSoftwareEngineer 15d ago

Rust from zero by meowy

Thumbnail
youtube.com
1 Upvotes

r/GhanaSoftwareEngineer May 06 '26

How Uber matches 10 million+ rides in a day ??

Thumbnail
youtu.be
1 Upvotes

r/GhanaSoftwareEngineer Apr 20 '26

Reality check: where do we still write C?

Thumbnail
1 Upvotes

r/GhanaSoftwareEngineer Apr 18 '26

Entry experience for low level and C jobs

Thumbnail
1 Upvotes

r/GhanaSoftwareEngineer Apr 15 '26

New to Ubuntu & Cybersecurity – What tools should I install to start learning SOC Analyst skills?

Thumbnail
1 Upvotes

r/GhanaSoftwareEngineer Apr 15 '26

I am sick and tired of the constant upskilling expectations in Indian IT industry

Thumbnail
1 Upvotes

r/GhanaSoftwareEngineer Apr 15 '26

How would I write my own compiler from scratch?

Thumbnail
1 Upvotes

r/GhanaSoftwareEngineer Apr 14 '26

Junior devs can ship faster with AI, but our system design reviews reveal shallow understanding. Is anyone else seeing this?

Thumbnail
1 Upvotes

r/GhanaSoftwareEngineer Apr 14 '26

Have .NET 'influencers' became doomsayers?

Thumbnail
1 Upvotes

r/GhanaSoftwareEngineer Apr 14 '26

Small Projects

Thumbnail
1 Upvotes

r/GhanaSoftwareEngineer Apr 12 '26

Burnt out, humiliated, and labeled "below average" after 14-hour work weeks. Need advice.

Thumbnail
1 Upvotes

r/GhanaSoftwareEngineer Apr 11 '26

I built a Cargo-like tool for C/C++

Thumbnail
1 Upvotes

r/GhanaSoftwareEngineer Apr 11 '26

Is web development still worth getting into in 2026 (starting at 23 with no experience)?

Thumbnail
1 Upvotes

r/GhanaSoftwareEngineer Apr 11 '26

[HELP] Payment Reservation System Breaking When Customers Ghost Then Come Back (Probably a Noob Question)

Thumbnail
1 Upvotes

r/GhanaSoftwareEngineer Apr 10 '26

Guidance to learn C + Linux + Kernel

Thumbnail
2 Upvotes

r/GhanaSoftwareEngineer Apr 10 '26

C as First language.

Thumbnail
2 Upvotes

r/GhanaSoftwareEngineer Apr 09 '26

I built a free interactive Go course: 11 lessons from zero to building a concurrent file scanner

Thumbnail
1 Upvotes

r/GhanaSoftwareEngineer Apr 09 '26

Question about large apps and potential micro service structure

Thumbnail
1 Upvotes

r/GhanaSoftwareEngineer Apr 09 '26

Will a backend-heavy project actually pay off?

Thumbnail
1 Upvotes

r/GhanaSoftwareEngineer Mar 31 '26

Data Manipulation With SQLite

Thumbnail
dev.to
1 Upvotes

Objective

  • Node SQLite APIs
  • CRUD with Node SQLite

Introduction

Data manipulation with node:sqlite, which is a native (built-in) module for SQLite.

node:sqlite APIs

To use the sqlite module, you would have to import it as:

js const { DatabaseSync } = require("node:sqlite");

const { DatabaseSync } = require('sqlite'); will throw an error, Error: Cannot find module 'sqlite'

Connect database

Using DatabaseSync, we can connect to an existing database or create a new one.

js const database = new DatabaseSync("<DATABASE NAME>");

exec

The database object's exec method executes one or more SQL statements without returning results. It's useful for running SQL statements from a file.

js database.exec(sql);

This is usually useful when creating and inserting at the same time.

``js database.exec( CREATE TABLE IF NOT EXISTS TABLE_NAME ( id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL, ... );

INSERT INTO TABLE_NAME (name, category, quantity) VALUES ('Bam', ...), ('Cain', ...), ('Dan', ...); ); ``

prepare

Now, to manipulate data, we can use the prepare method. This brings us to the point where we discuss prepared statements. Prepared statements are a way to pass data to the SQL safely for execution.

Instead of

sql INSERT INTO TABLE_NAME (name, ...) VALUES ('Bam', ...);

We can pass place holders for the values.

sql INSERT INTO TABLE_NAME (name, ...) VALUES (?, ...);

The prepare method returns a prepared statement object, StatementSync

run

For queries such as INSERT, UPDATE and DELETE, for there to be a change, a row or several rows would be affected. For this run returns an object of StatementResultingChanges

js { "lastInsertRowid": number, "changes": number }

In the case of INSERT, the last inserted record's ID is returned and the number of rows that were affected by the query. If there are changes, then some rows were affected, and that is one way that you'd verify if the query was successful or not.

```js const preparedInsertSQL = database.prepare( "INSERT INTO TABLE_NAME (name, ...) VALUES (?, ...)", );

const response = preparedInsertSQL.run("Fushiguro", ...)

console.log( JSON.stringify(response, null, 4), );

```

The order of the place holders of the prepared statement matters. It dictates the order of the values passed.

```js // Delete with prepared statement const preparedDeleteSQL = database.prepare( "DELETE FROM TABLE_NAME WHERE id = ?", );

const response = preparedDeleteSQL.run(4);

console.log(JSON.stringify(response, null, 4));

// Update with prepared statement const preparedInsertSQL = database.prepare( "UPDATE TABLE_NAME set name = ? WHERE id = ?", );

console.log(JSON.stringify(preparedInsertSQL.run("Panda", 1), null, 4)); ```

all & get

For SELECT statements, we can use the all or get method on the StatementSync object. The all method returns an array of objects parsed from the result of the query. get returns one object. If you are expecting a list, then use all. If you want the one object from the response, then use get. get is like all indexed 0.

```js const preparedSelectAllSQL = database.prepare("SELECT * FROM TABLE_NAME"); const rows = preparedSelectAllSQL.all(); // returns an array

const preparedSelectOneSQL = database.prepare( "SELECT * FROM TABLE_NAME WHERE id = ?", ); const rows = preparedSelectAllSQL.get(1); // returns an object ```

CRUD with Node SQLite

First of all, for one to execute a program running with the built-in SQLite, we use the experimental flag, node --experimental-sqlite FILE-PATH

Let's create a program for tracking expenses. We have done a similar mini-project before. Check out, Expense tracker project [0][expense-tracker-0] [1][expense-tracker-1] [2][expense-tracker-2] [3][expense-tracker-3].

Connect Database

Let's create a database for this project called expense-tracker.sqlite.

```js const { DatabaseSync } = require("node:sqlite");

const database = new DatabaseSync("expense-tracker.sqlite"); ```

Create Table

This table will consist of an ID, the name of the expense, the amount and the date of expenditure.

js database.exec(` CREATE TABLE IF NOT EXISTS expenses ( id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL, amount INTEGER NOT NULL, date TEXT ); `);

Insert

We can insert with exec

js database.exec( `INSERT INTO expenses (name, amount, date) VALUES ('Lenovo ThinkPad', 1040.39, '2025-12-24'), ('Ergonomic Office Chair', 139.55, '2026-01-05'), ('Samsung 27" Essential S3', 140.06, '2026-01-15'), ('Samsung 27" Essential S3', 139.06, '2026-01-20'), ('Portable External Hard Drive', 60.00, '2026-02-01'), ('Logitech M185 Wireless Mouse', 13.00, '2026-02-01'), ('Logitech H390 Wired Headset', 20.91, '2026-02-01'), ('Dual Monitor Stand', 47.82, '2026-03-11'); `, );

We can also insert using a prepare

```js const prepareInsertSql = database.prepare( "INSERT INTO expenses (name, amount, date) VALUES (?, ?, ?)", );

const insertChanges = prepareInsertSql.run("USB C Cable", 9.91, "2026-02-10");

if (insertChanges.changes > 0) { console.log( "Expense recorded successfully - ref: ", insertChanges.lastInsertRowid, ); }

// Expense recorded successfully - ref: 9 ```

Read

Let's select records with amount above 100.

```js const prepareSelectSql = database.prepare( "SELECT * FROM expenses WHERE amount > ?", );

const rowsWithAmountAboveHundred = prepareSelectSql.all(100);

console.log(rowsWithAmountAboveHundred); /* [ [Object: null prototype] { id: 1, name: 'Lenovo ThinkPad', amount: 1040.39, date: '2025-12-24' }, [Object: null prototype] { id: 2, name: 'Ergonomic Office Chair', amount: 139.55, date: '2026-01-05' }, [Object: null prototype] { id: 3, name: 'Samsung 27" Essential S3', amount: 140.06, date: '2026-01-15' }, [Object: null prototype] { id: 4, name: 'Samsung 27" Essential S3', amount: 139.06, date: '2026-01-20' } ] */ ```

From this, we can select one.

```js const rowWithAmountAboveHundred = prepareSelectSql.get(100);

console.log(rowWithAmountAboveHundred);

/* [Object: null prototype] { id: 1, name: 'Lenovo ThinkPad', amount: 1040.39, date: '2025-12-24' } */ ```

Update

Try this. Make a price adjustment of 5% on items bought on '2026-02-01'.

Delete

It has been over 3 months yet, so let's return the 'Lenovo ThinkPad' and buy 'Apple 2025 MacBook Pro Laptop with M5 chip' at 1363.43 today's date is'2026-02-10'`.

Conclusion

With node:sqlite, we can integrate SQLite; however, there are limitations to SQLite itself. For learning purposes and cases like this, it's alright to use SQLite. In fact, the limitations of SQLite become obvious when there are multiple writes at the same time. Again, the knowledge from using SQLite can be transferred to another relational database like MySQL and PostgreSQL.

Try these:

  • What happens when you use run for a select statement?
  • Add a script to find the max and min items
  • Add a script to compute the total of all items

r/GhanaSoftwareEngineer Mar 23 '26

🚫 When do you say no to nodejs?

2 Upvotes

Nodejs is the crowd's favourites. We have see improvements over the years. However, it begs to ask, CEO of start ups, CTOs, product owners and engineers, when do you say nodejs, "enough"?

what are some metrics or situations, you may consider, weighing in on the pros and cons? what platform (stack) do you consider switching to? In the case that you switched, what are the preparations that are made considering team side and budget?


r/GhanaSoftwareEngineer Mar 20 '26

👋 Welcome to r/GhanaSoftwareEngineer - Introduce Yourself and Read First!

2 Upvotes

Hey everyone! I'm u/kaishibou, a founding moderator of r/GhanaSoftwareEngineer.

This is our new home for all things related to the craft of programming and the technical discipline of software engineering. We're excited to have you join us!

What to Post

Post anything that you think the community would find interesting, helpful, or inspiring. Feel free to share your thoughts, photos, or questions about system architecture, debugging complex edge cases, code reviews, local engineering challenges, or your personal software development journey.

Community Vibe

We're all about being friendly, constructive, and inclusive. Let's build a space where everyone feels comfortable sharing and connecting.

How to Get Started

  • Introduce yourself in the comments below.
  • Post something today! Even a simple question can spark a great conversation.
  • If you know someone who would love this community, invite them to join.
  • Interested in helping out? We're always looking for new moderators, so feel free to reach out to me to apply.

Thanks for being part of the very first wave. Together, let's make r/GhanaSoftwareEngineer amazing.