<?xml version="1.0" encoding="iso-8859-1"?>
<feed version="0.3"
xmlns="http://purl.org/atom/ns#"
xmlns:dc="http://purl.org/dc/elements/1.1/"
>
<title mode="escaped">Knowing and Doing</title>
<link rel="alternate" type="text/html" href="https://www.cs.uni.edu/~wallingf/blog/index.html"/>
<modified>2026-05-31T12:08:04-05:00</modified>
<author>
<name>Eugene Wallingford</name>
<url>https://www.cs.uni.edu/~wallingf/blog/index.html</url>
</author>

<entry>
<title mode="escaped">Work that bypasses apprenticeship produces no apprentice.</title>
<author>
<name>Eugene Wallingford</name>
</author>
<link rel="alternate" type="text/html" href="https://www.cs.uni.edu/~wallingf/blog/archives/monthly/2026-05.html#e2026-05-31T12_08_04.htm"/>
<id>https://www.cs.uni.edu/~wallingf/blog/archives/monthly/2026-05.html#e2026-05-31T12_08_04.htm</id>
<issued>2026-05-31T12:08:04-05:00</issued>
<modified>2026-05-31T12:08:04-05:00</modified>
<created>2026-05-31T12:08:04-05:00</created>
<dc:subject>Computing, Teaching and Learning, Software Development</dc:subject>
<content type="application/xhtml+xml" xml:lang="en" xml:space="preserve" mode="escaped">
<![CDATA[
<p></p><p>
 Courtesy
 <a href="https://www.joanwestenberg.com/how-to-be-inspired-without-copying/">
   Joan Westenberg,
 </a>
 another way in which
 <a href="https://www.cs.uni.edu/~wallingf/blog/archives/monthly/2026-05.html#e2026-05-24T11_57_36.htm">
   outputs are not enough:
 </a>
</p><p>
<blockquote style="border-left: 3px solid lightblue; padding: 10px 0 10px 15px; font-style: italic;">
 Bach copied Vivaldi for years before the Brandenburgs.  Picasso
 painted in classical mode for two decades before cubism.  Joni
 Mitchell played other people's standards in coffee houses for
 years before <b>Blue</b>.  Hunter Thompson typed out <b>The
 Great Gatsby</b> and then spent fifteen years writing journalism
 that no one could ever mistake for Fitzgerald.
 <br><br>
 These are long, long stretches of work that looked, from outside,
 like nothing was happening.  Inside, the inputs were being broken
 down into their components, sorted, and rebuilt as something the
 practitioner could call their own.   The temptation, especially
 now, is to skip this phase by trusting a model to deliver the
 surface without the years.  That temptation should be refused for
 the same reason a virtuoso refuses to lip-sync: the work that
 bypasses the apprenticeship produces no apprentice, only an
 output.  And an output is not enough.
</blockquote>
</p><p>
 When we train a model, the inputs are broken down into their
 components, sorted, and rebuilt as the model.  That process
 doesn't change us, though.  The model's output is just another
 input for us to consider.
</p><p>
 Several colleagues and former students have told me that LLMs
 have helped them learn a new area more quickly than they might
 otherwise have been able.  One element common to all their
 stories is that they have deep background knowledge they can
 use as they process the new information.  Another is the time
 and energy they spend processing the new information, engaging
 with it &mdash; and with more reliable sources &mdash; in ways
 that successful learners always do.
</p><p>
 Our new tools may lead to more personalized education, but they
 will not eliminate the need to do the work.</p>
]]>
</content>

</entry>
<entry>
<title mode="escaped">Deep learning learns the outputs.  It does not learn the program.</title>
<author>
<name>Eugene Wallingford</name>
</author>
<link rel="alternate" type="text/html" href="https://www.cs.uni.edu/~wallingf/blog/archives/monthly/2026-05.html#e2026-05-24T11_57_36.htm"/>
<id>https://www.cs.uni.edu/~wallingf/blog/archives/monthly/2026-05.html#e2026-05-24T11_57_36.htm</id>
<issued>2026-05-24T11:57:36-05:00</issued>
<modified>2026-05-24T11:57:36-05:00</modified>
<created>2026-05-24T11:57:36-05:00</created>
<dc:subject>Computing, Software Development</dc:subject>
<content type="application/xhtml+xml" xml:lang="en" xml:space="preserve" mode="escaped">
<![CDATA[
<p><blockquote style="border-left: 3px solid lightblue; padding: 10px 0 10px 15px; font-style: italic;">
  But Shannon entropy and Kolmogorov complexity are measuring
  fundamentally different things.  Shannon entropy measures
  the statistics of outputs.  Kolmogorov complexity measures
  the structure of the generating process &mdash; the program,
  the mechanism, the cause.
</blockquote>
</p><p>
 Deep learning learns the outputs.  It does not learn the program.
</p><p>
 The quoted passage is from
 <a href="https://medium.com/@vishalmisra/shannon-got-ai-this-far-kolmogorov-shows-where-it-stops-c81825f89ca0">
   Shannon Got AI This Far.  Kolmogorov Shows Where It Stops.
 </a>
 It explains &mdash; better and more completely than I've ever
 articulated to myself &mdash; why neural networks and
 statistical approaches have never appealed to me.
</p><p>
 Even back in the late 1980s and early 1990s, these systems
 could be very good at producing answers.  Today's LLMs
 operate at a new level and really do produce amazing outputs.
</p><p>
 But even at their most impressive, they interest me only as
 a possible substrate for something more.  The results are
 cool, but they don't answer the question that motivates me:
 What's the program?
</p><p>
 One thing I like about the Shannon/Kolmogorov article is
 that it does a reasonable job of describing how the current
 statistical models, despite their limitations, might help
 scientists and creators:  These systems may well be useful
 tools for humans operating at higher rungs on Judea Pearl's
 ladder of causation.  In doing so, they will magnify the
 abilities of those humans best able to operate at the higher
 rungs &mdash; and especially those able to move with some
 facility among the rungs.
</p><p>
 I'd still rather work with other humans myself.</p>
]]>
</content>

</entry>
<entry>
<title mode="escaped">Are You a Shipbuilder?  Or a Writer?</title>
<author>
<name>Eugene Wallingford</name>
</author>
<link rel="alternate" type="text/html" href="https://www.cs.uni.edu/~wallingf/blog/archives/monthly/2026-05.html#e2026-05-19T20_46_31.htm"/>
<id>https://www.cs.uni.edu/~wallingf/blog/archives/monthly/2026-05.html#e2026-05-19T20_46_31.htm</id>
<issued>2026-05-19T20:46:31-05:00</issued>
<modified>2026-05-19T20:46:31-05:00</modified>
<created>2026-05-19T20:46:31-05:00</created>
<dc:subject>General</dc:subject>
<content type="application/xhtml+xml" xml:lang="en" xml:space="preserve" mode="escaped">
<![CDATA[
<p> Here are two passages from
 <a href="https://thecreativeindependent.com/people/henry-rollins-on-defining-success/">
   an old conversation with musician Henry Rollins
 </a>
 about writing and creating that stood out to me as I wrap
 up another year of teaching:
</p><p>
<blockquote style="border-left: 3px solid lightblue; padding: 10px 0 10px 15px; font-style: italic;">
  I'm a shipbuilder.  I don't want to sail in them.  I want you
  to sail in them.  I'm just happy that they leave the harbor
  so I can have an empty workplace.
</blockquote>
</p><p>
 And:
</p><p>
<blockquote style="border-left: 3px solid lightblue; padding: 10px 0 10px 15px; font-style: italic;">
  That hesitation, that's what holds a lot of people back.
  That's why I never say, "I'm a writer," because I don't
  want to shoulder that.  I just want to do some writing.
  "What would a writer do in this situation?" I don't
  know, man.  Ask one.  And don't tell me what he said,
  I'm busy.
</blockquote>
</p><p>
 Hat tip to Jen Myers, who quoted yet another blunt passage in
 <a href="https://jenmyers.net/notes/recently/recently-15-may.html">
   her recent newsletter,
 </a>
 along with this piece of advice, "Sometimes, you just need Henry
 Rollins to set you straight, you know?"</p>
]]>
</content>

</entry>
<entry>
<title mode="escaped">This and That, January 28 Edition</title>
<author>
<name>Eugene Wallingford</name>
</author>
<link rel="alternate" type="text/html" href="https://www.cs.uni.edu/~wallingf/blog/archives/monthly/2026-01.html#e2026-01-28T18_56_56.htm"/>
<id>https://www.cs.uni.edu/~wallingf/blog/archives/monthly/2026-01.html#e2026-01-28T18_56_56.htm</id>
<issued>2026-01-28T18:56:56-05:00</issued>
<modified>2026-01-28T18:56:56-05:00</modified>
<created>2026-01-28T18:56:56-05:00</created>
<dc:subject>Computing, Teaching and Learning, General</dc:subject>
<content type="application/xhtml+xml" xml:lang="en" xml:space="preserve" mode="escaped">
<![CDATA[
<p></p><p>
 I need to write titles that distinguish This and That posts,
 so here you have the January 28 edition.
</p><p>
 <b>It's Books</b>
</p><p>
 A delightful paragraph from
 <a href="https://helloruby.substack.com/p/no-114-its-books-darling-gingerbread">
   Linda Liukas:
 </a>
</p><p>
 <blockquote style="border-left: 3px solid lightblue; padding: 10px 0 10px 15px; font-style: italic;">
   At Hatchard's I was waiting for B. who had vanished into
   the first and modern editions section.  An older husband
   was already exasperated: <b>I've been calling you several
   times</b>, he sighed down the stairwell.  His wife emerged,
   unbothered, brushing past him: <b>Oh, it's books, darling</b>,
   as if that settled not only the argument but the entire
   question of how to live.
 </blockquote>
</p><p>
 "... as if that settled not only the argument but the entire
 question of how to live."  Beautiful.
</p><p>
 Hat tip
 <a href="https://www.robinsloan.com/newsletters/little-rooms/">
   Robin Sloan.
 </a>
</p><p>
 <b>Money on the Table</b>
</p><p>
 Joan Westenberg in
 <a href="https://www.joanwestenberg.com/why-my-newsletter-costs-2-50/">
   Why My Newsletter Costs $2.50:
 </a>
</p><p>
 <blockquote style="border-left: 3px solid lightblue; padding: 10px 0 10px 15px; font-style: italic;">
   The instinct to leave money on the table in exchange for
   a better relationship with your audience is neither naive
   nor unsophisticated.
 </blockquote>
</p><p>
 Most CS faculty leave money on the table to work with students
 in a way that only colleges and universities offer.
</p><p>
 <b>Way to Sell the Downside</b>
</p><p>
 From Dan Wang's
 <a href="https://danwang.co/2025-letter">
   2025 letter:
 </a>
</p><p>
 <blockquote style="border-left: 3px solid lightblue; padding: 10px 0 10px 15px; font-style: italic;">
   While critics of AI cite the spread of slop and rising power
   bills, AI's architects are more focused on its potential to
   produce surging job losses.  Anthropic chief Dario Amodei
   takes pains to point out that AI could push the unemployment
   rate to 20 percent by eviscerating white-collar work.  I
   wonder whether this message is helping to endear his product
   to the public.
 </blockquote>
</p><p>
 I was glad to see Dan write a 2025 letter after taking a break
 last year to work on his book.  This letter is worth a read, as
 always.  As much as I learn from and think about his writing on
 China and American policy, I really enjoy the parts about books
 and culture more broadly.</p>
]]>
</content>

</entry>
<entry>
<title mode="escaped">This and That</title>
<author>
<name>Eugene Wallingford</name>
</author>
<link rel="alternate" type="text/html" href="https://www.cs.uni.edu/~wallingf/blog/archives/monthly/2026-01.html#e2026-01-11T08_56_17.htm"/>
<id>https://www.cs.uni.edu/~wallingf/blog/archives/monthly/2026-01.html#e2026-01-11T08_56_17.htm</id>
<issued>2026-01-11T08:56:17-05:00</issued>
<modified>2026-01-11T08:56:17-05:00</modified>
<created>2026-01-11T08:56:17-05:00</created>
<dc:subject>Computing, Software Development</dc:subject>
<content type="application/xhtml+xml" xml:lang="en" xml:space="preserve" mode="escaped">
<![CDATA[
<p></p><p>
 A few items from recent weeks...
</p><p>
 <b>Writing Code Is Fun</b>
</p><p>
 David Celis, in
 <a href="https://davidcel.is/articles/writing-code-is-fun">
   a post of the same name:
 </a>
</p><p>
 <blockquote style="border-left: 3px solid lightblue; padding: 10px 0 10px 15px; font-style: italic;">
   When someone's primary job is to figure out and write requirements
   or manage the entities who are actually producing the code, we
   don't usually call that person a software engineer.  We call them
   a product or project manager.
 </blockquote>
</p><p>
 Not, as Celis goes on to say, that there's anything wrong with that.
 But I like to write code.  For that purpose, looking up an answer in
 language documentation or on StackOverflow serves me fine.
</p><p>
 I'm not ready to turn writing code over to an assistant programmer.
 When I do want to work with an assistant, though, I work with a
 student.  I'd rather help a student learn to design and write code
 than help somebody's LLM gather more data.
</p><p>
 <b>Being a Beginner</b>
</p><p>
 Asha Dornfest, in 
 <a href="https://ashadornfest.substack.com/p/you-too-can-be-an-urban-sketcher">
   You, too, can be an urban sketcher:
 </a>
</p><p>
 <blockquote style="border-left: 3px solid lightblue; padding: 10px 0 10px 15px; font-style: italic;">
   <b>There's a spark of aliveness that comes with being a beginner.</b>
   A combo of shock and giddiness when you do something you thought you
   couldn't do.  The intense focus that comes when there's no prior
   experience to fall back on.  The possibility of new and exciting
   things within your grasp, like finding hidden treasure inside your
   house.
 </blockquote>
</p><p>
 Hat tip to
 <a href="https://dimsumthinking.com">
   Daniel Steinberg.
 </a>
</p><p>
 <b>More Confident a Year Ago</b>
</p><p>
 From
 <a href="http://timesofindia.indiatimes.com/articleshow/126121875.cms">
   comments
 </a>
 by an exec at Salesforce:
</p><p>
 <blockquote style="border-left: 3px solid lightblue; padding: 10px 0 10px 15px; font-style: italic;">
   All of us were more confident about large language models a year ago...
 </blockquote>
</p><p>
 This is a Senior Vice President of Product Marketing, talking about
 why Salesforce is rethinking its "heavy reliance on large language
 models after encountering reliability issues".  It turns out that
 "predictable 'deterministic' automation" is more reliable.
</p><p>
 Huh.  It turns out regular old programs do many tasks really well.</p>
]]>
</content>

</entry>
<entry>
<title mode="escaped">My /ai Page</title>
<author>
<name>Eugene Wallingford</name>
</author>
<link rel="alternate" type="text/html" href="https://www.cs.uni.edu/~wallingf/blog/archives/monthly/2025-12.html#e2025-12-30T20_43_11.htm"/>
<id>https://www.cs.uni.edu/~wallingf/blog/archives/monthly/2025-12.html#e2025-12-30T20_43_11.htm</id>
<issued>2025-12-30T20:43:11-05:00</issued>
<modified>2025-12-30T20:43:11-05:00</modified>
<created>2025-12-30T20:43:11-05:00</created>
<dc:subject>Computing, General, Personal</dc:subject>
<content type="application/xhtml+xml" xml:lang="en" xml:space="preserve" mode="escaped">
<![CDATA[
<p></p><p>
 I'm not sure where I first heard about <code>/ai</code> pages.
 Damola Morenikeji may have been the first
 <a href="https://www.bydamo.la/p/ai-manifesto">
   to explain the idea:
 </a>
 generative AI is getting so good that readers won't be able to
 tell if the text they are reading was written by a person or
 generated by an LLM.  One way for a writer to engender trust is
 to be transparent, by linking to a page that tells readers how
 AI is used on the site.
</p><p>
 I ran across
 <a href="https://sive.rs/ai">
   Derek Sivers's <code>/ai</code> page
 </a>
 again recently and decided I would have one, too.
</p><p>
 So, I have created
 <a href="https://www.cs.uni.edu/~wallingf/ai.html">
   <code>https://www.cs.uni.edu/~wallingf/ai.html</code>.
 </a>
</p><p>
 The one-line answer to "How does Eugene use AI on this site?"
 is: not at all, and certainly not on this blog.
</p><p>
 If you see any text here that isn't a quotation of another
 person's work, then I wrote the text myself.  That page
 elaborates a bit on my thinking, but it all boils down to the
 fact that I like to write and don't want to outsource my writing
 to a program.  If I want to have a writing assistant, I'll work
 with a student.
</p><p>
 My <code>/ai</code> page does describe one time I used an LLM as
 part of a research project:
</p><p>
 <blockquote style="border-left: 3px solid lightblue; padding: 10px 0 10px 15px; font-style: italic;">
   I have used large language models (LLMs) in a research
   project with a student.  The student and I worked with a
   prospective author to train an LLM on the public writing
   of a well-known educator from history.  We then queried
   the model to see what the educator might say about some
   modern issues in education and public policy.  For me,
   this is just the sort of project for which LLMs offer a
   potential benefit that would be hard to attain in another
   way.
 </blockquote>
</p><p>
 By the way, this is a really cool project...  I've been meaning
 to write more about it here, but it's not ready yet for public
 exposure.  Besides, I'm sensitive to the externalities imposed
 on creators and on the environment by VC-backed generative AI
 systems, so I'm reluctant to promote their use any more than
 the current AI bubble is promoting them.
</p><p>
 Anyway, I have an <code>/ai</code> page now.  I doubt my stance
 on generative AI is likely to change significantly in the future.
 I like to write, I like to program, and I like for the presence
 of my name on a piece of work to reflect my personal investment
 in that work.  If that changes, I will update the page.</p>
]]>
</content>

</entry>
<entry>
<title mode="escaped">&quot;Source code is the literature of computer scientists.&quot;</title>
<author>
<name>Eugene Wallingford</name>
</author>
<link rel="alternate" type="text/html" href="https://www.cs.uni.edu/~wallingf/blog/archives/monthly/2025-12.html#e2025-12-26T18_28_37.htm"/>
<id>https://www.cs.uni.edu/~wallingf/blog/archives/monthly/2025-12.html#e2025-12-26T18_28_37.htm</id>
<issued>2025-12-26T18:28:37-05:00</issued>
<modified>2025-12-26T18:28:37-05:00</modified>
<created>2025-12-26T18:28:37-05:00</created>
<dc:subject>Computing, Teaching and Learning, Personal</dc:subject>
<content type="application/xhtml+xml" xml:lang="en" xml:space="preserve" mode="escaped">
<![CDATA[
<p> Recently, a link to the 2013 Computer History Museum article
 <a href="https://computerhistory.org/blog/adobe-photoshop-source-code/">
   Adobe Photoshop Source Code
 </a>
 was going around my social media feed.
</p><p>
 <blockquote style="border-left: 3px solid lightblue; padding: 10px 0 10px 15px; font-style: italic;">
   That first version of Photoshop was written primarily in
   Pascal for the Apple Macintosh, with some machine language
   for the underlying Motorola 68000 microprocessor where
   execution efficiency was important.  It wasn't the effort
   of a huge team.  Thomas said, "For version 1, I was the
   only engineer, and for version 2, we had two engineers."
   While Thomas worked on the base application program, John
   wrote many of the image-processing plug-ins.
 </blockquote>
</p><p>
 I'm not sure why a 12-year-old article about a 35-year-old
 software application popped back into everyone's attention,
 but it brought back good memories for me.  My history with
 Photoshop does not go all the way back to the beginning of
 Photoshop, but it does go back to my beginning as a faculty
 member.
</p><p>
 In 1992, I started as a brand-new assistant professor.  A
 colleague worked with me to set up my office and lab computing
 equipment: a Macintosh Quadra 950, a massive Apple display (*),
 and a bunch of complementary hardware and software, including
 a flatbed scanner from LaCie, OmniPage OCR software &mdash;
 and Photoshop.  I felt like I was living in the future.
</p><p>
 (*) This display got warm... really warm.  One day that year,
 I was down the hall teaching an AI lab section when we all
 smelled burning wire.  My display had spontaneously combusted.
 Fortunately, we turned it off soon enough to avoid setting off
 the alarm and inviting a visit from the fire department.
</p><p>
 With permission from Adobe, the Computer History Museum provides
 access to the source code of Photoshop 1.0.1 from 1990:
</p><p>
 <blockquote style="border-left: 3px solid lightblue; padding: 10px 0 10px 15px; font-style: italic;">
   All the code is here with the exception of the MacApp
   applications library that was licensed from Apple.  There
   are 179 files in the zipped folder, comprising about
   128,000 lines of mostly uncommented but well-structured
   code.  By line count, about 75% of the code is in Pascal,
   about 15% is in 68000 assembler language, and the rest is
   data of various sorts.
 </blockquote>
</p><p>
 Pascal &mdash; another connection to 1992 Eugene.
</p><p>
 That first semester as a prof, I taught Pascal in our intro
 course, something I did again for the next couple of years.
 I had fun.  Teaching programmers to beginners is a challenge
 that rewards you every time the light goes on in a student's
 eyes.  Besides, Pascal had become one of my go-to languages
 halfway through my undergrad years, and I loved writing Pascal
 programs every day.  It remains a favorite to this day, though
 I haven't written any Pascal in many, many years.
</p><p>
 In the coming year, I intend to dive into the Photoshop source
 and see what I can learn from it.  I like reading source code.
 This line from the CHM article says it all:
</p><p>
 <b>Software source code is the literature of computer scientists,
 and it deserves to be studied and appreciated.</b></p>
]]>
</content>

</entry>
<entry>
<title mode="escaped">A Brave New World in the College Classroom</title>
<author>
<name>Eugene Wallingford</name>
</author>
<link rel="alternate" type="text/html" href="https://www.cs.uni.edu/~wallingf/blog/archives/monthly/2025-12.html#e2025-12-16T19_41_30.htm"/>
<id>https://www.cs.uni.edu/~wallingf/blog/archives/monthly/2025-12.html#e2025-12-16T19_41_30.htm</id>
<issued>2025-12-16T19:41:30-05:00</issued>
<modified>2025-12-16T19:41:30-05:00</modified>
<created>2025-12-16T19:41:30-05:00</created>
<dc:subject>Teaching and Learning, Personal</dc:subject>
<content type="application/xhtml+xml" xml:lang="en" xml:space="preserve" mode="escaped">
<![CDATA[
<p> ... or, "How a Pair of Smart Glasses Jogged My Memory"
</p><p>
 Earlier today, a student in my department tried to take a final exam
 while wearing Ray-Ban Meta smart glasses.  Fortunately, the prof
 noticed.
</p><p>
 Now we get to monitor our students' eyewear.
 <a href="https://mastodon.social/@wallingf/115731407319511996">
   Good times.
 </a>
</p><p>
 We now range from students who can't afford to buy textbooks in their
 effort to learn, to kids who can afford to buy smart glasses in their
 effort not to.
</p><p>
 As someone
 <a href="https://mastodon.social/@chillicampari@layer8.space/115731521388315570">
   commented
 </a>
 on Mastodon,
 
 <blockquote style="border-left: 3px solid lightblue; padding: 10px 0 10px 15px; font-style: italic;">
   the thing that really sucks is that smart glasses ... can help with
   accessibility and have very valid use cases, but they are already
   so misused that any wearing of them is suspect now.
 </blockquote>
</p><p>
 Likewise, LLMs may also have a valid use in support of student learning
 (*), but right now their dominant use among students seems to be as the
 sort of crutch that inhibits learning &mdash; which accounts for the
 desperation come exam time.
</p><p>
 <span style="font-style: italic; font-size: smaller;">
   (*) modulo their negative externalities, of course
 </span>
</p><p>
 Unfortunately, a student who does not confront their lack of learning
 until exam time, even if only by being unable to perform, generally
 ends up paying a steep price.
</p><p>
 After all these years teaching, I have a lot of sympathy for students
 who feel desperate enough to cheat.  Yes, they put themselves in a
 bad position, often after their instructor has made a significant
 effort to inform them about appropriate ways to use technology in
 support of learning and to explain the risks of inappropriate uses.
 And yes, they are accountable for their own behavior.
</p><p>
 Still, a part of me thinks of the adage, "There but for grace of God
 go I..."
</p><p>
 The year is fourth grade; I am taking a science test.  I want to say
 that the test was on
 <a href="https://en.wikipedia.org/wiki/Simple_machine">
   the six simple machines,
 </a>
 but it might have been on a biology topic.  At this great distance,
 memory is unreliable...
</p><p>
 In any case, I forgot one item from a list.  Either I knew that I was
 underprepared for the exam, or I had simply rushed in the moments
 before it started, because my science notebook was open on top of the
 pile of papers inside my flip-top desk.  I opened my desk, saw the
 list, and filled in the final answer.
</p><p>
 The teacher noticed.
</p><p>
 Mrs. Bell came to my desk, looked at my paper, and asked what had had
 happened.  I told the truth.  She shook her head and told me she was
 disappointed in me.
</p><p>
 That was like a dagger.  I was the sort of student who wanted to
 please all authority figures.  But this wasn't me disappointing just
 any teacher.  I loved Mrs. Bell.  She remains to this day my all-time
 favorite teacher.  She was a huge influence on me.
</p><p>
 (Here's another memory: I remember once saying to Mrs. Bell something
 like, "I don't know if I'll go to college."  She smiled and said,
 "Eugene, college was invented for people like you."  From that moment
 forward, I never doubted my educational future.)
</p><p>
 Anyway: I don't recall what else she did or said in that moment.  Did
 she dock me points?  Make me take a new test?  I don't even know if she
 told my parents, but I don't think so.  If she did, they never said
 anything about.  They, like Mrs. Bell, knew me well enough to know how
 I embarrassed I was by doing something so wrong and, yes, being caught.
</p><p>
 Whatever else she did or said, I remember her calm demeanor and her
 personal response to me.
</p><p>
 The cost of failing a test in the fourth grade is significantly less
 than the cost of failing a final exam in college, or of failing a
 course.  So, I may have been saved from paying a much steeper price
 later by succumbing to a temptation much earlier and paying the price
 then.  I was also saved by a generous and loving teacher who knew just
 how to respond to the particular student in front of her at that moment.
 What she did and how she treated me obviously made an impression.
</p><p>
 I can only hope that my colleagues and I have the wherewithal to
 respond in such situations in a way that both holds our students
 accountable (yes, that's important) and helps them learn from what
 could be a traumatic experience.  Unfortunately, I think we are going
 to have plenty of opportunities.</p>
]]>
</content>

</entry>
<entry>
<title mode="escaped">Fizzbuzz, Functional Style</title>
<author>
<name>Eugene Wallingford</name>
</author>
<link rel="alternate" type="text/html" href="https://www.cs.uni.edu/~wallingf/blog/archives/monthly/2025-11.html#e2025-11-27T20_10_28.htm"/>
<id>https://www.cs.uni.edu/~wallingf/blog/archives/monthly/2025-11.html#e2025-11-27T20_10_28.htm</id>
<issued>2025-11-27T20:10:28-05:00</issued>
<modified>2025-11-27T20:10:28-05:00</modified>
<created>2025-11-27T20:10:28-05:00</created>
<dc:subject>Computing</dc:subject>
<content type="application/xhtml+xml" xml:lang="en" xml:space="preserve" mode="escaped">
<![CDATA[
<p><q>Ask, and ye shall receive.</q>
</p><p>
In
<a href="https://www.cs.uni.edu/~wallingf/blog/archives/monthly/2025-11.html#e2025-11-25T13_33_10.htm">
  yesterday's post,
</a>
I reported on an attempt to solve the classic Fizzbuzz problem
in a functional style.  Near the end of the post, I wrote:
</p><p>
<blockquote style="border-left: 3px solid lightblue; padding: 10px 0 10px 15px; font-style: italic;">
  This solution is fun but feels a little unsatisfactory.
  I'm not as fluent with functional programming as I am with
  OOP.  Perhaps there is a more idiomatic FP way to do this?
  <a href="mailto:wallingf@cs.uni.edu">Let me know.</a>
</blockquote>
</p><p>
Thanks to everyone who responded with ideas and conversation!
</p><p>
<a href="https://w3.cs.jmu.edu/johns8cr">Chris Johnson</a>
offered a couple of different approaches and ended up with
a slick solution that is fully functional: create an array
containing the different values to print, then use cycled
values for Fizz and Buzz to construct an index into the array.
</p><p>
Here's an elegant solution in Haskell, courtesy of Chris:
</p><p>
<pre style="border: 1px solid blue;margin: 10px 100px 10px 0;padding: 10px;">
pick :: (Int, Int, Int) -> String
pick (f, b, n) = [show n, "Fizz", "Buzz", "FizzBuzz"] !! (f + b)
</p><p>
main = do
  let fizzes = cycle [0, 0, 1]
  let buzzes = cycle [0, 0, 0, 0, 2]
  mapM_ putStrLn $ take 30 $ map pick $ zip3 fizzes buzzes [1..]
</pre>
</p><p>
Beautiful.  1 (= 1 + 0), 2 (= 0 + 2), and 3 (= 1 + 2) select
the appropriate word to print in cases divisible by 3 and/or 5,
and 0 (= 0 + 0) selects the number as a default.  Beyond that,
the code is a couple of maps on top of a zip.
</p><p>
This technique reminds me of a similar trick Joe Bergin used
when we ran the Polymorphism Challenge workshop back in 2005,
solving one problem by looking up in an array an object to send
a message to.  I'd completely forgotten that solution until I
saw Chris's!
</p><p>
Racket is not as concise as Haskell for a problem like this, but
a Racket solution is nice, too.
</p><p>
First, here's <code>choose</code>:
</p><p>
<pre style="border: 1px solid blue;margin: 10px 100px 10px 0;padding: 10px;">
(define (choose f b n)
  (let ((answers (vector (number->string n) "Fizz" "Buzz" "FizzBuzz")))
    (vector-ref answers (+ f b))))
</pre>
</p><p>
Then we define the cycles:
</p><p>
<pre style="border: 1px solid blue;margin: 10px 100px 10px 0;padding: 10px;">
(let ((fizzes (cycle '(0 0 1) size))
      (buzzes (cycle '(0 0 0 0 2) size))
      (numbers (range 1 (add1 size))))
  ...)
</pre>
</p><p>
Finally, the code to implement the functional idea is:
</p><p>
<pre style="border: 1px solid blue;margin: 10px 100px 10px 0;padding: 10px;">
(map displayln
     (map (lambda (L) (apply choose L))
          (zip fizzes buzzes numbers)))
</pre>
</p><p>
I have to apply <code>choose</code> to the zipped lists because
Racket doesn't have a destructuring <code>define</code> form.
Of course, Racket is a language for making languages, so we
can create one if we'd like!  I've written a three-place form
hardcoded to handle <code>(define-match (choose (f b n)) ...)</code>,
but I'll have to do some work to generalize it to take lists of
any size.
</p><p>
Thanks again to everyone who wrote in response to my post, and
especially to Chris for the fine solution.  Readers of this blog
continue to teach me new things.  I hope they find some value in
my posts, all too rare these days.  In any case, I have much to
be thankful for on this Thanksgiving Day.</p>
]]>
</content>

</entry>
<entry>
<title mode="escaped">A Polymorphism Challenge, Functional Programming Style</title>
<author>
<name>Eugene Wallingford</name>
</author>
<link rel="alternate" type="text/html" href="https://www.cs.uni.edu/~wallingf/blog/archives/monthly/2025-11.html#e2025-11-25T13_33_10.htm"/>
<id>https://www.cs.uni.edu/~wallingf/blog/archives/monthly/2025-11.html#e2025-11-25T13_33_10.htm</id>
<issued>2025-11-25T13:33:10-05:00</issued>
<modified>2025-11-25T13:33:10-05:00</modified>
<created>2025-11-25T13:33:10-05:00</created>
<dc:subject>Computing</dc:subject>
<content type="application/xhtml+xml" xml:lang="en" xml:space="preserve" mode="escaped">
<![CDATA[
<p><figure style="float:right;margin-left:20px;margin-bottom:15px;">
  <img
    src="http://www.cs.uni.edu/~wallingf/blog-images/computing/fizzbuzz.png"
    width="175"
    style="padding:4px;border:1px solid blue;"
    alt="three numbered lines: 1...15, fizz=3, and buzz=3">
  <figcaption style="font-style:italic;font-size:smaller;margin-top:5px;">
    the Fizzbuzz problem solved<br>in the Fizzbuzz language
  </figcaption>
</figure>
</p><p>
Over the weekend I ran across
<a href="https://evanhahn.com/fizz-buzz-without-conditionals-or-booleans/">
  a blog post by Evan Hahn
</a>
in which he took on this exercise:
</p><p>
<blockquote style="border-left: 3px solid lightblue; padding: 10px 0 10px 15px; font-style: italic;">
  ... write Fizz Buzz with no booleans, no conditionals, no pattern
  matching, or other things that are like <b>disguised booleans</b>.
</blockquote>
</p><p>
Ah, the memories!  In 2005, Joe Bergin and I ran a SIGCSE workshop
called The Polymorphism Challenge, which I mentioned briefly in
<a href="https://www.cs.uni.edu/~wallingf/blog/archives/monthly/2005-02.html#e2005-02-24T15_08_31.htm">
  a trip report
</a>
at the time and reported more fully in
<a href="https://www.cs.uni.edu/~wallingf/blog/archives/monthly/2012-02.html#e2012-02-19T12_17_41.htm">
  a 2012 post.
</a>
The goal of that workshop was to help participants learn how to use
polymorphic objects to solve a variety of standard problems without
relying on <code>if</code> statements to select among different
conditions.  It was great fun, and many of the workshop participants
found it both challenging and enlightening.
</p><p>
Hahn's post gives a functional solution to
<a href="https://en.wikipedia.org/wiki/Fizz_buzz">
  Fizzbuzz
</a>
in Python, using iterators and a creative, though limited, string
mask:
</p><p>
<pre>
from itertools import cycle
</p><p>
def string_mask(a, b):
    return b + a[len(b):]
</p><p>
def main():
    fizz = cycle(["", "", "Fizz"])
    buzz = cycle(["", "", "", "", "Buzz"])
    numbers = range(1, 101)
    for f, b, n in zip(fizz, buzz, numbers):
        print(string_mask(str(n), f + b))
</pre>
</p><p>
I thought, hey, I can do that in Racket:
</p><p>
<pre>
(define string-mask
  (lambda (num-str fb-str)
    (string-append fb-str
                   (guarded-substring num-str
		                      (string-length fb-str)))))
</p><p>
(define fizzbuzz
  (lambda (max)
    (let ((fizz (cycle '("" "" "Fizz") max))
          (buzz (cycle '("" "" "" "" "Buzz") max))
          (numbers (range 1 (add1 max))))
      (for ((f fizz)
            (b buzz)
            (n numbers))
        (displayln (string-mask (number->string n)
                                (string-append f b)))))))
</pre>
</p><p>
Two notes:
</p><p>
<ul>
  <li>
    I wrote my own <code>cycle</code> function.  Racket has a
    <code>sequence-&gt;repeated-generator</code> function in
    <code>racket/generator</code>, which behaves like
    <code>cycle</code> in Python's <code>itertools</code>,
    but I wanted to write a simple <code>for</code> over
    lists.
  </li>
  <li>
    I had to create a substring function that allows the
    start index to be out of bounds.  Racket's native
    <code>substring</code> is more careful than Python's [:].
  </li>
</ul>
</p><p>
The string masking idea is clever, but Hahn points out that it
starts to fail when the number is long enough that the Fizzbuzz
string can't cover it all.
</p><p>
This solution is fun but feels a little unsatisfactory.  I'm
not as fluent with functional programming as I am with OOP.
Perhaps there is a more idiomatic FP way to do this?
<a href="mailto:wallingf@cs.uni.edu">Let me know.</a>
</p><p>
<b>Bonus code:</b>  If you want to see a solution that will melt
your face, check out
<a href="https://code.kx.com/q/learn/reading/fizzbuzz/">
  this article
</a>
implementing Fizzbuzz in the array language Q.  I learned APL
on 1985 or so, and its way of thinking will always have a
strange hold on my brain!
</p><p>
Anyway, that was a nice diversion for a few minutes during
Thanksgiving break.  As I tell my students almost every day in
class, I like to program.  I'm thankful that I am able to do it.</p>
]]>
</content>

</entry>

</feed>
