19 Comments

“his character was in a hotel room and had removed his shoes. But needed to quickly escape out the window. With no mention of grabbing his shoes.”

That’s a big one for me too. This is why I rely on my writing group. And when I think of these types of errors, I do think of them as a sort of video game that needs to be beta tested to make sure the characters don’t start running into walls and glitching.

Expand full comment
author

Heh, yeah, I imagine the better you can imagine your characters doing what they’re doing, the more chance you have of dodging logic errors.

I think programming and authoring suffer from the same issue here that both are creating something new “from the whole cloth”. It’s one thing to write, as I have, about real stuff. You have a reference then. And the way things works is necessarily always logical.

But programs and stories aren’t physical, so there is no necessity to obey physics or logic.

Expand full comment

Ah, but there is the story's physics or rules, which can either be invented or based on reality, and you still have to be consistent about within those parameters. You don't want to have a character who "finishes off a beer" and "takes a sip" from it a moment later. Seems small, but there's always someone out there keeping track.

Expand full comment
author

Yes, exactly the point. The author and programmer are responsible for maintaining the reality of the story, whatever it is. You can easily write that a character just floated away in the wind, and no physical reality rears its head to prevent you from writing that. Just as nothing prevents a programmer from allowing physical objects to intersect in a video game. In the physical world, those things *can't* ever happen.

Expand full comment

Wyrd, you did some fantastic writing there. Well done. Being a total blockhead in programming, I haven't a clue what you said, but it was well written.

Back in the days when I was studying Accounting, I had to take computer programming. Fortran and Cobal. I'm dating myself; I know. PC's weren't on the scene in those days and computers were about the size of a small house. Why I needed to learn how to program one of those monstrosities I will never know! That's what computer programmers did, NOT accountants. Regardless, I studied Fortran until the cows came home! Passed the necessary exams and have never looked at computer programing since then.

Writing I understand. Programing I don't. You, my friend, are talented in both areas.

Well done!

Expand full comment
author

😊 Well, thank you!

Back in the day they thought everyone with any kind of white-collar job was likely to wind up programming computers. At the time languages like COBOL and Fortran seemed poised to liberate office workers from having to wait for a small group of computer programmers to get around to their bullshit. I mean very important task. Office and personal computers were the coming wave of the future, and the assumption was we'd all use them and necessarily need to program them.

Then never envisioned the massive software industry that liberated computer *users* from having to do any programming. A good friend's husband is a commercial artist who has been using Macs in his work since they first came out. His whole litany is that he should only need to know how to use the tools, and Apple has long specialized in that.

It was like the Spanish Inquisition. No one saw it expected it.

Expand full comment

Thank goodness for PC’s. As one who was destined for a more “academic” education path, I had to fight tooth and nail to take “typing” in high school. Typing was for “secretaries.” I saw it different. As long as I had typing skills, I could get a job. Period. Turns out the keyboard has been a lot more valuable to me than the computer programing I took in college.

Just goes to show us how things don’t turn out the way we think they will.

Expand full comment
author

They sure don’t. My parents pushed me to take typing class in high school because I was already writing by then, and they saw it as a useful skill. A decade later, becoming a programmer, boy, was it ever! I knew a lot of coders still stuck in hunt ‘n’ peck.

Expand full comment

I draw a parallel between software libraries and, say, cultural libraries. References to a software library are always explicit. References to a “cultural library” can, and often are, implicit. “Driving into the town was like a journey to Modor.”

The line/sentence analogy is strongest for imperative/noun verb languages. It is less so for declarative languages, like Python in object mode with constructs like rbi.sd. For functional programming, like, say, Haskell, we have come quite far from the line/sentence analogy.

-- Haskell imperative style

-- Define a function to square a number

square :: Num a => a -> a

square x = x * x

-- Define a function to sum a list of numbers

sumList :: Num a => [a] -> a

sumList = foldl (+) 0

-- Define a function to calculate the sum of squares

sumOfSquares :: Num a => [a] -> a

sumOfSquares = sumList . map square

-- Main function to demonstrate usage

main :: IO ()

main = do

let numbers = [1..5]

putStrLn $ "Numbers: " ++ show numbers

putStrLn $ "Sum of squares: " ++ show (sumOfSquares numbers)

## Python imperative style

def square(x):

return x * x

def sum_list(numbers):

total = 0

for num in numbers:

total += num

return total

def sum_of_squares(numbers):

squared_numbers = []

for num in numbers:

squared_numbers.append(square(num))

return sum_list(squared_numbers)

def main():

numbers = list(range(1, 6)) # [1, 2, 3, 4, 5]

result = sum_of_squares(numbers)

print(f"Numbers: {numbers}")

print(f"Sum of squares: {result}")

if __name__ == "__main__":

main()

## Python object oriented style

class Number:

def __init__(self, value):

self.value = value

def square(self):

return Number(self.value ** 2)

class NumberList:

def __init__(self, numbers):

self.numbers = [Number(n) for n in numbers]

def sum(self):

return sum(num.value for num in self.numbers)

def square_all(self):

return NumberList([num.square().value for num in self.numbers])

class SumOfSquaresCalculator:

@staticmethod

def calculate(number_list):

squared_list = number_list.square_all()

return squared_list.sum()

def main():

numbers = [1, 2, 3, 4, 5]

number_list = NumberList(numbers)

result = SumOfSquaresCalculator.calculate(number_list)

print(f"Numbers: {numbers}")

print(f"Sum of squares: {result}")

if __name__ == "__main__":

main()

Expand full comment
author

Your notion of cultural libraries compared to code libraries hits squarely on something I saw only dimly writing the post. I like the notion of metaphors being implicit "import" statements. What did occur to me writing the post is that stories draw on a considerable body of knowledge from the most basic (things fall downwards) to the most topical (Taylor Swift endorsed Kamala Harris shortly after the debate last night). So, we have another good parallel between coding and authoring. Thanks.

I don't know Haskell well enough to try to translate code lines to English lines. Can you illustrate the disconnect you're seeing between Haskell lines and sentences? I'm not sure my Python functional version is an exact match (it is *functionally* 😁), but I think I can map code lines to sentences...

First, a function that takes a number and returns its square. Second, a function that takes a list and uses tail recursion to sum the list elements. Third, a function that takes a list of numbers and maps them to a list of their squares. Then a function with a list of numbers to square generates their squares and prints both lists.

But maybe we're not looking at it the same way. How are you seeing it?

Expand full comment

square :: Num a => a -> a

Any a is a number type that returns the same number type by multiplying it by itself

sumList :: Num a => [a] -> a

Same except a is a number type that operates on a list of a's to return a running total.

sumList = foldl (+) 0

sumOfSquares :: Num a => [a] -> a

Same type restrains as sumList to take a list of a's and take the cumulative sum

main :: IO ()

Specifies the entry and exit points of the program as input/output

main = do

Initiate operations

let numbers = [1..5]

Bind a list one to 5 to "number" The variable numbers is immutable once created

putStrLn $ "Numbers: " ++ show numbers

and

putStrLn $ "Sum of squares: " ++ show (sumOfSquares numbers)

Places output on stdout. Note the first class function usage

The functional style is evident in how each function is a transformation of its input, without modifying any external state.

The functions, except main() are pure.

square :: Num a => a -> a

square x = x * x

sumList :: Num a => [a] -> a

sumList = foldl (+) 0

sumOfSquares :: Num a => [a] -> a

sumOfSquares = sumList . map square

main :: IO ()

main = do

let numbers = [1..5]

putStrLn $ "Numbers: " ++ show numbers

putStrLn $ "Sum of squares: " ++ show (sumOfSquares numbers)

1. Pure Functions:

- square, sumList, and sumOfSquares are all pure functions. They always produce the same output for the same input and have no side effects.

2. Referential Transparency:

- The expressions in these functions can be replaced with their values without changing the program's behavior, which is a key property of pure functions.

3. Immutability:

- All data structures used (like the “numbers” list) are immutable, which supports purity.

4. No Side Effects (in the pure parts):

- The pure functions don't modify any external state, perform I/O, or have any effects other than computing and returning a value.

5. main Function:

- The main function, however, is not pure. It performs I/O operations (putStrLnj which are side effects.

The program as a whole is not entirely pure due to the I/O operations in `main`. However, it's structured in a way that separates the pure computations (square, sumList, sumOfSquares) from the impure I/O operations.

This separation is a common pattern in Haskell and other functional programming languages. It allows most of the program logic to remain pure, with impurity isolated to a small, controlled part of the program (typically main or other I/O functions).

Expand full comment
author

Cool. Are converging on the code line sentence equivalence? You described each line with a sentence. I mean this equivalence only in the weight or volume sense. I'm not drawing any parallels between actual sentences and their grammar with code lines. I'm only claiming the "weight" of one sentence seems roughly equal to the that of one line of code.

Expand full comment

Sorry to be obscure. My point is that functional languages differ in that the orientation is what, rather than how. It’s like saying “do-this, do-that” in the imperative style is like a noun/verb sentence. In pidgin Python:

Here’s a duck, now figure out what kind of duck it is and multiply it by itself. Now take a flock of ducks multiplied that way and add them all up.

In Haskell it more like solve for y where y = f(x) where x and y are members of the set of numbers, x is an immutable list of type number and f is a function such that f(x) = sum(x²_1 … x²_n)

Expand full comment
author

Oh, totally. Very different abstractions between functional, imperative, and object-oriented. To my mind a stronger divide between functional and the other two which really only differ in being, respectively, verb-noun or noun-verb oriented. Functional is a whole other mindset I find challenging. This conversation has dusted off some old Haskell memories -- a little time spent trying to get to know the language.

Expand full comment
author

Hell, yeah. Lotta meat here. And this is one place Substack makes me wince. You can post code okay in a Post or Note, but not in comments. Very annoying sometimes.

I want to chew on your words a bit, but here's this (which Substack will mangle 😡):

# Python functional style

#

square = lambda n:n*n

sumlst = lambda lst:lst[0] if len(lst)==1 else lst[0]+sumlst(lst[1:])

sumsqrs = lambda lst: list(map(square,lst))

def main ():

numbers = [1,2,3,4,5]

squares = sumsqrs(numbers)

print(f'Numbers: {numbers}')

print(f'Sum of squares: {(squares)}')

Expand full comment
Sep 12Liked by Wyrd Smythe

I do both.

There are some similarities: the flow-state you mention is one. The misspelling, punctuation, copy edits that writing represents and the bugs in naming, syntax and copy-pasta glitches in software. As well as the higher level structure concepts of plot, arc, story line vs module and model organization, code reuse and build structures for code.

And /maybe/ the concept of solving problems. Narrative situations are those you intentionally, or perhaps not, write your characters into, knowing they'll have to "solve" them to maintain the story. Code is all about solving problems.

The one area, to me, that doesn't jive is the creative side. Code is directed. There is a definite and often well defined intent behind code. Technical specs, functional specs, TDD, unit tests and integrations tests to prove your solution. Fiction has no rules. In fact, fiction that follows rules is often formulaic. Writing is a wild dance within dazzling landscapes and spontaneous interactions with instantly fabricated ideas, settings and characters. Programming is rigid in comparison.

That rigidity comes with benefits in that, once you're in the know, and you exercise that knowledge in novel ways, the product of a successful execution can feel pretty similar to completing a compelling and whimsical short story.

Fun topic!

Expand full comment
author

You make a good point about the creative side. I wonder if it doesn't follow both from the collaborative nature and that code is information, an abstraction. I've had to rewrite code by a programmer who was too creative and not formulaic enough. Very challenging, so, yeah, huge difference here. And as I said myself, its primary purpose is utilitarian. I think you're right. Programming at best is high craft.

Now here's an interesting thought. It's sometimes said that art flourishes most when most constrained. Finding creative expression within some rigid structure -- Haiku, for instance -- can be its own kind of high art. Or another example, writing posts here on Substack is, in some key ways, primitive compared to writing on WordPress. But that constraint forces one to focus more on the writing and less on the unavailable HTML and wrap-around image tricks.

So, maybe there are small ways within writing code that one can approach artistically? I know that all my OCD gets channeled into the way my code looks and reads. I tend to adopt the "literary coding" approach that says where things are source code -- how you express the algorithm -- should be meaningful. For instance, in my C++ days, anyone who knew my style, knew I always put constructors and destructors at the bottom of the class. Code should read like a letter to someone. (And the Fundamental Rule: Code is for humans.)

High craft with a smidgeon of art?

Expand full comment
Sep 12Liked by Wyrd Smythe

Writing prompts are a form of artificial constraint. Or those 99 word stories and exercises for "a conversation in a park where the world is crumbling around the participants."

Which are rather like coding problems -- design a GET + query that scans a 1M record db, aggregates on X,Y,Z returns the results as JSON and does so < 200 milliseconds.

And as such, such boxes can seem to trigger "creative solutions".

Fiction, for me, however, is more than just prompts or virtual boxed lines in the sand. Sci-Fi & Fantasy -- good versions of each -- can really push the boundaries of what an imagination can contrive.

Sure, I tend to want to constrain my fiction, these days, to the probable/improbable rather than the possible/impossible. I've written plenty of impossible stories and they're fun to dream. They were bound by nothing. Just my thoughts of fantastical situations and beings interacting in impossible ways.

Expand full comment
author

Oh, I quite agree. I recall the SF from the 1980s when authors were trying all sorts of alternate ways of presenting stories. That didn’t take long, fortunately. The ancient way of telling stories just works best.

Expand full comment