the_text = "a simple text value"

Bear
2025-06-15 20:44
About five days ago Mya started barking like crazy in the middle of the night. In the morning we found our bird feeder had been knocked over.
Four days ago we spotted a fox hanging around the bird feeder (which, you know, attracts fox food).
Three days ago we got a community email that a bear had been sighted. This included two photos, one of which was taken one property over from us.
This morning at about 0600 Mya and I both heard something outside. I jumped up and was able to take some photos of the cause. A bear!
I’ve seen quite a few brown bears in Canada and California and, yes, they’re bigger, but this visiting black bear impressed me with his size. He was a big animal!
Just look at that bird feeder pole. That is a steel pipe and the bear just broke it in half! Sorry, birds, looks like you’re not getting fed any more.
You also hear about how fast bears are but I’ve never personally seen one running quickly. (I personally have run and biked quickly away from them!) This one did give us a demonstration by running across our forest and, ya, as someone who is pretty experienced at moving through the forest quickly, this bear was fast. There’s no way I could match its speed on snow skis under my own power. If I had a decent enough head start, out-running one on rollerskis could be possible only if the bear tired after 100m or so. In my best cycling shape, I do think on a bike on pavement I could have outrun this bear’s demonstrated running speed. But I’m not in my best cycling shape. And maybe the bear wasn’t at top speed. I do think about these things for obvious reasons. Now I can hope about these things too — hope it doesn’t ever become an issue.
Skiing in the winter I saw wolf tracks all the time in the deep middle of nowhere. But I never worried too much about them since the tracks were always alone. (Here’s a dashcam clip of a wolf on our property.) But I did often worry about bears. You may think you’re safe when they’re presumably hibernating, but I’ve heard of backcountry skiers accidentally skiing into/on their dens and waking them up. I always keep that in mind.
Best Programming Language For Text
2025-06-14 21:11
There are a lot of standard challenges that face all serious programmers at some point. My favorite is the problem of encoding text strings with text strings. It is my favorite inevitable problem because, in the programming language I created, I have cured it.
It’s nearing 20 years since I came up with my system and during that time I have overwhelmingly preferred it over all other systems I have ever encountered. As one of my better innovations, I felt it deserved to be highlighted on its own.
The Problem
Let’s start with an overview of what I’m talking about and the notable forms this problem takes. Simple text is always simple. Consider a generic definition of a string of text in some hypothetical computer language.
That is a very normal way to define text strings. Cool. Easy!
Let’s now jump right to the thought experiment that I think best illustrates the worst kinds of problems: text for a user manual. What if the real text string I want to define is part of a programming manual describing the bit about how to define text strings?
text_definition_example = "the_text = "a simple text value""
Serious programmers see the problem immediately and even normal people are likely to sense it — the quotes are ambiguous. Are they part of the defining of the string, or part of the string itself?
(I love this cartoon! And the magnificent Dan Piraro, the creator of the Bizarro comic, kindly gave me permission to use it to educate about text entry problems. Go check out his website and send him some $.)
The normal way this is handled — and universally hated by programmers — is to "escape" certain characters from the program syntax so they can remain inert as part of the text string itself. Here’s the typical C way.
char text_definition_example[] = "the_text = \"a simple text value\"";
The \"
pair gets converted to just a simple double quote character
in the resulting text string. But we’re writing a manual, remember?
How do we then explain that, how to suppress interpreting a double quote
as program syntax? Well, here’s how that would traditionally be done
in C — and why this kind of thing makes programmers queasy.
char complex_definition_example[] = "To include a literal quote, use \\\".";
Don’t worry if you’re eyes are glazing over looking at that — that happens to even the sharpest programmers when faced with enough of this kind of syntax gunk. I mention C because it inspired many style elements and ways to solve syntax problems for many, perhaps most, programming languages (Python, Javascript, Java, R, obviously other nominal C derivatives, etc.).
However it is interesting to note that this style of character escaping wasn’t new to C. Here is what the solution looked like in Lisp a decade before C.
(setq myString "A quoted \"quote\".")
This "solution" to the problem is by far the most common one in all of software creation.
A newer partial remedy which is found in languages like Python, JavaScript, PHP, Perl, R, Lua, SQL, Go, Rust, and Bash (sort of) is to let the user choose what kind of quote character they’d like to use. These both define strings in, say, Python.
t1 = 'text'
t2 = "also text"
This means you can do this.
fact = 'The first "Windows" keys had Apple logos.'
It is amazing how seldom this type of quote substituting is a good solution. It mostly just leads to annoying capricious style discrepancies.
I won’t go into detail but Python’s text formatting has
bloated into all kinds of exuberant features for string input: raw
strings, formatted strings (including an optional format()
function), variable substitution in strings (two completely different
syntaxes), triple quote (single and double) blocks, Unicode strings,
and template class string voodoo. I’m not saying it’s bad — it’s typical for
modern languages — but it is hard to look at that and say those text
syntax rules are clear and simple.
I definitely researched a lot of programming languages when I designed mine and interestingly one of the best ones for string quoting is Fortran. Fortran definitely has the usual mess of backslash escape sequences; beating C by over a decade it may actually be the ultimate source of the technique that is near universal today.
Interestingly Fortran also allows a rather idiosyncratic way to escape quotes in strings. To include an apostrophe in an apostrophe-delimited string, you can repeat it. To include a double quote in a double quote-delimited string, you can also repeat that too.
character(len=20) : : myString = 'A quoted ''quote''.'
This stores A quoted quote. into myString. Ultimately Fortran is still a bit clumsy but I did take some slight inspiration from this syntax.
Why Me?
It may seem ridiculous that I, Chris Edwards, thought up a better solution but it is helpful to understand why this problem was so much more oppressive to me than for normal programmers. When I first was getting serious about writing software I was working as the plant engineer of a machine shop and every day I would see shop prints filled with text like this.
(3) 1' 2-1/4" C'BORE 2" DP.
The reason I thought to write about this today is I was just looking at a land survey document that included tons of directional bearings like this.
Those are angular minutes and seconds. Every day I also record text noting temporal minutes and seconds for my workouts.
Maybe most programmers can dodge these annoying cases, but I run right into them all the time! When I started designing my own programming language in the early 2000s, the main application I envisioned was to support a technical geometry system (modeling, GIS, solving complex geometry problems, etc.) Solving the problem of how to specify extremely inconvenient text typical of technical geometry was one of my main goals.
My Solution
My solution is that text delimiters are defined — always — as a pair
of single quotes (aka apostrophes): ''
. I chose this character
because it is a home row key and no shift is needed. Pressing it twice
should be slightly more ergonomic than one double quote.
This solves all problems — except one. If you’ve been following along,
you may be wondering: ok, how then are a pair of single quotes
specified as content text? The answer is what I call the magic
character. Normally it is ^
, aka ^.
Because this glyph usually modifies other characters (e.g. hôpital,
hôtel), this character in isolation is very seldom found in natural
text, at least in my experience. (Though not impossible! For example,
I do use it here.) By putting this magic
character directly between two single quotes, the result is that the
magic character is dropped, leaving just the two single quotes.
Problem solved!
Input:
''A '^' B''
Result:
A '' B
Whoa, hold up! Doesn’t that now introduce a new problem? Yes it does.
What if you need your text to actually include a '^'
? If the magic
character gets stripped out what do you do? First, let’s understand
that we are now firmly into very weird territory. The only natural
case I’ve ever contrived for this to occur is perhaps describing how
to construct a regular expression. For example, if I wanted the
following text, this way to specify it would not work.
''Expand your term by adding anchors: regexp='^'+term+'$'''
The first solution I have provided for is that you can set your magic character to anything you want with a kind of pragma variable. But that could get messy. Let’s stay within the orthodox system and instead solve this very small problem by creating a much smaller one. This will work to create the string shown above.
''Expand your term by adding anchors: regexp='^^'+term+'$'''
When two of the magic characters are found directly between single quotes, one is removed. And yes, to get two magic characters between single quotes, use three and one will be removed. Need 3, use 4. Ad infinitum. Use as many as you need. And that’s it. I do not think there are any more rules that are needed to cover all cases. Yes, that is somewhat of an infinite regress but no worse than obnoxious backslash escaping. And every level down you go, the need for another level becomes orders of magnitude smaller.
As I mentioned the best demonstration of the problem is encoding text for a user manual, i.e. something that uses how it works to describe how it works. The following shows the exact characters I use in the definition syntax and then I will show the resulting string. The content of the example input/result pairs are explanatory, and the result text is factually correct.
Input:
''Text is specified with two apostrophe (') characters.''
Result:
Text is specified with two apostrophe (') characters.
Input:
''Typing '^'foo'^' would make a text object containing "foo".''
Result:
Typing ''foo'' would make a text object containing "foo".
Input:
''Note that to get that text '^^' was typed where a '^' was desired.''
Result:
Note that to get that text '^' was typed where a '' was desired.
Input:
''This can be repeated indefinitely to get '^^^' and so on.''
Result:
This can be repeated indefinitely to get '^^' and so on.
Here’s a more complicated example. Let’s say I want this text.
"He said, 'It's text with "doubles" and 'singles'.'", she replied.
"But what about ""doubled doubles"" and ''doubled singles''?" I asked.
I simply enter this, both lines as is.
''"He said, 'It's text with "doubles" and 'singles'.'", she replied.
"But what about ""doubled doubles"" and '^'doubled singles'^'?" I asked.''
The only weirdness there is inserting the magic character in the content doubled (single) quotes. I would show you how gruesome that is with backslash escaping, but I would probably get it wrong. I don’t feel bad about that because even modern LLMs often struggle with this kind of thing.
Problems
In practice, I’ve never run into problems or limitations with my system but here are some potential arguments against it.
-
It’s different and unfamiliar. I consider this a plus since the traditional C style system is so terrible.
-
More bytes required for source code. This was something that K&R maybe needed to think about when each delimiter took up valuable chad on a punch card, but today Python with its addition of single character string hints tells us it’s not profligate to use two extra characters to completely eliminate 99% of quoting problems.
-
Does not do fancy formats and variable substitutions. Python has a
.format()
function, and that really is the correct way to do this. I’m not sure that adding a new third syntax (beyond using normal strings and beyond using functions) is ideal. -
Utility through obscurity. If this system were to catch on, then doubled single quotes would appear in content text more often. But still, it’s easier to deal with than the old Lisp/C system.
Advantages
-
Simple cases are simple. The simplest case covers almost everything any real text ever needs. It is generally much less intrusive.
-
More readable. Only one weird non-natural character is ever seen within the text and it can be truly unusual highlighting its purpose. This is in contrast to backslash escaping which immediately runs afoul of anything to do with DOS or Windows because of filesystem/server paths. Also many typesetting systems heavily depend on it like TeX/LaTeX and RTF.
-
Complex cases - simple rules. Even when doing hard text (like explaining its own syntax) it is still quite easy and the rules are minimal and quickly and fully understood.
-
What you enter is what you get. It’s very flexible in handling newlines, special characters, and the natural usage of common delimiters as quotation marks and apostrophes.
-
Customizable. Allowing a pragma to set the magic character allows specific projects (that may heavily use the default magic character in their content for some reason) to avoid problems completely.
-
Easy implementation. It must be easy to write a parser for this system because even I have managed to do it. It’s one of the more robust parts of my interpreter.
That is basically my text quoting system. I think it is better than any other I’ve ever come across. By a lot. The rest of my programming language is generally superior to all other programming languages because the guys who made the 1990s HP programmable calculators were geniuses and I lifted their stuff pretty much directly. But the text input system is all mine and it is something I’m quite proud of.
Rowing Again
2025-06-09 21:05
When I was a teenager, for some weird reason our high school had a rowing team. If you ask me what my second favorite memory from high school is, well, I’m drawing a blank — I’m pretty sure I don’t have one. My only fond memory from my high school experience is rowing.
It was rowing that introduced me to serious athletic goals. When I moved on to university I went to the freshman orientation and found the rowing team and told them that I was somewhat competent. I put my name and contact info on their sign up sheet and never heard from them again. I moved on to triathlon and TT cycling and I never rowed again. Until this Saturday.
After 38 years of not being able to row, I finally returned to it. A couple of days ago, I was just testing my rowing shell to see if it actually floated and worked and getting the rigging setup. The shell is a very strange boat - a Scullcraft rowing shell. It was made by a Michigan canoe company and has much in common with canoes. It’s 18'-6" long with a 27" beam. It’s 62lbs which is pretty light considering that it was probably made between 1984 and 1986. I paid $220 for it — an incredible bargain! It even came with two obsolete carbon fiber Concept2 Oars. Today serious people use the new style of offset "hatchet" oars. But no complaints from me — these old style oars are exactly the ones I used in high school in the late 1980s!
This evening I went for my first substantial outing in a rowing shell since I was a teenager.
I did 3km, across the lake and back, in 17m 24s at a pace of 10.4kph. Interestingly that’s about the pace I could ski it in the winter. For reference, my best time on the indoor rowing machine in 2020 just hit 16kph after several months of intense training (which I covered here). But during that program I started out at about 13kph. So this boat is not too far off of the rowing machine’s calibration (which is for racing shells).
It’s been a long time since I’ve rowed, but an even more weird fact is that until today, I have never — to my knowlege — been photographed rowing a boat. I fixed that today.
Today I even took a video. It’s long and kind of boring but you might like skipping around and seeing what it looks like for me to cross our lake. It also shows the very irritating precautions taken to keep the bugs off me at the shore. No bugs out on the lake thankfully!
Ya, watching that, my form looks terrible. I’m pulling high at the catch for some reason. But hey, remember, it’s been 38 years, I’ve never rowed a boat like this, and I’ve never seen myself row before! Also, sorry about that super annoying squeaking — of course it waited to start right when I get too far from our dock to do anything about it. Also the 40 year old foot stretchers broke in the middle of the lake on my way back. There are definitely some details that still need a little work, but overall, I’m quite happy with this boat!
Mya and A* were also out on the water tonight to rescue me if my boat sank or had some serious operator error.
Due to a lack of opportunity, I’ve been kept away from rowing for a long time but I’m glad to be back!
Tree Problems
2025-04-29 08:53
Here is something I worry about.
I was out walking with Mya in a pretty intense wind storm and I heard a tree fall. With all that experience being out in the forest in challenging weather I know exactly what trees sound like when they fall and this didn’t sound normal. Sure enough, this one had hit a neighbor’s house.
With the power cutting out all evening I didn’t have anything better to do than apply some engineering physics to cure the problem.
Luckily no damage done by the falling tree or me getting it off the roof.
Some people worry about my safety when I go out into the forest during high winds. But I think of it like the lottery. Are you going to win the lottery? The statistical answer is clear — no. But what if you buy two tickets? Well, still no. What about ten? Nope, still very unlikely to happen. That’s like going out into the forest on a windy day — the stronger the wind, the more lottery tickets. Yes, I may be many times more likely to be crushed by something on a windy day, but the odds are that I’ll just hear more things crashing around me. Don’t get complacent, but the forest is a big place. As you can see, it’s probably worth being more worried about a tree falling on you when you don’t leave the house!
The Magnificent Ski Season
2025-04-28 22:03
I have a lot of goals but the one that was at the top of the list when winter came was to ski as much as possible. This year, I feel like I have truly accomplished that goal.
A few days ago I posted a video showing what the last few days of the 2024-2025 XC skiing season looked like in my corner of the world, the Western Hiawatha National Forest of the UP in Michigan. Hopefully that video evidence can help you understand how I was able to make this an almost unbelievable ski season. This report is a look back at this amazing season.
My main metric for how I judge a ski season is number of days I was able to ski on snow. This winter of 2024-2025 I was able to ski on snow 150 days. Not only that but these were all the contiguous days starting on November 25 and ending on April 23. I believe I skied every day it was possible to ski.
One of the ways I am able to ski so much is that I am doing cross country skiing, a.k.a. Nordic skiing. Nordic skiing is a kind of transportation where you actually travel, uh, across the countryside. Over these 150 days, my total distance skied is a pretty serious 1146.5km (712mi). This is like the distance separating Chicago from New York City. This is an average daily distance skied of 7.6km/day.
The total amount of time I spent skiing on snow this season was 141hrs 37min. This is an average daily time of about 57min/day. Each and every day for 150 days.
You might be noticing that this works out to an overall average speed of 8.1kph over the whole season, and thinking that’s not that fast. That is quite true and this pace tells much more of the story. The reason this pace is so low is that 87% of the time I did not ski where grooming ever takes place, and half of the time I went to some place that sometimes is groomed, they had not yet started or stopped for the season.
This can be seen when looking at the disparity in my pace. My fastest two kms were tied at 18.4kph. My top 8 daily fastest extraordinary kms on snow over the entire season averaged 17.1kph, over double my average pace. Compare that with a quotidian outing on rollerskis, for example this morning, where I did 8 contiguous kms all of which averaged 21.0kph. (The fastest km was 24.3kph!) Clearly the slow speeds on snow is not so much about me but about the exceptionally strenuous snow conditions I regularly skied on.
Another hypothesis would be that I’m somehow good at rollerskiing and less effective on snow. I would challenge that by pointing out that I was incredibly lucky with mishaps. Sure, I had a couple of stumbles here and there getting my ski hooked around a beech tree or slightly overcooking icy descents or tripping over a layer of crust after it collapsed under me, but really I only had one bad fall in all of the 150 days. I had stopped at the driveway of a neighbor to chat with him and was standing there chatting for maybe 15 minutes when suddenly I fell to the ground. I did a pretty good job of landing on my butt in a damage minimizing way, but out of all the sketchy things I did on skis this year to have the biggest problem just simply standing still, well, I’ll take it! (I think what happened there was I was on some snow that transformed from the pressure of me standing on it from pretty high friction to very low friction icy. I maybe melted down to an ice layer. Suddenly the very slight angle of the driveway became more relevant than I was expecting.)
You might assume that with all this extra hard skiing that I would be in fantastically good physical shape. You would be correct. Also consider how all that snow got cleared from my driveway and walkways.
I was blessed to avoid any serious illness this winter. The closest to ill I felt was later in the afternoon after skiing on day 150. Good timing.
There are not a lot of photos of me skiing but this, day 142, is roughly what I looked like most of the time.
As you can see, I was up for it but what is most astonishing is the weather. Last year in the UP, there was practically no snow at all the entire winter. But this year, wow. And it wasn’t the kind of obnoxious lake effect snow where you get 2 meters in a weekend and then it goes back to raining (ahem South Towns of Buffalo). The snowfall was really well paced. And what I always stress is that it is never about the snowfall really — what makes a great ski season is the temperatures. You need to have consistently cool temps so that when precipitation comes, no matter how slight, it adds to the snowpack, not extirpates it in the form of rain. I thought early on in the season that surely there would be some skiable snow that would disappear and that would repeat a few times until the proper base came. But no, that first snow covered the ground and endured in many places for five months. It’s also important for maximal skiing to be very attentive to weather reports and signs so that you can choose the optimal time of day to ski. Also important to be attentive to is tree shading, slope facing, drift catching, drainage, ice formation, etc.
With so much skiing, ski care became quite an operation. I only started recording my ski waxing habits at the end of December when I realized this would become somewhat complicated if I didn’t pay attention. I recorded 32 times where I waxed a pair of skis but it was surely well over 40. I did get better at it as the season went on. It now takes me about 6 minutes per ski to clean the ski, apply wax, iron the wax, scrape the excess wax, brush the ski (3 different brushes), polish, and do whatever else is necessary to get them ready to go again (e.g. lightly run a cabinet scraper to cut away base damage, paste wax on the tops and/or bindings to prevent sticking snow, etc). This means I spent well over the equivalent of an entire work day doing nothing but waxing skis all day long. I tried a bunch of waxing strategies, but with "garbage snow" or even great snow that’s not groomed, you’re really chasing your tail if you worry about the fine details too much. I mostly stuck with what I call "Toko Cheap Red". It roughly works, it’s easy and, yup, it’s cheap.
Here’s my wax log showing when I waxed each pair of skis and how many kms they had on them.
BLUEVO - 1-27 22km, 2-10 23km, 2-19 20km, 2-24 23km, 2-28 24km, 3-10 20km, 3-18 25km,
3-23 19km, 3-25 26km, 4-2 23km, 4-4 25km, 4-5 25km, 4-10 24km
MTLSOL - 1-27 40km, 2-19 22km, 2-28 24km, 3-18 7km, 3-23 22km, 4-2 22km, 4-10 29km
BLKEVO - 1-27 22km, 2-10 17km, 2-19 27km, 2-24 24km, 3-10 44km
GLDEVO - 1-27 24km, 2-10 22km
FSHSKN - 1-27 25km, 2-19 7km
FSHSK8 - 2024-12-24 46km, 2-24-20km
MADSK8 - 1-10 20km
Here is what such a long season of wax scrapings looks like.
As you can see, I have a lot of pairs of skis and they all have their merits. The wax log hints correctly at which skis are my favorite. Here is a breakdown of exactly what my ski collection is and how many times this year I used them (the half values mean I came back to the house and switched halfway through).
I think it’s pretty weird that my best and fastest skis — which I protect from abuse — were only appropriate for the conditions twice. If there’s an area for improvement, that is it.
Here’s a photo of my well loved blue Evos after skiing through some very ragged snow on day 146. These skis have taken some serious abuse!
Here is a complete day by day representation of most of the interesting data I have about this season.
-
The blue bars show the duration of the outing in hours.
-
The green bars show the distance covered in km.
-
The black diamonds show the average speed of the outing in km/hr on the same scale (or close) as the distance bar. The numeric value of the average speed is shown as the first number on the right.
-
The black triangles on the right show the speed of the fastest km for that outing. It’s interesting to compare this to the average. Some outings didn’t get individual kms recorded and this mark is absent. The numeric value of the max km pace is shown as the second number on the far right (where extant).
-
The stars are a personal subjective rating of the outing where 1 star is skiing but as annoying as it can be and 10 is the best flawless skiing imaginable. I only started rating the outings in 2025 so early days just have a square.
-
The color of the stars (or square) show which skis I used, color coded the same as the pie chart above.
-
The codes after some of the dates show excursions to official ski trails which sometimes will be groomed. "mk" = McKeever Hills, "vs" = Valley Spur, et al.
The stars that show my subjective rating of a ski outing were an attempt to empirically analyze and optimize the good things about skiing. I find that rating the outing is very helpful for clarity. "Am I really enjoying this?" is a sane question that everyone who skis 150 days in a year will be asking at some point.
The interesting thing I have discovered with such a large data set is that for me something like the following is roughly true.
This means I’m reckoning that my assessment is correct about half of the time — good or bad. But when I’m wrong, I tend to overstate the lack of potential. The lesson one should take if this kind of pattern is observed, is that, sure, you should try things that seem like they will be suboptimal. By recalibrating my expectations to give opportunities the benefit of the doubt, I’ve definitely come out ahead skiing. I think it also applies to many other areas of life.
Finally, I must mention one other element of unreasonably good fortune this ski season, my wonderful wife. Imagine what a fantastic good sport you’d need to be to indulge my foolish quest to ski such an unreasonable amount — and she was that good sport. She didn’t just tolerate my mad hobby but she herself skied 35 days on snow. She skied a very respectable 185km this year. Sometimes the date is shown twice in the data plot — that is generally where I’m going out multiple times in the day, usually a second time to ski with her. She did not grow up skiing and rightly avoids a lot of the sketchy conditions I will blithely ski on. She can have a hard time descending which is the part that’s normally considered "easy". But her climbing is impressive and her endurance is better than mine — her average outing time was just under 59 minutes. Getting to ski with her was definitely the highlight of the season.

For older posts and RSS feed see the blog archives.
Chris X Edwards © 1999-2025