HackerReposA FIELD GUIDE TO OPEN SOURCE
ProSponsor the shelf♧ 0
← Back to top all-time
michaelmacinnis
oh
Go2011–2022
michaelmacinnis / oh

oh

A new Unix shell.

10Distinct people
13Mentions
1Explicit recommenders
1.4KGitHub stars
REPOSITORY AT A GLANCE

What to know before exploring

What it is

A new Unix shell.

GitHub

Where it is used

No documented product use has been verified yet.

What people are saying

I love chatting about Kernel :D Here's my most recent post: https://lobste.rs/s/d0hogq/problem_with_macros#c_nozcrm Thanks for showing me Oh! It really has f-exprs?! I didn't…

akkartik used a recommendation phrase. One indexed comment matches. This is a phrase match, not a verdict.

No classified warning is attached to this page. Read the discussions before treating silence as approval.

Also in these discussions

No other repository is repeatedly linked in the same discussions.

This week on Hacker News

Nov 7–Nov 14 UTC · Direct repository links and separately labeled related project stories. Indexed through 11/14/2026, 3:56:07 PM UTC.

No direct repository links were found in the indexed HN discussions over the past seven days. Older discussions are available below.

Mentions over time

HN mentions by year13 dated mentions

Observed mentions: 2011-05-18 07:19:46 UTC to 2022-01-03 02:01:28 UTC.

0123452011-01-01 00:00:00 UTC to 2012-01-01 00:00:00 UTC (exclusive): 3 mentions; 2 submissions, 1 comments20112012-01-01 00:00:00 UTC to 2013-01-01 00:00:00 UTC (exclusive): 0 mentions; 0 submissions, 0 comments2013-01-01 00:00:00 UTC to 2014-01-01 00:00:00 UTC (exclusive): 0 mentions; 0 submissions, 0 comments2014-01-01 00:00:00 UTC to 2015-01-01 00:00:00 UTC (exclusive): 1 mentions; 0 submissions, 1 comments2015-01-01 00:00:00 UTC to 2016-01-01 00:00:00 UTC (exclusive): 1 mentions; 1 submissions, 0 comments2016-01-01 00:00:00 UTC to 2017-01-01 00:00:00 UTC (exclusive): 1 mentions; 1 submissions, 0 comments20162017-01-01 00:00:00 UTC to 2018-01-01 00:00:00 UTC (exclusive): 1 mentions; 0 submissions, 1 comments2018-01-01 00:00:00 UTC to 2019-01-01 00:00:00 UTC (exclusive): 0 mentions; 0 submissions, 0 comments2019-01-01 00:00:00 UTC to 2020-01-01 00:00:00 UTC (exclusive): 0 mentions; 0 submissions, 0 comments2020-01-01 00:00:00 UTC to 2021-01-01 00:00:00 UTC (exclusive): 0 mentions; 0 submissions, 0 comments2021-01-01 00:00:00 UTC to 2022-01-01 00:00:00 UTC (exclusive): 5 mentions; 1 submissions, 4 comments2022-01-01 00:00:00 UTC to 2023-01-01 00:00:00 UTC (exclusive): 1 mentions; 0 submissions, 1 comments2022

Counts come from the repository’s dated source evidence. Index cutoff: 2026-11-02 08:16:59 UTC.

View mention counts and date ranges
UTC ranges include their start and exclude their end. Select a period to filter the source evidence.
PeriodStart (UTC)End (exclusive, UTC)MentionsSubmissionsComments
20112011-01-01 00:00:00 UTC2012-01-01 00:00:00 UTC321
20122012-01-01 00:00:00 UTC2013-01-01 00:00:00 UTC000
20132013-01-01 00:00:00 UTC2014-01-01 00:00:00 UTC000
20142014-01-01 00:00:00 UTC2015-01-01 00:00:00 UTC101
20152015-01-01 00:00:00 UTC2016-01-01 00:00:00 UTC110
20162016-01-01 00:00:00 UTC2017-01-01 00:00:00 UTC110
20172017-01-01 00:00:00 UTC2018-01-01 00:00:00 UTC101
20182018-01-01 00:00:00 UTC2019-01-01 00:00:00 UTC000
20192019-01-01 00:00:00 UTC2020-01-01 00:00:00 UTC000
20202020-01-01 00:00:00 UTC2021-01-01 00:00:00 UTC000
20212021-01-01 00:00:00 UTC2022-01-01 00:00:00 UTC514
20222022-01-01 00:00:00 UTC2023-01-01 00:00:00 UTC101

What Hacker News says

13 sources
> Still, the basic eval command looks remarkably similar in lisp vs TCL. The primary difference is whether arguments are evaluated before (Scheme/Lisp) or after (Tcl) being sent to the function/command. The deferred evaluation is what allows you to do things that you need macros for in other languages. (ie. you need deferred evaluation or macros to implement short-circuit operators, for example) However, early Lisps had FEXPRs which also deferred evaluation. The late John Shutt built and entire Lisp called "Kernel" around the idea: http://web.cs.wpi.edu/~jshutt/kernel.html I strongly recommend a read through his PhD thesis: https://www.wpi.edu/Pubs/ETD/Available/etd-090110-124904/ Unfortunately, his implementation isn't anywhere near as good as his conception. Other people have implemented it better. http://axisofeval.blogspot.com/sear
Read the rest
ch/label/kernel http://axisofeval.blogspot.com/2011/09/kernel-underground.ht... The Oh Unix shell grabs some of the core Kernel concepts and runs with them in a useful package: https://github.com/michaelmacinnis/oh
In Understanding the Power of Lisp (2020)
> Is there a reason we aren’t using a shell with a proper programming language for scripting? Mostly because the people who want to introduce a "programming language" into the shell don't prioritize being a shell. Check out the "Oh" shell for contrast. This is what a programming language looks like when you force it to conform to being a shell first priority. https://github.com/michaelmacinnis/oh https://www.youtube.com/watch?v=v1m-WEZz46U This is "Scheme-like" (actually the late John Shutt's Kernel-like) but has FEXPRs so things can be redefined and evaluation can be controlled.
In Bash functions are better than I thought
> Why is this quoting the top-level lambda expression arguments? I suspect mostly because the implementation stumbled into the dynamic binding/lexical binding/FEXPR traps that hit all the early Lisps. > Here it becomes clear that, in its most bare essential form, beneath the macros and abstractions, LISP actually has an unpleasant nature where name bindings (or assignments) look like a venus fly trap. Ayup. A lot of these problems were addressed by the late John Shutt in his thesis about vau calculus in the Kernel programming language: FEXPRS: https://en.wikipedia.org/wiki/Fexpr John Shutt's vau calculus thesis: http://www.wpi.edu/Pubs/ETD/Available/etd-090110-124904/unre... John Shutt's Kernel Language--"Revised-1 Report on the Kernel Programming Language" https://core.ac.uk/download/pdf/47187352.pdf The "magic" is that the "$vau" operat
Read the rest
ive closes over the environment when it is defined so that it can execute later in that environment--this is the "static/lexical environment". However, when you actually execute the "$vau" operative, you also pass in the "execution/dynamic" environment so that the code that the "$vau" operative runs can choose to do what it wants with the arguments--do nothing, evaluate them in the lexical environment, or evaluate them in the dynamic environment. It's a powerful concept, but difficult to compile so got kind of relegated from the Lisp/Scheme languages. For something which seems to implement it properly, see the "Oh" UNIX shell: https://github.com/michaelmacinnis/oh https://www.youtube.com/watch?v=v1m-WEZz46U I would mumble that the fact that "list" is defined as "cons pairs with a final nil()" is also a pain in the ass. I understand why it was originally done this way, but it makes the idea of a "sequence" abstraction so very much more painful. It's one of the reasons why Clojure dropped it.
In Show HN: SectorLISP now fits in one sector

MAKE YOURSELF AT HOME

A few shortcuts

/
Search the collection
?
Open this guide
Esc
Close dialogs and navigation

Your saved repositories and interests stay in this browser.