From 98b1c8ffbed0bdc66a2c588ee91cfab0e7b766fc Mon Sep 17 00:00:00 2001 From: Paul Buetow Date: Sun, 31 May 2026 14:27:29 +0300 Subject: Update content for html --- gemfeed/atom.xml | 677 ++++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 521 insertions(+), 156 deletions(-) (limited to 'gemfeed/atom.xml') diff --git a/gemfeed/atom.xml b/gemfeed/atom.xml index 3a48e534..25bf4cf1 100644 --- a/gemfeed/atom.xml +++ b/gemfeed/atom.xml @@ -1,11 +1,531 @@ - 2026-05-16T09:16:19+03:00 + 2026-05-31T14:27:21+03:00 foo.zone feed To be in the .zone! https://foo.zone/ + + gt a calculator - a calculator built with local LLMs + + https://foo.zone/gemfeed/2026-06-01-gt-calculator.html + 2026-05-31T14:24:10+03:00 + + Paul Buetow aka snonux + paul@dev.buetow.org + + I created a calculator. Not because the world needed another one, but because I wanted to test something: how well do local LLMs hold up as pair programmers on a real project? + +
+

gt a calculator - a calculator built with local LLMs


+
+Published at 2026-05-31T14:24:10+03:00
+
+I created a calculator. Not because the world needed another one, but because I wanted to test something: how well do local LLMs hold up as pair programmers on a real project?
+
+The answer is: well enough.
+
+gt is a command-line calculator written in Go that does RPN (Reverse Polish Notation), percentage calculations, unit conversion, and a fair bit more. The name stands for "greater than" — gt is a comparison operator the calculator supports. Plus it was free in my terminal and I liked the short name.
+
+If you want the full feature guide, the README links to a detailed doc for every feature covered here and more:
+
+gt on Codeberg
+gt logo
+
+The whole thing — code, tests, documentation, even the logo — was built using only LLMs that can run locally on reasonable hardware: Qwen, Gemma, Nemotron, GPT-OSS. To be honest, I didn't run them locally either — I rented a Hyperstack GPU just to get a feel for the quality before investing in hardware. The point was to test models that don't require a cloud API and could realistically run on your own box.
+
+https://www.hyperstack.cloud/
+
+This post is about the calculator and what it does. My experience running those LLMs as pair programmers will be a separate post later.
+
+And no, this wasn't vibe-coded. I used a specific technique and a set of AI skills to drive the LLMs. The codebase came out well-structured and maintainable — not the "prompt it and pray" mess.
+
+

Table of Contents


+
+
+

The motivation


+
+Four things drove this.
+
+First, I wanted to test local LLMs as coding partners. Not the cloud-hosted ones with infinite context and billions of parameters — the ones you can actually run yourself. I figured a calculator project is big enough to be interesting but small enough to finish.
+
+Second, cloud independence is a thing I care about. I build tools that don't need a network connection to function. Writing software that talks to OpenAI or Anthropic APIs doesn't count as "running locally." Everything here runs offline.
+
+Third, I wanted to learn more about how these models actually work in practice. Not benchmarks or leaderboard scores — the day-to-day experience. How do you operate them? How do you structure prompts? When do they produce clean code versus garbage? Where do they struggle?
+
+Finally, the tool needed to be genuinely useful. A toy that calculates 2 + 2 isn't worth the disk space. I aimed for a calculator I'd actually reach for.
+
+

What it does


+
+At its core, gt is a stack-based RPN calculator with percentage support and a full metrics system. It runs as a single binary, has no dependencies, and works three ways:
+
+ +
gt '3 4 +'                     # one-liner: RPN
+gt '20% of 150'                # one-liner: percentage
+gt                             # interactive REPL
+
+
+You can also pipe into it: echo '1000Mbps @Gbps convert' | gt1.
+
+

Percentage calculations


+
+This is the simplest entry point. Three forms, all case-insensitive, all with step-by-step output:
+
+ +
gt '20% of 150'                # → 30.00
+gt '30 is what % of 150'       # → 20.00%
+gt '30 is 20% of what'         # → 150.00
+
+
+Every percentage result shows the formula and intermediate values, so you can verify the math. Useful for tips, discounts, tax, and any "what's the actual number?" moment.
+
+

RPN arithmetic


+
+The main engine uses Reverse Polish Notation. No parentheses needed — the order of tokens determines the order of operations.
+
+ +
gt '3 4 +'                     # 7
+gt '2 10 ^'                    # 1024
+gt '100 10 / 5 +'              # 15
+gt '3 4 + 5 6 + *'             # (3+4) × (5+6) = 77
+
+
+Six basic operators: +, -, *, /, ^, %. All work on the stack, popping operands and pushing the result.
+
+The fast integer power operator ** uses binary exponentiation (O(log n) instead of O(n)). So 2 100 ** does about 7 multiplications instead of 99. It only accepts integer exponents — use ^ for fractional powers.
+
+

Logarithms


+
+Three unary operators for when you need them:
+
+- lg — base 2 (information theory, algorithm complexity)
+- log — base 10 (decibels, pH, order of magnitude)
+- ln — natural log (continuous growth, statistics)
+
+ +
gt '1024 lg'                   # → 10
+gt '1000 log'                  # → 3
+gt 'e ln'                      # → 1.0000000000
+
+
+

Hyper operators (n-ary)


+
+Want to add everything on the stack at once? Square-bracket operators pop the entire stack and reduce left-associatively:
+
+ +
gt '1 2 3 4 5 [+]'            # → 15 (sum of all)
+gt '100 10 20 30 5 [-]'       # → 35 (100-10-20-30-5)
+gt '2 5 10 [*]'               # → 100 (product)
+gt '1000 2 2 2 2 [/]'         # → 62.5
+
+
+Full set: [+], [-], [*], [/], [^], [%] for arithmetic, plus [lg], [log], [ln] for logarithms. The log hyper operators work differently from the arithmetic ones — they compute the sum of the log function applied to each value, not a left-associative reduction. The square-bracket syntax is inspired by Raku's hyper operators.
+
+https://raku.org
+
+

Comparisons and booleans


+
+Six comparison operators, each with a symbolic alias:
+
+ +
gt '5 3 gt'                    # → true
+gt '3 5 <'                     # → true
+gt '5 5 =='                    # → true
+
+
+Results are true or false, which coerce into arithmetic (true = 1, false = 0). That means you can do inline conditionals:
+
+ +
gt '85 80 gt 10 *'             # → 10 (85 > 80, so 1 × 10)
+gt '50 80 gt 10 *'             # → 0  (50 < 80, so 0 × 10)
+
+
+Range validation works by summing boolean results:
+
+ +
gt '72 68 gte 100 lte +'       # → 2 (both checks pass, temp is in range)
+gt '105 68 gte 100 lte +'      # → 1 (out of range)
+
+
+

Variables and symbols


+
+Store values with three assignment styles:
+
+ +
gt 'x 10 :='                   # right assignment
+gt '20 y =:'                   # left assignment
+gt 'rate 100Mbps ='            # standard (or rate = 100Mbps)
+
+
+vars lists them, clear wipes all variables and constants, :name d deletes one. In REPL mode, variables persist to disk between sessions.
+
+Symbols (the :x syntax) are named placeholders on the stack. They're how you do explicit variable assignment and deletion without ambiguity. Bare identifiers that don't match any variable or constant also push as symbols.
+
+

Built-in constants


+
+Thirty-six of them. Use them directly as tokens:
+
+ +
gt 'pi 2 *'                    # → 6.283185307
+gt 'euler'                     # → 2.718281828
+gt 'phi 10 *'                  # → 16.18 (golden rectangle)
+gt 'sqrt2 sqrt3 *'             # → 2.449 (√6)
+
+
+Greek letter aliases work too: π, τ, φ, √2, √3, √5.
+
+

The metrics system


+
+This is where gt earns its swiss army knife title. Every number carries a unit of measurement, and arithmetic understands those units.
+
+Six built-in categories, plus Cool — the default unitless metric for plain numbers. The name comes from Raku's Cool role, which represents things that are "cool enough" to do basic operations (strings, numbers, etc.). In gt, Cool values absorb into any metric category during arithmetic, so 5 100Mbps + treats the 5 as 5Mbps.
+
+- *DataRate*: bps, Kbps, Mbps, Gbps, Tbps
+- *DataSize*: bits, bytes, KB/MB/GB/TB/PB (SI), KiB/MiB/GiB/TiB/PiB (IEC)
+- *Time*: ms, s, min, hr, day
+- *Weight*: mg, g, kg, lb, oz, ton
+- *Speed*: mps, kmh, mph, knots
+- *Distance*: m, km, mi, ft, in, nm (nautical miles)
+
+

Suffix notation


+
+Attach units directly to numbers:
+
+ +
gt '100Mbps'                   # 100 megabits per second
+gt '5GB'                       # 5 gigabytes
+gt '1hr'                       # 1 hour
+gt '70kg'                      # 70 kilograms
+
+
+

Unit conversion


+
+Use @<target> convert:
+
+ +
gt '1000Mbps @Gbps convert'    # → 1
+gt '1km @mi convert'           # → 0.6213711922
+gt '60mph @kmh convert'        # → 96.56
+gt '3day @s convert'           # → 259200
+
+
+

Metric-aware arithmetic


+
+Addition and subtraction auto-convert within categories:
+
+ +
gt '1km 500m +'                # → 1.5 (converted to km)
+gt '1Gbps 500Mbps -'           # → 500 (in Mbps)
+
+
+Multiplication and division do cross-category inference:
+
+ +
gt '100Mbps 1hr *'             # rate × time = data transferred
+gt '10GB 2hr /'                # data / time = rate
+gt '100kmh 1hr * @mi convert'  # → 62.14 miles traveled
+
+
+Comparison operators are metric-aware too:
+
+ +
gt '1km 1000m eq'              # → true
+gt '1GB 1024MB eq'             # → false (SI: 1GB = 1000MB)
+
+
+

Custom metrics


+
+Define your own units:
+
+ +
custom define reel 304.8 Distance    # surveyor's reel
+custom define fortnight 1209600 Time
+
+
+Then use them like built-ins: 5reel @m convert → 1524.
+
+

SI vs IEC modes


+
+Data size units have two modes. SI (default) uses powers of 1000. IEC uses powers of 1024. Switch with metric decimal set / metric binary set. The dedicated IEC units (KiB, MiB, GiB) are always unambiguous.
+
+

Stack manipulation


+
+Five operators for managing the RPN stack:
+
+- dup — duplicate the top value
+- swap — swap top two values
+- pop — discard the top value
+- show / showstack / print — display the stack without modifying it
+- clear — clear all variables and constants
+
+dup and swap come up a lot. Square a number: 7 dup * → 49. Reverse operand order: 2 10 swap / → 5 (instead of 0.2).
+
+

Rational number mode


+
+"Rational" refers to rational numbers — numbers that can be expressed as an exact fraction of two integers (numerator/denominator). The name "rat" is just the shorthand command.
+
+In the default float64 mode, numbers are stored as binary floating-point approximations. 0.1 cannot be represented exactly in binary, so it becomes something like 0.1000000000000000055511151231257827.... This causes the classic problem:
+
+ +
> rat off
+Rational mode disabled (using float64)
+> 0.3 0.1 - 0.2 -
+-2.775557562e-17
+
+
+The result should be 0, but floating-point rounding errors accumulated. Silent wrong answer.
+
+Rational mode stores numbers as exact fractions using Go's math/big.Rat. 0.1 is stored as 1/10, 0.2 as 2/10 (simplified to 1/5), and all arithmetic operates on those exact values. No binary approximation, no silent drift.
+
+ +
> rat on
+Rational mode enabled
+> 0.1 0.2 +
+0.3000000000
+
+
+Internally, 1/3 stays as the exact fraction 1/3, and 1/3 * 3 computes to exactly 3/3 = 1. No binary conversion, no rounding.
+
+REPL-only. Has a known limitation with non-dyadic decimals and metric operations — the docs explain the why.
+
+

The REPL


+
+Run gt with no arguments when attached to a terminal and you get the interactive session. Command history (1000 entries, persisted to ~/.gt_history), tab completion, Emacs-style line editing, Ctrl+R reverse search.
+
+Variables save to disk between sessions. Session logging with --log session.log. Session state lives in ~/.local/state/gt/vars.
+
+Built-in REPL commands: help, clear, quit/exit, rpn/calc, rat, stack. Tab-completes.
+
+Here's what a session looks like:
+
+ +
$ gt
+> rate 100Mbps =
+rate = 100
+> time 2hr =
+time = 2
+> rate time *
+200 Mbps
+> metric show
+Mbps, DataRate, base: bps, factor: 1e+06
+> download 50GB =
+download = 50
+> speed 100Mbps =
+speed = 100
+> download speed / @min convert
+83.33333333
+> custom define reel 304.8 Distance
+defined custom metric "reel" (factor: 304.8, category: Distance)
+> 5reel @m convert
+1524
+> 100Mbps 50Mbps swap -
+50 Mbps
+> show
+50 Mbps
+> 20% of 150
+20.00% of 150.00 = 30.00
+  Steps: (20.00 / 100) * 150.00 = 0.20 * 150.00 = 30.00
+> rat on
+Rational mode enabled
+> 1 3 / 3 *
+1.0000000000
+> vars
+rate = 100
+time = 2
+download = 50
+speed = 100
+
+
+Inline help is built in. Bare help lists all commands, and help <command> drills into one topic:
+
+ +
> help rat
+rat on/off/toggle - Switch between float64 and rational number modes
+  rat on       Enable rational mode (exact fractions)
+  rat off      Disable rational mode (use float64)
+  rat toggle   Toggle current mode
+> help clear
+clear - Clear the screen
+Usage: clear
+
+
+No need to leave the REPL or dig through docs when you forget a subcommand.
+
+

Some more usage examples


+
+Here are some more gt usage examples:
+
+ +
# Download volume at 1 Gbps for an hour
+gt '1Gbps 1hr * @GB convert'        # → 450
+
+# Internet speed threshold in scripts
+MIN_SPEED=$(gt '1Gbps @Mbps convert')  # → 1000
+
+# Travel planning
+gt '500mi @km convert'              # → 804.67
+gt '65mph @kmh convert'             # → 104.86
+
+# Tips, discounts, whatever
+gt '18% of 63.40'
+gt '15% of 89.99'
+
+# File sizes in MiB instead of bytes
+find . -exec wc -c {} + | awk '{print $1}' | xargs -I{} gt '{} @MiB convert'
+
+# Quick math
+gt 'pi 5 5 * *'                     # circle area, r=5 → 78.54
+gt '1000 lg'                        # → 10 (bits needed)
+
+
+

Fish shell completions


+
+gt ships with a fish completion script that covers everything: operators, constants, metric units, stack commands, the metric and custom subcommand trees, and boolean literals. It's context-aware — it won't suggest metric subcommands in the middle of an RPN expression, and it suppresses fish's default file completions so you only see calculator tokens.
+
+Install it:
+
+ +
cp completions/gt.fish ~/.config/fish/completions/
+
+
+Or system-wide:
+
+ +
sudo cp completions/gt.fish /usr/local/share/fish/vendor_completions.d/
+
+
+In practice this means tab-completion for all 36 constants, every metric unit (bps through Tbps, KB through PiB, kmh, mph, knots, etc.), all arithmetic and hyper operators, and the metric show / metric list / custom define subcommand chains. The custom define subcommand even completes the valid category names so you don't have to memorize them.
+
+

Installation


+
+ +
go install codeberg.org/snonux/gt/cmd/gt@latest
+
+
+Or from the source directory: mage install.
+
+

Wrapping up


+
+The local LLM experiment worked. The code is clean enough, the tests pass, the docs are thorough, and I use the tool. The logo was generated by a local model too.
+
+For the complete and always-up-to-date feature guide, detailed docs for every feature, and the source code, head to the repo.
+
+gt on Codeberg
+
+But will I now invest a couple of thousand dollars in hardware to run Qwen 2.5 35B or 27B? (I used the dense 27B model most of the time to build gt). Unfortunately, no. I don't think it's worth the cost yet, as cloud models are still cheaper and more convenient.
+
+However, I will keep an eye on how the technology develops and continue experimenting with rented Hyperstack VMs for now; I will also default more often to smaller LLMs that could potentially run on home hardware. Ollama Cloud subscription or an OpenRouter API key are also good options alongside Claude and OpenAI Codex.
+
+I will write another blog post at some point about my setup and what I learned from self-hosting models on Hyperstack.
+
+Other related posts:
+
+2026-06-01 gt a calculator - a calculator built with local LLMs (You are currently reading this)
+2025-08-05 Local LLM for Coding with Ollama on macOS
+
+E-Mail your comments to paul@nospam.buetow.org :-)
+
+Back to the main site
+
+
+
Unveiling I/O Riot NG — Part 3: under the hood @@ -19906,161 +20426,6 @@ Waking up e8:ff:1e:d7:1c:a0...
E-Mail your comments to paul@nospam.buetow.org :-)

-Back to the main site
- - -
- - 'Staff Engineer' book notes - - https://foo.zone/gemfeed/2024-10-24-staff-engineer-book-notes.html - 2024-10-24T20:57:44+03:00 - - Paul Buetow aka snonux - paul@dev.buetow.org - - These are my personal takeaways after reading 'Staff Engineer' by Will Larson. Note that the book contains much more knowledge wisdom and that these notes only contain points I personally found worth writing down. This is mainly for my own use, but you might find it helpful too. - -
-

"Staff Engineer" book notes


-
-Published at 2024-10-24T20:57:44+03:00
-
-These are my personal takeaways after reading "Staff Engineer" by Will Larson. Note that the book contains much more knowledge wisdom and that these notes only contain points I personally found worth writing down. This is mainly for my own use, but you might find it helpful too.
-
-
-         ,..........   ..........,
-     ,..,'          '.'          ',..,
-    ,' ,'            :            ', ',
-   ,' ,'             :             ', ',
-  ,' ,'              :              ', ',
- ,' ,'............., : ,.............', ',
-,'  '............   '.'   ............'  ',
- '''''''''''''''''';''';''''''''''''''''''
-                    '''
-
-
-

Table of Contents


-
-
-

The Four Archetypes of a Staff Engineer


-
-Larson defines four archetypes. You'll probably recognize yourself in one (or a mix):
-
-
    -
  • Tech Lead: You own the technical direction of a team. Architecture, quality, keeping everyone aligned.
  • -
  • Solver: You get thrown at the hard cross-team problems. Basically a firefighter for gnarly stuff.
  • -
  • Architect: Long-term technical vision. Standards, system design, things that need to last.
  • -
  • Right Hand: Trusted technical advisor to leadership. Strategy, org politics, the stuff nobody else wants to touch.
  • -

-

Influence and Impact over Authority


-
-You won't have direct authority over most people or teams you work with. Influence is the actual tool here. You have to persuade, align, sometimes just nudge people in the right direction. No one reports to you, but you still need to drive outcomes.
-
-

Breadth and Depth of Knowledge


-
-You need to know a bit about a lot of things (infra, security, product, etc.) but still be able to go deep in a few areas. The tricky part is keeping that breadth current without spreading yourself too thin.
-
-

Mentorship and Sponsorship


-
-Mentoring is obvious -- help people grow technically and career-wise. But sponsorship is the one that surprised me: actively advocating for people, creating opportunities for them, pushing them forward. It's not just answering questions, it's putting your reputation behind someone.
-
-

Managing Up and Across


-
-You have to manage up (set expectations with leadership, advocate for technical needs) and across (work with peer teams, build alignment). Basically a lot of communication and relationship building. Easy to underestimate this one.
-
-

Strategic Thinking


-
-Senior engineers focus on execution. Staff engineers need to think about what happens months or years from now. That means sometimes pushing back on short-term pressures in favor of longer-term architectural decisions. Not always a popular move.
-
-

Emotional Intelligence


-
-The higher you go, the more soft skills matter. Building relationships, resolving conflicts, reading the room. I think this catches a lot of engineers off guard -- you can't just be the smartest person technically anymore.
-
-
-
-A lot of the problems you deal with are poorly defined. Nobody knows exactly what the problem is, let alone the solution. You have to be comfortable operating in that fog and still making progress.
-
-

Visible and Invisible Work


-
-A huge chunk of Staff Engineer work is invisible. Aligning teams, influencing decisions, resolving conflicts -- none of that shows up as commits. Larson says you need to get comfortable with that, which I think is genuinely hard for engineers who are used to shipping things.
-
-

Scaling Yourself


-
-You can't do everything yourself anymore. Write things down, build repeatable processes, mentor others, automate what you can. The goal is to make teams more effective even when you're not in the room.
-
-

Career Progression and Title Inflation


-
-"Staff Engineer" means wildly different things at different companies. Titles don't always match actual responsibility or skill. Focus on the work and impact, not the title.
-
-Some of the above is less about technical chops and more about the strategic and interpersonal side of things. Anyway, here are some more concrete takeaways:
-
-

Not a faster Senior Engineer


-
-
    -
  • A Staff engineer is more than just a faster Senior.
  • -
  • A staff engineer is not a senior engineer but a bit better.
  • -

-It's important to know what work or which role most energizes you. A Staff engineer is not a more senior engineer. A Staff engineer also fits into another archetype.
-
-As a staff engineer, you are always expected to go beyond your comfort zone and learn new things.
-
-Your job sometimes will feel like an SEM and sometimes strangely similar to your senior roles.
-
-A Staff engineer is, like a Manager, a leader. However, being a Manager is a specific job. Leaders can apply to any job, especially to Staff engineers.
-
-

The Balance


-
-The more senior you become, the more responsibility you will have to cope with them in less time. Balance your speed of progress with your personal life, don't work late hours and don't skip these personal care events.
-
-Do fewer things but do them better. Everything done will accelerate the organization. Everything else will drag it down—quality over quantity.
-
-Don't work at ten things and progress slowly; focus on one thing and finish it.
-
-Only spend some of the time firefighting. Have time for deep thinking. Only deep think some of the time. Otherwise, you lose touch with reality.
-
-Sebactical: Take at least six months. Otherwise, it won't be as restored.
-
-

More things


-
-
    -
  • Provide simple but widely used tools. Complex and powerful tools will have power users but only a very few. All others will not use the tool.
  • -
  • In meetings, when someone is inactive, try to pull him in. Pull in max one person at a time. Don't open the discussion to multiple people.
  • -
  • Get used to writing things down and repeating yourself. You will scale yourself much more.
  • -
  • Title inflation: skills correspond to work, but the titles don't.
  • -

-E-Mail your comments to paul@nospam.buetow.org :-)
-
-Other book notes of mine are:
-
-2025-11-02 'The Courage To Be Disliked' book notes
-2025-06-07 'A Monk's Guide to Happiness' book notes
-2025-04-19 'When: The Scientific Secrets of Perfect Timing' book notes
-2024-10-24 'Staff Engineer' book notes (You are currently reading this)
-2024-07-07 'The Stoic Challenge' book notes
-2024-05-01 'Slow Productivity' book notes
-2023-11-11 'Mind Management' book notes
-2023-07-17 'Software Developers Career Guide and Soft Skills' book notes
-2023-05-06 'The Obstacle is the Way' book notes
-2023-04-01 'Never split the difference' book notes
-2023-03-16 'The Pragmatic Programmer' book notes
-
Back to the main site
-- cgit v1.2.3