Alex Karle's phloggopher://alexkarle.com/1/phlogAlex Karle2024-08-03T12:06:07-04:00What Words Can't Describegopher://alexkarle.com/0/phlog/039.txt2024-08-03T12:06:07-04:002024-08-03T12:06:07-04:00In Praise of the Local Librarygopher://alexkarle.com/0/phlog/038.txt2024-01-24T09:33:37-05:002024-01-24T09:33:37-05:00
$200 in tools saved! How cool is that?
And of course there's books, lots of
them :) Our library is part of a bigger
network where they'll share books
with neighboring libraries, which has
meant I have never found a title I
couldn't get at the library.
So here's a little thanks to all our
librarians; you make the community a
better place :)
]]>
The Joys of a Wood Stovegopher://alexkarle.com/0/phlog/037.txt2023-12-31T17:36:16-05:002023-12-31T17:36:16-05:00The Many Benefits of Anti-Consumerismgopher://alexkarle.com/0/phlog/036.txt2023-12-02T23:07:43-05:002023-12-02T23:07:43-05:00
purchase->discard hamster wheel and instead
reusing, repairing, and recycling.
With our FI hat on:
Any dollar spent is a dollar
not gaining interest ("working
for you").
But maybe that argument doesn't appeal to
the already wealthy. A more urgent need
is seen with the sustainability hat on:
Any material thing must
have been created with resources
taken from this earth (potentially
through harmful methods).
Repairing, repurposing, and most importantly
sharing our possessions can keep waste out
of landfills and strengthen our communities.
I'm sharing all this not to preach, judge,
or otherwise posture as a better earth citizen
than anyone else. I'm just as guilty of buying
my own lawnmower for ~10 mows a year instead
of arranging a joint custody with neighbors
(albeit before having given this much thought).
I bring this all up because I'm excited. My
seemingly complex and varied lifestyle goals
all have a simple, effective, solution to get
me 90% of the way there: just buy less.
[1]: https://alexkarle.com/blog/life-updates-2023.html
]]>
When Seemingly Infinite Becomes Suddenly Finitegopher://alexkarle.com/0/phlog/035.txt2023-04-24T22:59:14-04:002023-04-24T22:59:14-04:00On Digital Minimalismgopher://alexkarle.com/0/phlog/034.txt2023-04-12T00:09:51-04:002023-04-12T00:08:20-04:00New Gopherhole Release: My Record Collectiongopher://alexkarle.com/0/phlog/033.txt2023-01-14T00:16:04-05:002023-01-14T00:16:04-05:00This Gopherhole as a Time Capsulegopher://alexkarle.com/0/phlog/032.txt2023-01-05T23:22:36-05:002023-01-05T23:22:36-05:00Announcing a New Gopherhole Section: Games!gopher://alexkarle.com/0/phlog/031.txt2023-01-05T22:48:42-05:002023-01-05T22:48:42-05:00Happy New Year!gopher://alexkarle.com/0/phlog/030.txt2023-01-01T15:02:56-05:002023-01-01T15:02:56-05:00Book Review: Sketchy Scheme by Nils M Holmgopher://alexkarle.com/0/phlog/029.txt2022-12-01T23:02:38-05:002022-12-01T23:02:38-05:00Hackers and Painters and Paint Brushesgopher://alexkarle.com/0/phlog/028.txt2022-11-30T23:54:33-05:002022-11-30T23:54:33-05:00A Simple Case for Lisp Parenthesisgopher://alexkarle.com/0/phlog/027.txt2022-11-29T23:23:59-05:002022-11-29T23:23:59-05:00On Window Managers and the UNIX Philosophygopher://alexkarle.com/0/phlog/026.txt2022-11-27T23:02:14-05:002022-11-27T23:02:14-05:00
Why don't more applications leverage the window manager?
## Backstory
In my internet research on CHICKEN Scheme, I stumbled
across Felix's website (the original author) [1]. He has
some projects listed, including a Acme-like editor he
develops. As an Acme enthusiast myself, I had to check
it out!
The editor is called ma [2] and I'm using it to write
this post. It has the classic look and the mouse
chording/plumbing (and to my pleasant surprise some emacs
and CUA hybrid so Ctrl-S/C/V saves/copies/pastes and
Ctrl-N/P go up/down, etc).
The most interesting thing about ma(1), however, is that
it only supports a single buffer per window. To handle
multiple files, run multiple ma(1) instances. They
communicate with a registry, if needed (presumably for
things like "does anyone have this file open already?").
From the README:
> ma ... needs a tiling window manager to be used in a
> satisfactory way.
This is such an interesting concept, I had to write about it.
[1]: http://call-with-current-continuation.org
[2]: http://call-with-current-continuation.org/ma/ma.html
## On Leveraging the Window Manager
The more I looked around, the more I realized... most
applications have their own window manager. Splits in
Vim, tabs in Firefox, heck Emacs even _calls_ their splits
"windows" (vs "frames" for X11 windows). Terminals
frequently have tabs/splits, and for those that don't
tmux(1) can be used!
To these apps, the window manager is a foe, not a friend.
It will resize them, force them to adapt. They really
don't seem to be built to work in tandem.
On the other hand, these apps aren't really doing anything
tiling window managers can't. Tabs, splits, stacks... I'd
argue tiling window managers provide more flexibility
than any home baked solution.
Further, each app has a slightly different set of key
bindings to use their window management. They _have_ to
be different because frequently users nest apps within
apps (think vim in tmux in gnome-terminal ctrl-t for gnome
tabs, ctrl-a[num] for tmux, :tab for vim).
Wouldn't it just be cleaner to pull a ma(1) and leverage
the window manager? This would mean:
1. Uniform key bindings between many app types
2. The ability to stack/tab/split between different apps
(2) can't be understated--it's so cool having ma(1) split
in the main panel, firefox and st(1) on the right. If I was
in vim, I could have my shell and editor, but surely not
the browser in the same "grid"!
Off the top of my head there's only two reasons _not_
to do this:
1. (lesser) Needing to run a "registry" to synchonize
multiple apps is kindof awkward
2. (more importantly) The majority of computer
users just don't (and can't) use a tiling (or otherwise
configurable) window manager.
With Windows and macOS having the majority of users, of
_course_ firefox needs to have its own tabs (and so on).
There's simply no sane way to manage your 30+ tab session
as floating windows.
## Wrapping Up
It seems, unless there's a massive shift in how mainstream
desktop window managers work, that writing ma-like programs
that rely on a window manager for basic things like
multiple files is a pipe-dream (unless you drastically
shrink your audience size). That said, it's an interesting
way of dividing the responsibilities; if you can do one
thing only, and do it well, surely you should focus on
being an editor and not a window manager :)
]]>
On Text Editing Efficiency pt. 2gopher://alexkarle.com/0/phlog/025.txt2022-11-21T13:13:44-05:002022-11-21T13:13:44-05:00On Skill vs Automation in Code Editinggopher://alexkarle.com/0/phlog/024.txt2022-11-20T23:19:20-05:002022-11-20T23:19:20-05:00
n.n.n.n.` (select the
next one, then change it to bar, then next -> change
-> next..)
* If many: `:%s/\/bar/gc` (y/n at each prompt)
There's a clear slowdown with Vim (beyond the amount of
typing): the mental overhead of having to decide if
each is a false positive or not. It can be eliminated a
bit by the word-boundary \<\> and the search for just
\ via *, but it's definitely not perfect. With
LSP, the server knows the instances and can tell the
client every location without the operator changing
anything.
The major downside of LSP AFAICT is that it's limited to
languages that have a server (and code in general). In
a CSV file, for instance, `gr` just won't be an option.
And of course, for massive codebases it can be very
expensive to run / slow.
If anything, this just reinforces the difference
between a _text_ editor and a _code_ editor, and I
expect we'll continue to see the gap widen over time
(with the line between IDE and code editor maybe
blurring a bit).
vi is a text editor through and through. Vim, Emacs,
and VSCode are all code editors (the former two if
configured properly).
In a world with CoPilot, I wonder how far Code editors
will go. And I wonder if that'll make it harder for new
languages to form (with such a barrier for tooling,
etc). If developers become operators of AI, there's a
real chicken and egg problem with new languages: the AI
just won't have any samples to learn from if humans
don't write it.
I'd like to think the AI-operator-coding world is far
away (but admittedly I've never tried CoPilot myself,
so I don't know how usable it is).
What I do feel pretty strongly about is that it puts
oneself at a disadvantage to use a pure text editor for
professional coding where a code editor might provide a
more full-featured suite of tools.
Even the most adept vi(1) user probably can't keep up
with an LSP enabled editor.
But hey, I'd love to be proved wrong. As someone who
strives for simplicity in software (this is on Gopher
after all), I'd love to believe some combination of
vi(1) for surgical edits, sed(1) for bulk edits, etc
could culminate to VSCode efficiency. It just feels
like a losing battle having a human make all the
incantations when we've written language parsers that
can make high level edits for us.
Now, the more philosophical question is: with the trend
towards better automation, is it worth becoming a
skilled/efficient editor of text at all? How much of
our time is thinking, designing, and generally not
cranking out words? Is it worth hours of learning,
config customization, to get the most efficient
environment? At what point is one doing themselves a
disservice by refusing to use a code editor and
insisting on editing code as text?
I'd like to believe (maybe partially biased by sunk
cost fallacy) that efficiently editing text is still an
important skill, even with better editing software: so
much of the things we deal with are unstructured text
(logs, emails, blog posts, data files, etc). Of course,
you can't always use your favorite editor for all text
(unless that editor is Emacs and you're willing to
customize it :)).
I also think there's some joy in knowing a language
well enough to code in it without assistance (even if
that's probably not the way one should write
professional software while "on the clock"); its like a
chef cooking from memory instead of following a recipe:
probably error prone and slower, but enjoyable? There's
a better analogy out there somewhere.
]]>
Revisiting Emacsgopher://alexkarle.com/0/phlog/023.txt2022-11-15T15:25:47-05:002022-11-15T15:21:09-05:00
"$PHLOG/$file"
echo "$underline" >>"$PHLOG/$file"
date >>"$PHLOG/$file"
ed "$PHLOG/index.gph" <1M LOC of
LISP, but if the core is solid and makes a hackable
platform, isn't that a properly designed
platform/system? (note: didn't try to weed out test
code, used David Wheeler's SLOCCount)
In other words, Vim and NeoVim feel like they're
gravitating towards Emacs, but with a fragmented
community and a less capable extension language (even
if they have a better core editor).
I wonder if Emacs will have a revival? (but such a
discussion needs to discuss the elephant in the room:
VSCode, and that requires a whole other post!).
]]>
Adventures in Schemegopher://alexkarle.com/0/phlog/022.txt2022-11-02T00:37:14-04:002022-11-02T00:37:14-04:00
L3: call yin1 on yang1 (jump back to L1 and
--> return yang1 from call/cc, storing it in yin)
yin1' | 1 | yang1 | nil | @*@
yang2 | 2 | yang1 | yang2 | @*@*
--> call yang1 on yang2 (jump back to L2 and
--> return yang2. but NOTE yin has also gone
--> back to its old value at the time yang1
--> was crafted!)
yang1' | 2 | yin1 | yang2 | @*@**
--> call yin1 on yang2
yin1' | 1 | yang2 | nil | @*@**@
yang3 | 2 | yang2 | yang3 | @*@**@*
--> call yang2 on yang3
yang2' | 2 | yang1 | yang3 | @*@**@**
--> call yang1 on yang3
yang1' | 2 | yin1 | yang3 | @*@**@***
--> call yin1 on yang3
yin1' | 1 | yang3 | nil | @*@**@***@
yang4 | 2 | yang3 | yang4 | @*@**@***@*
yang3' | 2 | yang2 | yang4 | @*@**@***@**
yang2' | 2 | yang1 | yang4 | @*@**@***@***
yang1' | 2 | yin1 | yang4 | @*@**@***@****
yin1' | 1 | yang4 | yang5 | @*@**@***@****@
And so on... because the continuation for yang encloses the
value of yin at the creation time, whenever we invoke yangN
on yangK, we print a * and invoke yangN-1 on yangK until
yang1 at which point yin goes back to yin1 and we print a
new @ and create a new yangN+1. yin is then yangN and the
cycle continues.
Wow, right?
This is also shown by looking at the following output of the
pointers for each variable (using CHICKEN Scheme):
(import (chicken memory) (chicken format))
(let* ((yin ((lambda (cc)
(newline) cc)
(call/cc (lambda (c) c))))
(yang ((lambda (cc) cc)
(call/cc (lambda (c) c)))))
(display (format "~A | ~A\n" (object->pointer yin) (object->pointer yang)))
(yin yang))
# | #
# | #
# | #
# | #
# | #
# | #
# | #
# | #
# | #
# | #
# | #
# | #
# | #
# | #
# | #
Notice that we always get down to bb0 in yin and then start
over!
As a final note, I got super confused in the middle of
writing this because of this example:
(define cc #f)
(let ((state "foo"))
(display
(+ 1
(call/cc (lambda (c)
(set! cc c)
1))))
(newline)
(display state)
(set! state "bar")
(newline))
(cc 5)
I thought surely that this would print:
2
foo
6
foo
Since the closure captured the value of "state" as "foo" at
the time. But instead it prints "bar". What gives??
My best guess here is that set! _modifies_ the continuation
environment in-place. In the yin-yang puzzle, each (let)
creates its own environment, so we end up with the
returning-to-old-values behavior, but when we use set! it
modifies the environment from underneath the continuation.
I'll do more research when it's not past midnight :)
]]>
Remembering the Kitchen Computergopher://alexkarle.com/0/phlog/021.txt2022-10-09T00:15:20-04:002022-10-09T00:15:20-04:00The Joys of IRCgopher://alexkarle.com/0/phlog/020.txt2022-10-06T23:56:27-04:002022-10-06T23:56:27-04:00
/dev/null
NICK rssbot
USER rssbot rssbot localhost :rssbot
PRIVMSG #garbash :New post '$1' here: $2
QUIT
EOM
How cool is that?? If all goes well, it should get
notified about this post :)
[1]: https://git.garbash.com/alex/irc-rss-listener/log.html
## Looking Forward
I'm optimistic that the work coming out of the great
folks at sourcehut.org will keep IRC along for some
time more. chat.sr.ht is a fantastic solution (running
a SaaS version of Gamja and Soju), providing an easy
cross platform way to connect to multiple servers
(with things like history built right in).
I can't say I've tried many other FOSS messaging
protocols like XMPP or Matrix, but I do hope the future
is open-protocol and not walled-garden like Discord
or Slack.
]]>
On Simplicitygopher://alexkarle.com/0/phlog/019.txt2022-10-06T00:47:53-04:002022-10-06T00:47:53-04:00
I want to make a really important point here:
> I've said Go is simple, but it's not.
> I know, I've worked on it!
> ...
> Simplicity ... is the art of hiding complexity
Scheme's simplicity seems to come from a mathematical
purity--closures and recursion and homoiconicity.
Go's simplicity seems to come from excellent design
focused on modern software needs.
It's a wonder they can be used to do the same things.
[1]: http://craftinginterpreters.com/
[2]: https://www.youtube.com/watch?v=rFejpH_tAHM
]]>
True Burrowinggopher://alexkarle.com/0/phlog/018.txt2022-10-02T22:17:07-04:002022-10-02T22:17:07-04:00The Non-Technical Diffculties of Phlogginggopher://alexkarle.com/0/phlog/017.txt2022-09-25T00:00:48-04:002022-09-25T00:00:48-04:00Been a Whilegopher://alexkarle.com/0/phlog/016.txt2022-09-23T00:17:33-04:002022-09-23T00:17:33-04:00Add Context to Your Notesgopher://alexkarle.com/0/phlog/015.txt2021-12-11T16:31:24-05:002021-12-01T00:16:51-05:00Screen Timegopher://alexkarle.com/0/phlog/014.txt2021-11-30T23:54:44-05:002021-11-30T23:54:44-05:00
meetings are screens), and then "couch time"
hobby coding and watching shows if Jennie and I don't otherwise
have a social commitment (most work nights).
Sometimes we give our eyes a break and play a board game, do
a puzzle, or read a book; but even if I spent no time on screens
outside of work, it'd be a shocking number of hours at a screen
each week.
When did I transition from such limited computer-time to such
a screen-full day? It probably started with high school, when
we started having homework on computers. Limiting screen time
became "limited video game time" and less-so about screens.
Regardless of when it happened, I've been wanting to get back
some of that offline time recently. I definitely find it
improves my mood and outlook on work and life.
I need to get outside more :)
]]>
Gopher-First Feedsgopher://alexkarle.com/0/phlog/013.txt2021-11-25T00:17:05-05:002021-11-25T00:17:05-05:00Optimizing for Archivalgopher://alexkarle.com/0/phlog/012.txt2021-11-21T14:08:02-05:002021-11-21T14:08:02-05:00Lowering Barriers to Writinggopher://alexkarle.com/0/phlog/011.txt2021-11-21T10:58:30-05:002021-11-21T10:58:30-05:00
"$PHLOG/$file"
echo "$underline" >>"$PHLOG/$file"
date >>"$PHLOG/$file"
ed "$PHLOG/index.gph" <Adding a Feed for the Phloggopher://alexkarle.com/0/phlog/010.txt2021-11-17T00:33:07-05:002021-11-17T00:33:07-05:00Going Live on the Webloggopher://alexkarle.com/0/phlog/009.txt2021-11-15T00:16:38-05:002021-11-15T00:16:38-05:00Choosing a Phormat pt. 4gopher://alexkarle.com/0/phlog/008.txt2021-11-11T22:53:11-05:002021-11-11T22:53:11-05:00Choosing a Phormat pt. 3gopher://alexkarle.com/0/phlog/007.txt2021-11-11T22:53:11-05:002021-11-11T22:53:11-05:00What's in a RFC?gopher://alexkarle.com/0/phlog/006.txt2021-11-11T22:53:11-05:002021-11-11T22:53:11-05:00Server Migrationgopher://alexkarle.com/0/phlog/005.txt2021-11-11T22:53:11-05:002021-11-11T22:53:11-05:00Launch Plangopher://alexkarle.com/0/phlog/004.txt2021-11-11T22:53:11-05:002021-11-11T22:53:11-05:00Momentumgopher://alexkarle.com/0/phlog/003.txt2021-11-11T22:53:11-05:002021-11-11T22:53:11-05:00Choosing a Phormat pt. 2gopher://alexkarle.com/0/phlog/002.txt2021-11-11T22:53:11-05:002021-11-11T22:53:11-05:00Choosing a Phormatgopher://alexkarle.com/0/phlog/001.txt2021-11-11T22:53:11-05:002021-11-11T22:53:11-05:00