<?xml version='1.0' encoding='utf-8' ?>

<rss version='2.0' xmlns:lj='http://www.livejournal.org/rss/lj/1.0/' xmlns:atom10='http://www.w3.org/2005/Atom'>
<channel>
  <title>The Mandelbear&apos;s Musings</title>
  <link>https://mdlbear.dreamwidth.org/</link>
  <description>The Mandelbear&apos;s Musings - Dreamwidth Studios</description>
  <lastBuildDate>Sat, 28 Nov 2020 04:38:49 GMT</lastBuildDate>
  <generator>LiveJournal / Dreamwidth Studios</generator>
  <lj:journal>mdlbear</lj:journal>
  <lj:journaltype>personal</lj:journaltype>
  <image>
    <url>https://v2.dreamwidth.org/15740388/505737</url>
    <title>The Mandelbear&apos;s Musings</title>
    <link>https://mdlbear.dreamwidth.org/</link>
    <width>96</width>
    <height>96</height>
  </image>

<item>
  <guid isPermaLink='true'>https://mdlbear.dreamwidth.org/1750335.html</guid>
  <pubDate>Sat, 28 Nov 2020 04:38:49 GMT</pubDate>
  <title>More on branch name changes</title>
  <link>https://mdlbear.dreamwidth.org/1750335.html</link>
  <description>&lt;p&gt; You may remember &lt;a href=&quot;https://mdlbear.dreamwidth.org/1744377.html&quot;&gt;this post about renaming the default branch in Git repositories&lt;/a&gt;.
    Since then I&apos;ve done some script writing -- they say you don&apos;t really
    understand a process until you can write a program that does it, and this
    was no exception.  (There are lots of exceptions, actually, but that&apos;s
    rather beside the point of this post...)

&lt;p&gt; Anyway, here&apos;s what I think is the best way to rename master to main in a
    clone of a repository where that rename has already been done.  (That&apos;s a
    common case anywhere you have multiple developers, each with their own
    clone, or one developer like me who works on a different laptop depending
    on the time of day and where the cats are sitting.)

&lt;pre&gt;     git fetch
     git branch -m master main
     git branch -u origin/main main
     git remote set-head origin main
     git remote prune origin&lt;/pre&gt;

&lt;p&gt; The interesting part is &lt;em&gt;why&lt;/em&gt; this is the best way I&apos;ve found of
    doing it:  1. It works even if master isn&apos;t the current branch, or if it&apos;s
    out of date or diverged from upstream.  2. It doesn&apos;t print extraneous
    warnings or fail with an error.  Neither of those is a problem if you&apos;re
    doing everything manually, but it can be annoying or fatal in a script.
    So here it is again, with commentary:

&lt;p&gt; &lt;code&gt;git fetch&lt;/code&gt; -- you have to do this first, or the &lt;code&gt;git
    branch -u ...&lt;/code&gt; line will fail  because git will think you&apos;re setting
    upstream to a branch that doesn&apos;t exist on the origin.

&lt;p&gt; &lt;code&gt;git branch -m master main&lt;/code&gt; -- note that the renamed branch
    will still be tracking master.  We fix that with...

&lt;p&gt; &lt;code&gt;git branch -u origin/main main&lt;/code&gt; -- many of the pages I&apos;ve seen
    use &lt;code&gt;git&amp;nbsp;push&amp;nbsp;-u...&lt;/code&gt;, but the push isn&apos;t necessary
    and has several different ways it can fail, for example if the current
    branch isn&apos;t main or if it isn&apos;t up to date.
     
&lt;p&gt; &lt;code&gt;git remote set-head origin main&lt;/code&gt; -- This sets main as the
    default branch, so things like &lt;code&gt;git&amp;nbsp;push&lt;/code&gt; will work
    without naming the branch.  You can use &lt;code&gt;-a&lt;/code&gt; for &quot;automatic&quot;
    instead of the branch name, but why make git do extra work?  Many of the
    posts I&apos;ve seen use the following low-level command, which works but isn&apos;t
    very clear and relies on implementation details you shouldn&apos;t have to
    bother with:

&lt;pre&gt;    git symbolic-ref refs/remotes/origin/HEAD refs/remotes/origin/main&lt;/pre&gt;

&lt;p&gt; &lt;code&gt;git remote prune origin&lt;/code&gt; -- I&apos;ve seen people suggesting
    &lt;code&gt;git&amp;nbsp;fetch&amp;nbsp;--prune&lt;/code&gt;, but we already did the fetch way
    back in step 1.  Alternatively, we could use &lt;code&gt;--prune&lt;/code&gt; on that
    first fetch, but then git will complain about master tracking a branch
    that doesn&apos;t exist.  It still works, but it&apos;s annoying in a script.

&lt;blockquote&gt;
&lt;p&gt; Just as an aside because I think it&apos;s amusing:  my former employer (a
    large online retailer) used and probably still uses &quot;mainline&quot; for the
    default branch, and I&apos;ve seen people suggesting as an alternative to
    &quot;main&quot;.  It is, if anything, more jarring than &quot;master&quot; for someone who
    has previously encountered &quot;mainlining&quot; only in the context of
    self-administered street drugs.
&lt;/p&gt;&lt;/blockquote&gt;

&lt;p class=&quot;colophon&quot;&gt; &lt;em&gt;Another fine post from
   &lt;a href=&quot;https://mdlbear.dreamwidth.org/tag/curmudgeon&quot;&gt;The Computer Curmudgeon&lt;/a&gt; (also at
   &lt;a href=&quot;https://computer-curmudgeon.com/&quot;&gt;computer-curmudgeon.com&lt;/a&gt;).&lt;br&gt;
   Donation buttons in &lt;a href=&quot;https://mdlbear.dreamwidth.org/&quot;&gt;profile&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;img src=&quot;https://www.dreamwidth.org/tools/commentcount?user=mdlbear&amp;ditemid=1750335&quot; width=&quot;30&quot; height=&quot;12&quot; alt=&quot;comment count unavailable&quot; style=&quot;vertical-align: middle;&quot;/&gt; comments</description>
  <comments>https://mdlbear.dreamwidth.org/1750335.html</comments>
  <category>black-lives-matter</category>
  <category>git</category>
  <category>scripting</category>
  <category>curmudgeon</category>
  <category>computers</category>
  <lj:mood>didactic</lj:mood>
  <lj:security>public</lj:security>
  <lj:reply-count>0</lj:reply-count>
</item>
<item>
  <guid isPermaLink='true'>https://mdlbear.dreamwidth.org/1692062.html</guid>
  <pubDate>Wed, 06 Nov 2019 06:05:00 GMT</pubDate>
  <title>How to MakeStuff (blogging)</title>
  <link>https://mdlbear.dreamwidth.org/1692062.html</link>
  <description>&lt;p&gt; Today the computer curmudgeon talks about how he blogs.

&lt;p&gt; I think it&apos;s widely known that I update this journal (and by that I mean
    both my Dreamwidth journal, which you are probably reading now,
    &lt;em&gt;and&lt;/em&gt; my &lt;a href=&quot;https://computer-curmudgeon.com/&quot;&gt;Computer
    Curmudgeon&lt;/a&gt; website), using a rickety combination of shell scripts and
    makefiles called &lt;a href=&quot;https://github.com/ssavitzky/MakeStuff&quot;&gt;MakeStuff&lt;/a&gt;.  There are several good reasons for that.  (Whether
    &quot;because I can&quot; is a good reason or not is debatable.  There are others.)

&lt;p&gt; A little over a year ago I made a &lt;a href=&quot;https://mdlbear.dreamwidth.org/1631514.html&quot;&gt;planning post&lt;/a&gt;, and
    the &quot;Where I am now&quot; section remains a pretty good, albeit sketchy,
    description of the process.  There&apos;s also an even sketchier one in the &lt;a href=&quot;https://github.com/ssavitzky/MakeStuff/tree/master/blogging&quot;&gt;README
    file for MakeStuff/blogging&lt;/a&gt;.  It had a list of what I wanted to do
    next, but essentially the only thing I&apos;ve actually done is posting in
    either HTML or Markdown.

&lt;p&gt; I have, however, reorganized things a bit, so that all of the relevant
    scripts are in MakeStuff/blogging -- the last part was moving in the
    script, now called &lt;code&gt;charm-wrapper&lt;/code&gt;, that takes the post&apos;s
    metadata out of its email-like header and turns it into a command line for
    &lt;a href=&quot;https://github.com/ssavitzky/charm&quot;&gt;charm&lt;/a&gt;, a
    livejournal/dreamwidth posting client written in Python.  It isn&apos;t a very
    good solution, but it works.

&lt;p&gt; And since I&apos;m running out of time to make a post today, I&apos;m going to start
    this series with the other utilities in MakeStuff/blogging.  And then go
    add this list to the README.

&lt;ul&gt;
  &lt;li&gt; &lt;code&gt;&lt;a href=&quot;https://github.com/ssavitzky/MakeStuff/blob/master/blogging/check-html&quot;&gt;check-html&lt;/a&gt;&lt;/code&gt; is a simple wrapper for &lt;code&gt;&lt;a href=&quot;http://www.html-tidy.org/&quot;&gt;html-tidy&lt;/a&gt;&lt;/code&gt;, a popular HTML
       syntax checker.  Since it&apos;s not actually being used to &lt;em&gt;fix&lt;/em&gt;
       syntax, it can play fast-and-loose with things like the header (it&apos;s
       just text) and blog-specific tags like &amp;lt;cut&amp;gt; and &amp;lt;user&amp;gt;.
       It handles those by putting a space after the &quot;&amp;lt;&quot; character.  It
       would be trivial to add this to the make recipe for post.
  &lt;li&gt; &lt;code&gt;&lt;a href=&quot;https://github.com/ssavitzky/MakeStuff/blob/master/blogging/last-post&quot;&gt;last-post&lt;/a&gt;&lt;/code&gt; is a site-scraper that returns the URL of your
       most recent post.  It&apos;s useful, because &lt;code&gt;charm&lt;/code&gt; doesn&apos;t
       return it.  (I eventually put that functionality into
       &lt;code&gt;charm-wrapper&lt;/code&gt;, but it&apos;s still useful.  Eventually it wants
       to take a date on the command line.
  &lt;li&gt; &lt;code&gt;&lt;a href=&quot;https://github.com/ssavitzky/MakeStuff/blob/master/blogging/word-count&quot;&gt;word-count&lt;/a&gt;&lt;/code&gt; is what I use to generate the NaBloPoMo
       statistics at the bottom of posts in November.  (In other months, you
       just get a straight list; you can also get a listing for a whole year.)
&lt;/li&gt;&lt;/li&gt;&lt;/li&gt;&lt;/ul&gt;

&lt;pre&gt;NaBloPoMo stats:
     43 2019/11/01--rabbit-rabbit-rabbit.html
   1731 2019/11/02--s4s-memorials.html
   1465 2019/11/03--done-since-1027.html
    145 2019/11/04--i-ought-to-post-something.html
    430 2019/11/05--how-to-makestuff.html
-------
   3814 words in 5 posts this month (average 762/post)
    430 words in 1 post today
&lt;/pre&gt;

&lt;p class=&quot;colophon&quot;&gt; &lt;em&gt;Another fine post from
    &lt;a href=&quot;https://mdlbear.dreamwidth.org/tag/curmudgeon&quot;&gt;The Computer
       Curmudgeon&lt;/a&gt; (also at
    &lt;a href=&quot;https://computer-curmudgeon.com/&quot;&gt;computer-curmudgeon.com&lt;/a&gt;).&lt;br&gt;
    Donation buttons in &lt;a href=&quot;https://mdlbear.dreamwidth.org/&quot;&gt;profile&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;img src=&quot;https://www.dreamwidth.org/tools/commentcount?user=mdlbear&amp;ditemid=1692062&quot; width=&quot;30&quot; height=&quot;12&quot; alt=&quot;comment count unavailable&quot; style=&quot;vertical-align: middle;&quot;/&gt; comments</description>
  <comments>https://mdlbear.dreamwidth.org/1692062.html</comments>
  <category>blogging</category>
  <category>computers</category>
  <category>scripting</category>
  <category>curmudgeon</category>
  <category>software</category>
  <lj:music>Bill Sutton: Do It Yourself (notionally)</lj:music>
  <lj:mood>geeky and didactic</lj:mood>
  <lj:security>public</lj:security>
  <lj:reply-count>0</lj:reply-count>
</item>
<item>
  <guid isPermaLink='true'>https://mdlbear.dreamwidth.org/1631872.html</guid>
  <pubDate>Fri, 27 Jul 2018 00:46:22 GMT</pubDate>
  <title>Scripting Languages</title>
  <link>https://mdlbear.dreamwidth.org/1631872.html</link>
  <description>&lt;p&gt; Today in my continuing series on programming languages I&apos;m going to talk
    about &quot;scripting languages&quot;.  &quot;Scripting&quot; is a rather fuzzy category,
    because unlike the kinds of languages we&apos;ve discussed before, scripting
    languages are really distinguished by how they are &lt;em&gt;used&lt;/em&gt;, and
    they&apos;re used in two very different ways.  It&apos;s also confusing because most
    scripting languages are interpreted, and people tend to use &quot;scripting&quot;
    when they should be using &quot;interpreted&quot;.  In my opinion it&apos;s more correct
    to say that a language is &lt;em&gt;being used as&lt;/em&gt; a scripting language,
    rather than to say that it &lt;em&gt;is&lt;/em&gt; a scripting language.  As we&apos;ll
    see, this is particularly true when the language is being used to
    customize some application.

&lt;p&gt; But first, let&apos;s define &lt;cite&gt;scripts.&lt;/cite&gt; A script is basically a
    sequence of &lt;em&gt;commands&lt;/em&gt; that a user could type at a terminal[1] --
    often called &quot;the command line&quot; -- that have been put together in a file
    so that they can be run automatically.  The script then becomes a
    new command.  In Linux, and before that Unix, the program that interprets
    user commands is called a &quot;shell&quot;, possibly because it&apos;s the visible outer
    layer of the operating system.  The quintessential script is a &lt;cite&gt;shell
    script&lt;/cite&gt;.  We&apos;ll dive into the details later.

&lt;blockquote style=&quot;font-size:small&quot;&gt;
[1] okay, a terminal &lt;em&gt;emulator.&lt;/em&gt;  Hardly anyone uses physical terminals
anymore.  Or remembers that the &quot;tty&quot; in &lt;code&gt;/dev/tty&lt;/code&gt; stands for
&quot;teletype&quot;&apos;.
&lt;/blockquote&gt;

&lt;p&gt; The second kind of scripting language is used to implement commands inside
    some interactive program that &lt;em&gt;isn&apos;t&lt;/em&gt; a shell.  (These languages
    are also called &lt;cite&gt;extension&lt;/cite&gt; languages, because they&apos;re
    extending the capabilities of their host program, or sometimes
    &lt;cite&gt;configuration&lt;/cite&gt; languages.)  Extension languages generally look
    nothing at all like something you&apos;d type into a shell -- they&apos;re really
    just programming languages, and often are just the programming language
    the application was written in.  The commands of an interactive program
    like a text editor or graphics editor tend to be things like single
    keystrokes and mouse gestures, and in most cases you wouldn&apos;t want to --
    or even be able to -- write programs with them.  I&apos;ll use &quot;extension
    languages&quot; for languages used in this way.  There&apos;s some overlap in
    between, and I&apos;ll talk about that later.

&lt;h3&gt;Shell scripting languages&lt;/h3&gt;

&lt;p&gt; Before there was Unix, there were mainframes.  At first, you would punch
    out decks of Hollerith cards, hand them to the computer operator, and they
    would (eventually) put it in the reader and push the start button, and you
    would come back an hour or so later and pick up your deck with a pile of
    listings from the printer.

&lt;p&gt; Computers were &lt;em&gt;expensive&lt;/em&gt; in those days, so to save time the
    operator would pile a big batch of card decks on top of one another with
    a couple of &quot;job control&quot; cards in between to separate the jobs.  Job
    control languages were really the first scripting languages.  (And the old
    terminology lingers on, as such things do, in the &quot;.bat&quot; extension of
    MS/DOS (later Windows) &quot;batch files&quot;.  Which are shell scripts.)

&lt;p&gt; By far the most sophisticated job control language ran on the Burroughs
    5000 and 6000 series computers, which were designed to run Algol very
    efficiently.  (So efficiently that they used Algol as what amounted to
    their assembly language!  Programs in other languages, including Fortran
    and Cobol, were compiled by first translating them into Algol.)  The job
    control language was a somewhat extended version of Algol in which some
    variables had files as their values, and programs were simply
    subroutines.  Don&apos;t let anyone tell you that all scripting languages are
    interpreted.

&lt;p&gt; Side note:  the Burroughs machines&apos; operating system was called MCP, which
    stands for Master Control Program.  Movie fans may find that name familiar.

&lt;p&gt; Even DOS batch files had control-flow statements (conditionals and loops)
    and the ability to substitute variables into commands.  But these features
    were clumsy to use.  In contrast, the Unix shell written by Stephen Bourne
    at Bell Labs was &lt;em&gt;designed&lt;/em&gt; as a scripting language.  The syntax of
    the control structures was, in fact, derived from Algol 68, which
    introduced the &quot;if...fi&quot; and &quot;do...done&quot; syntax.

&lt;p&gt; Bourne&apos;s shell was called &lt;code&gt;sh&lt;/code&gt; in Unix&apos;s characteristically
    terse style.  The version of Unix developed at Berkeley, (BSD, for
    Berkeley System Distribution -- I&apos;ll talk about the history of operating
    systems some time) had a shell called the C shell, &lt;code&gt;csh&lt;/code&gt;, which
    had a syntax derived from the C programming language.  That immediately
    gave rise to the popular tongue-twister &quot;she sells cshs by the cshore&quot;.

&lt;p&gt; The GNU (GNU&apos;s Not Unix) project, started by Richard Stallman with the
    goal of producing a completely free replacement for Unix, naturally had
    its own rewrite of the Bourne Shell called &lt;code&gt;bash&lt;/code&gt; -- the Bourne
    Again Shell.  It&apos;s a considerable improvement over the original, pulling
    in features from &lt;code&gt;csh&lt;/code&gt; and some other shell variants.

&lt;p&gt; Let&apos;s look at shell scripting a little more closely.  The basic statement
    is a command -- the name of a program followed by its arguments, just as
    you would type it on the command line.  If the command isn&apos;t one of the
    few built-in ones, the shell then looks for a file that matches the name
    of the command, and runs it.  The program eventually produces some output,
    and exits with a result code that indicates either success or failure.

&lt;p&gt; There are a few really brilliant things going on here.
&lt;ul&gt;
  &lt;li&gt; Each program gets run in a separate process.  Unix was originally a
       &lt;cite&gt;time-sharing&lt;/cite&gt; operating system, meaning that many people
       could use the computer at the same time, each typing at their own
       terminal, and the OS would run all their commands at once, a little at
       a time.
  &lt;li&gt; That means that you can pipe the output of one command into the input
       of another.  That&apos;s called a &quot;pipeline&quot;; the commands are separated by
       vertical bars, like | this, so the &apos;|&apos; character is often called &quot;pipe&quot;
       in other contexts.  It&apos;s a lot shorter than saying &quot;vertical bar&quot;.
  &lt;li&gt; You can &quot;redirect&quot; the output of a command into a file.  There&apos;s even a
       &quot;pipe fitting&quot; command called &lt;code&gt;tee&lt;/code&gt; that does both:  copies
       its input into a file, and also passes it along to the next command in
       the pipeline.
  &lt;li&gt; The shell uses the command&apos;s result code for control -- there&apos;s a
       program called &lt;code&gt;true&lt;/code&gt; that does nothing but immediately
       returns success, and another called &lt;code&gt;false&lt;/code&gt; that immediately
       fails.  There&apos;s another one, &lt;code&gt;test&lt;/code&gt;, which can perform
       various tests, for example to see whether two strings are equal, or a
       file is writable.  There&apos;s an alias for it:  &lt;code&gt;[&lt;/code&gt;.  Unix
       allows all sorts of characters in filenames.  Anyway, you can say
       things like &lt;code&gt;if&amp;nbsp;[&amp;nbsp;-w&amp;nbsp;$f&amp;nbsp;];&amp;nbsp;then...&lt;/code&gt;
  &lt;li&gt; You can also use a command&apos;s output as part of another command line, or
       put it into a variable.  &lt;code&gt;today=`date`&lt;/code&gt; takes the result of
       running the &lt;code&gt;date&lt;/code&gt; program and puts it in a variable called
       &lt;code&gt;today&lt;/code&gt;.
&lt;/li&gt;&lt;/li&gt;&lt;/li&gt;&lt;/li&gt;&lt;/li&gt;&lt;/ul&gt;

&lt;p&gt; This is basically functional programming, with programs as functions and
    files as variables.  (Of course, you can define variables and functions in
    the shell as well.)  In case you were wondering whether Bash is a &quot;real&quot;
    programming language, take a look at &lt;a href=&quot;https://github.com/mrstegeman/nanoblogger-mod&quot;&gt;nanoblogger&lt;/a&gt; and
    &lt;a href=&quot;https://abcde.einval.com/wiki/&quot;&gt;Abcde&lt;/a&gt; (A Better CD Encoder).

&lt;p&gt; Sometime later in this series I&apos;ll devote a whole post to an introduction
    to shell scripting.  For now, I&apos;ll just show you a couple of my favorite
    one-liners to give you a taste for it.  These are tiny but useful scripts
    that you might type off the top of your head.  Note that comments in shell
    -- almost all Unix scripting languages, as a matter of fact -- start with
    an octothorpe.  (I&apos;ll talk about octothorpe/sharp/hash/pound later, too.)

&lt;blockquote style=&quot;font-size:small&quot;&gt;&lt;pre&gt;# wait until nova (my household server) comes back up after a reboot
until ping -c1 nova; do sleep 10; done

# count my blog posts.  wc counts words, lines, and/or characters.
find $HOME/.ljarchive -type f -print | wc -l

# find all posts that were published in January.
# grep prints lines in its input that match a pattern.
find $HOME/.ljarchive -type f -print | grep /01/ | sort&lt;/pre&gt;&lt;/blockquote&gt;

&lt;h3&gt;Other scripting languages&lt;/h3&gt;

&lt;p&gt; As you can see, shell scripts tend to be a bit cryptic.  That&apos;s partly
    because shells are also meant to have commands typed at them directly, so
    brevity is often favored over clarity.  It&apos;s also because all of the
    operations that work on files are &lt;em&gt;programs&lt;/em&gt; in their own right;
    they often have dozens of options and were written at different times by
    different people.  The &lt;code&gt;find&lt;/code&gt; program is often cited as a good
    (or bad) example of this -- it has a very different set of options from
    any other program, because you&apos;re trying to express a rather complicated
    combination of tests on its command line.

&lt;p&gt; Some things are just too complicated to express on a single line, at least
    with anything resembling readability,  so many other programs besides
    shells are designed to run scripts.  Some of the first of these in Unix
    were &lt;code&gt;sed&lt;/code&gt;, the &quot;stream editor&quot;, which applies text editing
    operations to its input, and &lt;code&gt;awk&lt;/code&gt;, which splits lines into
    &quot;fields&quot; and lets you do database-like operations on them.  (Simpler
    programs that also split lines into fields include &lt;code&gt;sort&lt;/code&gt;,
    &lt;code&gt;uniq&lt;/code&gt;, and &lt;code&gt;join&lt;/code&gt;.)

&lt;blockquote style=&quot;font-size:small&quot;&gt;
    DOS and Windows look at the last three characters of a program&apos;s name
    (e.g., &quot;exe&quot; for &quot;executable&quot; machine language and &quot;bat&quot; for &quot;batch&quot;
    scripts) to determine what it contains and how to run it.  Unix, on the
    other hand, looks at the first few characters of the file itself.  In
    particular, if these are &quot;&lt;code&gt;#!&lt;/code&gt;&quot; followed by the name of a
    program (I&apos;m simplifying a little), the file is passed to that program to
    be run as a script.  The &quot;&lt;code&gt;#!&lt;/code&gt;&quot; combination is usually
    pronounced &quot;&lt;a href=&quot;https://en.wikipedia.org/wiki/Shebang_(Unix)&quot;&gt;shebang&lt;/a&gt;&quot;.  This
    accounts for the popularity of &quot;&lt;code&gt;#&lt;/code&gt;&quot; to mark comments -- lines
    that are meant to be ignored -- in most scripting languages.
&lt;/blockquote&gt;

&lt;p&gt; The scripting programs we&apos;ve seen so far -- &lt;code&gt;sh&lt;/code&gt;,
    &lt;code&gt;sed&lt;/code&gt;, &lt;code&gt;awk&lt;/code&gt;, and some others -- are all designed to
    do one kind of thing.  Shells mostly just run commands, assign variables,
    and substitute variables into commands, and rely on other programs like
    &lt;code&gt;find&lt;/code&gt; and &lt;code&gt;grep&lt;/code&gt; to do most other things.  Wouldn&apos;t
    it be nice if one could combine all these functions into one program, and
    give it a better language to write programs in.  The first of these that
    really took off was Larry Wall&apos;s &lt;a href=&quot;https://en.wikipedia.org/wiki/Perl&quot;&gt;Perl&lt;/a&gt;.  Like the others it
    allows you to put simple commands on the command line -- with &lt;em&gt;exactly
    the same syntax as grep and awk&lt;/em&gt;.

&lt;p&gt; Perl&apos;s operations for searching and substituting text look just like the
    ones in &lt;code&gt;sed&lt;/code&gt; and &lt;code&gt;grep&lt;/code&gt;.  It has associative arrays
    (basically lookup tables) just like the ones in &lt;code&gt;awk&lt;/code&gt;.  It can
    run programs and get their results exactly the way &lt;code&gt;sh&lt;/code&gt; does,
    by enclosing them in backtick characters (`...` -- originally meant to be
    used as left single quotes), and it can easily read lines out of files,
    mess with them, and write them out.  It has has objects, methods, and
    (more or less) first-class functions.  And just like &lt;code&gt;find&lt;/code&gt; and
    the Unix command line, it has a well-earned reputation for scripts that
    are obscure and hard to read.

&lt;p&gt; You&apos;ve probably heard &lt;a href=&quot;https://en.wikipedia.org/wiki/Python_(programming_language)&quot;&gt;Python&lt;/a&gt; mentioned.  It was designed by Guido van Rossum in an attempt
    to be a better scripting language Perl, with an emphasis on making
    programs more readable, easier to write, and easier to maintain.  He
    succeeded.  At this point Python has mostly replaced Perl as the most
    popular scripting language, in addition to being a good first language for
    learning programming.  (Which is the &lt;em&gt;best&lt;/em&gt; language for learning
    is a subject guaranteed to invoke strong opinions and heated discussions;
    I&apos;ll avoid it for now.)  I avoided Python for many years, but I&apos;m finally
    learning it and finding it much better than I expected.

&lt;h3&gt;Extension languages&lt;/h3&gt;

&lt;p&gt; The other major kind of scripting is done to extend a program that
    &lt;em&gt;isn&apos;t&lt;/em&gt; a shell.  In most cases this will be an interactive program
    like an editor, but it doesn&apos;t have to be.  Extensions of this sort may 
    also be called &quot;plugins&quot;.

&lt;p&gt; Extension languages are usually small, simple, and interpreted, because
    nobody wants their text editor (for example) to include something as large
    and complex as a compiler when its main purpose is defining keyboard
    shortcuts.  There&apos;s an exception to this -- sometimes when a program is
    written in a compiled language, the same language may be used for
    extensions.  In that case the extensions have to be compiled in, which is
    usually inconvenient, but they can be particularly powerful.  I&apos;ve already
    written about one such case -- the &lt;a href=&quot;https://mdlbear.dreamwidth.org/tag/xmonad&quot;&gt;Xmonad&lt;/a&gt; window
    manager, which is written and configured in Haskell. 

&lt;p&gt; Everyone these days has at least heard of &lt;a href=&quot;https://en.wikipedia.org/wiki/JavaScript&quot;&gt;JavaScript&lt;/a&gt;, which is
    the scripting language used in web pages.  Like most scripting languages,
    JavaScript has escaped from its enclosure in the browser and run wild, to
    the point where text editors, whole web browsers, web &lt;em&gt;servers&lt;/em&gt;,
    and so on are built in it.

&lt;p&gt; Other popular extension languages include various kinds of Lisp, &lt;a href=&quot;https://en.wikipedia.org/wiki/Tcl&quot;&gt;Tcl&lt;/a&gt;, and
    &lt;a href=&quot;https://en.wikipedia.org/wiki/Lua_(programming_language)&quot;&gt;Lua&lt;/a&gt;.  Lua and Tcl were explicitly designed to be embedded in
    programs.  Lua is particularly popular in games, although it has recently
    turned up in other places, including the TeX typesetting system.

&lt;p&gt; Lisp is an interesting case -- probably its earliest use as an extension
    language was in the Emacs text editor, which is almost entirely written in
    it.  (To the point where many people say that it&apos;s a very good Lisp
    interpretor, but it needs a better text editor.  I&apos;m not one of them:  I&apos;m
    passionately fond of Emacs, and I&apos;ll write about it at greater length
    later on.)  Because of its radically simple structure, Lisp is
    particularly easy to write an interpretor for.  Emacs isn&apos;t the only
    example; there are Lisp variants in the Audacity audio workstation and the
    Autodesk CAD program.  I used the one in Audacity for the sound effects in
    my computer/horror crossover song &lt;a href=&quot;https://steve.savitzky.net/Songs/vampire/&quot;&gt;&quot;Vampire Megabyte&quot;&lt;/a&gt;.

&lt;p&gt; Emacs, Atom (a text editor written in JavaScript), and Xmonad are good
    examples of interactive programs where the same language is used for
    (most, if not all, of) the implementation as well as for the configuration
    files and the extensions.  The boundaries can get very fuzzy in cases like
    that; as a Mandelbear I find that particularly appealing.

&lt;p&gt; &lt;em&gt;Another fine post from
    &lt;a href=&quot;https://mdlbear.dreamwidth.org/tag/curmudgeon&quot;&gt;The Computer Curmudgeon&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;img src=&quot;https://www.dreamwidth.org/tools/commentcount?user=mdlbear&amp;ditemid=1631872&quot; width=&quot;30&quot; height=&quot;12&quot; alt=&quot;comment count unavailable&quot; style=&quot;vertical-align: middle;&quot;/&gt; comments</description>
  <comments>https://mdlbear.dreamwidth.org/1631872.html</comments>
  <category>computers</category>
  <category>scripting</category>
  <category>languages</category>
  <category>curmudgeon</category>
  <category>programming</category>
  <lj:mood>didactic</lj:mood>
  <lj:security>public</lj:security>
  <lj:reply-count>9</lj:reply-count>
</item>
</channel>
</rss>
