Freestyle Development

As an older gentle-person, I’ve seen the marketing change over time for describing what computer programmers do. When I was child it was Rapid Application Development or RAD. I think this is best term. I like the “extreme” sports nature of it and it fits with the title of this post.

Agile is a modern software development methodology emphasizing adaptive planning, evolutionary development, early delivery, and continuous improvement. It promotes flexible responses to change and collaboration among self-organizing cross-functional teams.

Agile is perhaps the single biggest contributor to shit code-bases and jaded work-forces. 2-week sprints are hilariously impotent. Especially when you have 6 meetings between sprints and your management-chain infects the process daily. They just yap and you gotta drink it.

Short-term gains become long-term losses as you churn on things that matter to no one but the guy managing the jira/kanban board. But, by all means, keep doing it. It will give me time to catch up.

Because everything is planned and binned in ~2 week sprints, and everyone is RUNNING, nobody stops to smell the flowers. Stopping to think and say, “hey maybe this is architecturally wrong.” There is no time to fix systemic issues in an agile environment. You do look like you are working really hard though and getting it done!

You keep marching towards a false goal and you can’t stop!

Agile is a management technique, not an engineering technique.

Waterfall

Agile was sold as the solution to waterfall. Waterfall is the traditional approach of planning everything out and then after a Critical Design Review (CDR) you then begin to “cut metal” or type code. I believe this approach is still superior because it forces people to think about the entire journey. Not just where they will fill up for gas next.

Agile is a hedge for management that won’t/can’t specify up front what they want/need, because often they don’t know. Only develop what you need as you need it. It would probably work if everything in software wasn’t connected.

While remodeling a house, there is no way that hanging a picture or painting a wall can cause the light-switch to now not only turn on the light, but now it flushes the toilet as well

Scrum

When a word comes from a sport like Rugby. What do you expect this process to look like? It is a giant clusterfuck. All these yappers talking about coding and project management. They are distracting you!

There is no clean code, there is no silver bullet. Work hard, pay attention, ITERATE!

MVP

The Minimum Viable Product is the only thing that Agile may be good for. Thrash, Thrash, Thrash and get something going. But a stable mature “Product” should never probably never use agile. I may die on this hill. Fail as fast as you can and build MVP in a sprint. But don’t ever call it Agile, it isn’t!

Companies / Software Ruined by Agile:

  • Excel
  • … now accepting submissions in comments

please help me fix this article into a coherent rant instead of an old man yelling at the clouds 🙂

Freestyle development is when you just have a blank text file and an idea, and you go make something out of nothing. This is the way to get started to make dreams into reality.

Further Reading

(OOPs) I Made a Class

I learned to program in the 1990s when terms like Object Oriented Programming (OOP) and Rapid Application Development (RAD) were where people thought the future was headed. The exact way I “learned” C++ was through a yellow “learn c++ in 24 hours”

I guess I got the title wrong, it was yellow for sure:

I quit programming after about 3-4 months with this book. I remember they taught OOP through making terminal GUIs for DOS. I went back to Photoshop4 and decided I wasn’t smart enough.

Perhaps teaching OOP to a BASIC programmer with mid 90s C++ is what ruined me.

Main Topic

Leaving behind the baggage, let’s discuss what Object Oriented Programming is:

Objects are like people. They’re living, breathing things that have knowledge inside them about how to do things and have memory inside them so they can remember things. And rather than interacting with them at a very low level, you interact with them at a very high level of abstraction, like we’re doing right here

Steve Jobs ’94 Rolling Stone

I tell you what, that sounds great, but also terrifying. I think his quote actually shows a deep understanding of what Objects or “Classes” are in and the consequences in OOP.

Functions

Lets look at my Ray Tracer Challenge starting point for primitives:

import math

EPSILON = 1e-6 # [0-1] - grid size or fidelity (smaller is, is smaller)

tuple4 = tuple[float,float,float,float] #vector t[3]=0, point t[3]=1

# this can be replaced with math.isclose()
def float_is_equal(a:float, b:float, eps=EPSILON)->bool:
    return math.fabs(a-b) < eps
    
def tuple_is_equal(a:tuple4, b:tuple4, eps=EPSILON)->bool:
    return \
        float_is_equal(a[0], b[0], eps) and \
        float_is_equal(a[1], b[1], eps) and \
        float_is_equal(a[2], b[2], eps) and \
        float_is_equal(a[3], b[3], eps)

def tuple_neg(a:tuple4)->tuple4:
    return (-a[0], -a[1], -a[2], -a[3])

def tuple_add(a:tuple4,b:tuple4)->tuple4:
    return (a[0]+b[0], a[1]+b[1], a[2]+b[2], a[3]+b[3])

def tuple_sub(a:tuple4,b:tuple4)->tuple4:
    return (a[0]-b[0], a[1]-b[1], a[2]-b[2], a[3]-b[3])

def tuple_is_point(tuple:tuple4)->bool:
    return int(tuple[-1]) == 1 

def get_vector(x:float,y:float,z:float)->tuple4:
    return (x,y,z,0)

def get_point(x:float,y:float,z:float)->tuple4:
    return (x,y,z,1)

Ok lets try and use this:

Its not bad, but when we start adding more features to tuple it may become harder for a reasonable person to clearly see how to use this Application Programming Interface (API) for your tuple4 type.

Towards an Object

As you can see when you start down this path, the implementation can get annoying to program against. You could, with a small penalty performance wise*, wrap this functional interface in an object.

Lets motivate this a bit by looking at this code here:

import prim1 as pr
import canvas_io as cvi

ball_pos = pr.get_point(1,1,0)
#ball_vel = pr.tuple_norm(pr.tuple_mul_scale(pr.get_vector(1,1,0), 1.25))
ball_vel = pr.get_vector(15,15,0)

env_gravity = pr.get_vector(0,-1,0)
#env_wind = pr.get_vector(-0.01,0,0)
env_wind = pr.get_vector(0,0,0)

def tick(ball_pos, ball_vel, env_gravity, env_wind):
    return (pr.tuple_add(ball_pos,ball_vel), pr.tuple_add(pr.tuple_add(ball_vel,env_gravity),env_wind))


def sim(ball_pos, ball_vel, max_iters=1e3):
    pos_t = []
    for t in range(int(max_iters)):
        ball_pos, ball_vel = tick(ball_pos,ball_vel,env_gravity, env_wind)
        pos_t.append(ball_pos)
        if (ball_pos[1] <= 0): 
            print('ball hit ground')
            break

    return pos_t


pos = sim(ball_pos,ball_vel)
canvas = cvi.get_canvas(900,550)
for p in pos:
    x = int(p[0])
    y = int(550-p[1]) #swap y axis
    #y = int(p[1])
    cvi.canvas_write_pixel(canvas, x, y, (1,2,3))

#for i in range(550):
#    cvi.canvas_write_pixel(canvas, 10, i, (0,3,0))

#for i in range(900):
#    cvi.canvas_write_pixel(canvas, i, 10, (0,0,3))

#for i in range(900):
    #cvi.canvas_write_pixel(canvas, i, i, (3,3,3))

cvi.canvas_write_pixel(canvas, 10, 10, (3,0,0))
cvi.canvas_write_pixel(canvas, 899, 539, (3,0,0))

print("writing to disk")
import time
tic = time.perf_counter()
# cvi.canvas_to_ppm(canvas, "ball2.ppm")
toc = time.perf_counter()
#print("done: " + str(toc-tic) + " seconds")

import matplotlib.pyplot as plt
plt.imshow(canvas.swapaxes(0,1))
plt.show()

Python Class

I have something to admit. I looked up how to do everything you are about to see. Take it with grain of salt, and if you have feedback please check form at bottom of post (click title to break out of infinite scroll 🙂

class Tuple4:
    def __init__(self, x:float, y:float, z:float, p:float):
        self.x = x
        self.y = y
        self.z = z
        self.p = p

    def from_tuple4(t4:tuple4):
        return Tuple4(t4[0],t4[1],t4[2],t4[3])
        
    def get_point(x:float, y:float, z:float):
        return Tuple4(x,y,z,1)

    def get_vector(x:float, y:float, z:float):
        return Tuple4(x,y,z,0)
    
    def __repr__(self): #this will give us something nice in jupyter notebook when we eval in place
        return "(" + str(self.x) + ", " + str(self.y) + ", " + str(self.z) + ", " + str(self.p) + ")"
        
    def __eq__(self:Tuple4, other):
        return tuple_is_equal((self.x, self.y, self.z, self.p), (other.x, other.y, other.z, other.p))

    def __add__(self:Tuple4, other):
        if (isinstance(other, Tuple4)):
            return tuple_add((self.x, self.y, self.z, self.p), (other.x, other.y, other.z, other.p))
            

New Usage Pattern

Honestly, we need a part ][ of this post to continue 😉

I’m object oriented out. I ❤ Functions. Teaser for next post (objects are entire programs onto themselves, this can be troublesome)

Jupyter Notebook

sorry about that… some bugs with ipython forbidden. Main github project: https://github.com/robmurrer/pyrtc

The Tool Maker’s Dilemma

A humorous illustration entitled "The Tool Maker's Dilemma" with the main person not so freaked out, replace speech bubbles with nonsense slogans, make it higher resolution if possible, make it appear like an old style 70s poster, and make it more technology based

Programmers love their tools. It can be a fetish. How many tools is too many tools between your software and your customer?

Sometimes having more tools in your toolbox is a hinderance not an asset. Organizational breakdowns. Lost tools. Normally there are a few key tools you always have close by if needed.

As engineers or programmers it is often our bench software: Matlab, python, various editors and programming environments. Everyone loves good tools.

Editors and IDEs

Typing is so important. The speed of thought into your editor, the interface between man and machine. Keyboard shortcuts, specialized editors, beyond qwerty… they all tie you to a configuration. It is not a deal-breaker, but its important to reduce the friction between you and your data entry point. But the more you configure the harder it is to work on another’s system.

Do I have to mention emacs and vim? Yes. These ancient editors require months of training to use effectively and perhaps years to master.

VIM and EMACS fighting in a ring in a hellscape outside in a post-apocalyptic setting with a mortal kombat style

1970s computing was defined by big iron machines or mainframes. Big servers, dumb clients. PDP-10’s main storage was tape machines and TECO was the editor of choice. A single page editor. This was great for editing LISP programs and eventually an Editor of Macros (Emacs) was developed mid-70s. Somehow it is still the preferred editor of many programmers.

On the other end of the editor spectrum was “line editors” which were more attuned to working on teletypes. Teletypes are typewriters with serial links. Could it be over a phone line? Vi is a visual line editor created shortly after Emacs. Its modern version was rebooted in the 1980s as Vim. Again, the editor is still used at large (in 2024) and there is a large key-binding extension/plugin for most Integrated Development Environments (IDEs).

Is it worth it to learn emacs or vim? Yes, but that is my opinion and I wouldn’t suggest learning to ship a product and learn vim at same time. It is a lifestyle change that seems less and less important these days. It’s a fun distraction from real work.

Programming outside of a UNIX environment is largely done in a IDE. Visual Studio being the de-facto standard for C++ development. As opposed to makefiles and shell scripts, the idea of an IDE is everything is in one spot. Editor, Compiler, Debugger. Very convenient, you can setup IDE like features in emacs and vim, you could say emacs is a IDE for LISP. Borland IDEs have a special place in my heart as this is where it all started for me, outside of QBasic of course.

The point I’m trying to make is, you can approximate one with the other. Your customer doesn’t care which IDE or text editor you use. The language, framework, etc is a builder’s artifact. A tool mark.

Custom Keybindings & Hardware

If you listen intently you can hear the crackle of mechanical keyboards chording and creating arpeggiations of clicks echoing. Mechanical Keyboards are nice, but I think if you wanted to become inept on the other peoples machines. Just learn DVORAK or COLMAN instead of QWERTY. Still awaiting learning how to use my ErgoDox.

The command interface or how you move around the file are what I would say splits emacs and vim editors. Modal (vim) vs normal. Let’s leave that for another post. This is all to say the mouse is not the most important tool of a programmer when writing code. Your hands re on your keyboard.

Some people (ahem) have even added a foot pedal for shift or other keyboard strokes.

Vendor Software

On a unix you are almost guaranteed to have a C compiler. I think that is POSIX standard. Your distribution will provide it. Microsoft provides the Visual Studio. One you thing you can do is make these IDEs emulate emacs or vim. I do this for vim in both Visual Studio (Proper) and VS Code. Its pretty close and I get some breakpoints for free. On Linux I’ve heard good things about Qt Creator as an IDE.

You may have other vendors outside of your main development tool kit provided by vendor 1. Every piece of software you add beyond this point is normally business related. Libraries are the most important consideration when writing software in a reasonable amount of time. I would vet your libraries thoroughly and “vendor them in” to your main source control.

Then there is the subscription as a service (SaaS). This means you normally don’t host it yourself. Github is a perfect example of a legit reason to include a SaaS product into your development pipeline. But the real thing here is with a remote service, you run risk to disruptions you have no control over. Sometimes the website goes bankrupt. I would avoid these in your flows if possible.

Of course there is our own customization of your tools on top of this. Configurations, Plugins, Extensions, our own shell scripts. Often it’s the “dotfiles”. These build up over the years.

3 Levels

It is important for you to customize your development environment so that you can build and ship your product to customer. Often these setups can be cumbersome and fragile, but that is ok, the product doesn’t suffer from this directly. Now developer tool fatigue is a real thing. Developer ergonomics are important, but taken to the extreme, turns into a naval gazing exercise.

  • Rolling Stock – Minimum settings changed, As it was intended
  • Custom Setup – Tinkering deeper, voiding warranty
  • Fired or Getting Paid – How many apps/scripts are between you and your product or customer?

I like to roll stock when I can. Just because you CAN customize and extend, doesn’t mean you should. Is it worth it to add this new complication to my codebase?

Fired or Getting Paid? — I think this is an important question, will you create an unmaintainable mess while getting paid and then get fired because the business cannot support the liability you have created, or will you keep it running as best you can and improve the system reliability slowly over time?

endcap

I may or may have not written a kernel extension for windows that maps caps lock to escape. The autohotkey hack wasn’t fast enough. I love the idea of “jig’s” I love making tools, but sometimes it gets me into deep trouble…

AddRoom Code Breakdown for AOL

In a previous post, I teased that I would explain exactly what is happening in what I believe was the most copied function of the AOL Proggie era. Adding the list of people in a chatroom to a list in your program. This is that post. Fire up your BASIC editor and open up your Win32 API manual and follow along.

Let us start with the include from the Win32 API. Visual Basic (VB) is somewhat of an interpreted language, but it has the ability to include function calls to Dynamically Linked Libraries (DLLs) written in C or another system language.

Key Win32 APIs that are imported and used in dos32.bas from various .DLLs

VB “compiles” to P-CODE and then is interpreted by the runtime or virtual machine of sorts. Similar to Java’s JVM and its bytecode. In VB5 there was a native compiler for x86 machine code, but before VB5, and maybe after, you could “decompile” the P-CODE and get actual source of any program. People got upset at this and there was an entire obfuscation scene dedicated to preventing decompiling of VB programs…

Image result for fate x aol
A good programming team

Interacting with AOL by reading dialogs, clicking buttons and other automations was fairly straight forward. The general flow would be: identify the window, studying its hierarchy, find the control, and send it messages.

To do this, even today in 2021, I like to use Patorjk’s Tool for Window Spying, but you could always use spy++.exe included in the tools from Microsoft. Automation of this style is similar to scraping websites now. You are reverse engineering and poking into stuff you normally shouldn’t. With most scriptable apps you have an official API. For progs, you needed to invent your own API or SDK… by essentially inspecting the window “DOM”..

Image result for spy++

Most controls could be read and written too. But there was one control that alluded us. The list of people in the chat room was some type of special control. There was some formatting that would happen and other things that prevented a standard LB_GETTEXT from working.

Image result for aol chat room
TOXIC GAMER BROS – AOL 4.0? Running on Windows 98?

In the earlier Sk8er.bas there was a call to a “311.dll” which took care of the AOL16 bit. But when 3.0 came out, which was 32bit we had to reinvent the wheel. Not sure who wrote the 311.dll, maybe we could decompile it. It probably was reverse engineered… But I know it held something that is similar to the code in question. Food for thought: Why was it in a .dll?

Don’t make globals, always use Option Explicit 🙂

Ok onto the 32 bit version of this code. There are 2 main variants, but they all do the same thing. Tap into the process, read some memory and do some magic.

dos32.bas’s AddRoom Implementation

This dos32.bas was claimed to be completely written from scratch, it was… except for the above bit. Still searching for the original author. There is actually another variant that I saw in alpha32.bas, it is shorter and simpler, but I will focus on the tear down of dos’s copy pasta.

Code Review

1122-1132

  • Turn off error handling with On Error Resume Next (think of it as a blind try/catch on all exceptions and keep on trucking… not great, but hey)
  • Find Chat Room Window, Get Thread and follow to Process ID (seems roundabout way, was there multiple threads in Aol32.exe?)
  • You can see there are old-school postfix variable identifiers, I think this kept code smaller w/ Option Explicit.
  • VB4 straddled both 16bit and 32bit so I am guessing that is why the integers are defined as “long” here at 32 bit. Long to me is 64bit, but 1995…
Some Copy Pasta’d Knowledge. Thanks David!

1133-1137

  • Biggest mistake I think in this entire snippet, Iterating over a list of items while the list can change.
  • It cannot be atomic I guess, we cannot lock it, but it seems very strange to call LB_GETCOUNT every loop iteration.
  • Send message and get the LB_GETITEMDATA, then pad by 24… No idea perhaps that was formatting data? This listbox had embolden and italic modes for enter/leaving.
  • ReadMemory from ScreenName string which is only 4 characters, must be an address/pointer
  • psnHold now holds the value stored at the address stored in ScreenName
Source is Pointer to Address in ScreenName String of 4 Chars so 32bit Addy

1138-1142

  • psnHold now holds an address. Pad Address by 6… again no idea why.
  • Resize ScreenName to 16 characters (largest screen name possible on AOL)
  • Read Memory into ScreenName
  • Last Step: Trim to null character, remember we use c-strings in VB!

Epilog

Wow, we got through it. Still a lot of unanswered questions, but I think we solved most of the important bits. When I originally read this code in the 90s, it blew my mind. I just chalked it up to magic and copy and pasta’d it. It always stuck in the back of my mind though, and after I learned about memory and pointers in college it seemed to make more sense.

I promised myself I would eventually write this post to shed some light on one of the most important years of my life. What lessons are learned while you are having fun and sharing your code with friends. Thank you for reading and remember… If you don’t understand it, you don’t always need to! Copy Pasta!

The War Room

It keeps going…

Cosmic Rays – Extragalactic Objects

Determinism is an important part of computing.

2 + 2 = 4

Knowing that the computation of the above never changes gives the programmer the ability to reason about there machine in a scientific way. Two plus two is always equal to four!

Or is it?

With our molten iron core spinning within the earth, it creates a giant electromagnetic (EM) field that shields the planet. Very high up there, there is a cloud of stuff that is rejected and deflected from entering our atmosphere and ultimately us and our devices.

Mostly sunburn is the only problem coming from the heavens toward us, but there are other things to “look” for as well. Cosmic Rays are really charged particles believed to come from the stars exploding…

 In 1929, Bothe and Kolhörster discovered charged cosmic-ray particles that could penetrate 4.1 cm of gold.

Wikipedia 2020 🙂

So what happens when one of these particles hits a semi-conductor like your RAM, CPU, SWITCH?

Bad stuff. It could flip a bit.

2 + 2 = 5

This could be a problem. Flip the right bit, you have a blue screen of death. Not a big deal to an entertainment device or non-mission critical systems. Very big deal for a self-driving car, or a power plant control and monitoring system.

Shielding can help, but shielding is expensive. I wonder how well those NeXT cubes with the magnesium cases do for shielding.

Lockstep Computing…

When GUIDs Collide

What happens when 2 identifiers or keys collide?  Bad stuff.  Databases originally used integers for their record identifiers.  If you wanted to add a new record you must query or ask database what was the last integer and add one to it.

This is fine in isolation, but what happens if you want to insert a bunch of records into a remote database that you can only connect to once per hour?  Oh and there are multiple users.  You can’t use Integers anymore you must use something like a UUID/GUID.

Globals Unique Identifiers (GUID) or Universally Unique Identifiers provide a “random” 128bit value that looks like the following:

https://sessionlink.herokuapp.com/?id=c42db039-ba38-4ce8-a5c0-c997894bcade

They work great, and once you switch from Integers to GUIDs your database is truly distributed and can be updated on the moon!  They are a bit ugly though.  Also they take a huge amount of storage compared to the 64 bits of an integer.  Data size matters sometimes.  Wait, GUIDs are 128 bits!

But still we have a slight probability of generating or guessing the same ID with the birthday problem.

Screen Shot 2019-10-27 at 6.42.43 AM.png

If you are FAANG then you have to start worrying about stuff like this.  There will be collisions.  What happens if you add another GUID or two, increasing the bits to 512?

So there is still the GUID Soup to consider…  Start putting multiple GUIDs in an URL and it is pretty gross.

Enter CUID, which has some interesting objectives:

Collision-resistant ids optimized for horizontal scaling and binary search lookup performance.

Screen Shot 2019-10-27 at 6.29.57 AM.png

How do they do this?  with a string 25 characters.  Timestamping is critical to its binary search capabilities.  Ordering by timestamp allows the lookup to be logarithmic.  So if you need to find one record in a billion.  It would take about 30 tries to find it.  Sorting is key to speed here.

If you need speed and no creation time privacy CUIDs may be a viable option.  Anonymous systems must never use CUIDs.

Only slightly larger in storage size than a GUID… 25 Characters * 8 Bits/Character = 200 Bits.  Guessing CUIDs I feel would be easier…

Screen Shot 2019-10-27 at 6.50.42 AM.png

I’ll stick with my GUIDs soup for now.

Until Next Time. Happy Merging Distributed Datasets,

Rob

 

P.S. Microsoft trying to brand it, er recapitulate:

Screen Shot 2019-10-27 at 7.12.13 AM.png

Duck Typing

If it walks like a duck and talks like a duck it must be a duck.

Recently I started a project with Pure “Vanilla” Javascript, and it was quick going.  With the React as the starter pack, I had a basic prototype with proof of concept multi-user editing: https://twitter.com/robmurrer/status/1169118440122015744

That was a month ago and I ported it to Typescript which is a superset of Javascript (JS) that “compiles” to JS.  It plays well with React’s JSX becoming TSX.  Tip to cast in Typescript:

 blockchain = await this.state.store.getItem(id) as BlockProps;

To me, having to do the work of a compiler, is maddening and that is why I actually really love Typescript (TS).  Coming from any traditional language it is a nice safety cushion under you.

TS has excellent tooling to enable confident refactors, which is the number one issue with my JS codebase.  Refactoring “blind” in pure JS is nightmare.  Refactoring is by far the most important task, so I’ve gone full TS.  But I can see if you are just learning JS you should absolutely not start with TS.

Start pure Vanilla JS and build something. Then when you get stuck trying to refactor.  Revert and start fresh with TS.  I like the quick rewrite and throwaway approach for rapid prototyping.  JS is the best rapid prototyping environment I’ve ever seen.

Ok on to code… The most important part of an editor is the data the user enters.  You cannot lose it.  We are using the Local Forage package from the folks at Mozilla for the data storage layer.  Under the hood it will use IndexedDB on modern browsers.

Screen Shot 2019-10-21 at 6.59.49 AM.png

Ok so what are we looking at here?  The genesis for the post.  What the heck is Hydrate and Dehydrate?  It’s just the cool term for serialize and deserialize.  I like it. The whole point of these names is to communicate what it is they do.

Update:  Um it writes the data in a format it can send over wire or store in database.

But there is something about naming it what it has been called in the past.  Hence this post.

The tour de force of programming design patterns:

  • Finite State Machine (FSM)
    • React’s fundamental concept
    • Start here!
  • Command Pattern
    • Ahem…
  • Classes
    • Only to hold state!!!
    • Of course React uses inheritance 😀
  • Composite
    • Just a tree, or
    • Now with more Blockchain

I’ll write/link up some more about the above at some point.

Until next time, Happy Coding!

 

Screen Shot 2019-10-21 at 7.38.09 AM

Coded into a Corner

Creating software is easy, creating software that is sustainable to maintain and extend is hard.  There are not many mediums in which the consequences of a simple change or design decision can render the complete system useless.  The way in which the software is built is just as critical as to who is building it.

Honey why is the toilet flushing now when I flip the light switch?

Whoa! Cool! I didn’t realize changing the light bulb would do that.

Poorly designed systems are interconnected in ways that are not necessary.  It is often easier to write the prototype in this manner, but products often need to be refactored to use time tested design patterns.

If you ever find yourself scared to change something or can’t figure out how to add the next killer feature.  It is certainly time you reevaluate what you have and don’t be afraid to delete your code.   You may be surprised how much of it is no longer needed.

More code, more bugs!

Recommended Reading

61iOSX4WNiL._SX404_BO1,204,203,200_.jpg

 

Demo or Die

The amount of information conveyed with a picture is said to be worth a thousand words. What is the information density of a demo?  Pictures, flow arrows, and hand waiving can only get you so far.  Demo or die, or sometimes… demo and die.

5b6af7b0-efd9-4d94-b7d7-3319270f2662.jpg

Don’t you love it when someone in audience gets smart and tries to move you off script… the movie magic ends real quick.

There is something about the medium in which you can poke and paw a slider or a button and have something update in realtime.  It either works or it crashes and burns.  A working demo is the baseline test of competency, but the only problem is can the demo make it to 1.0?  Shipping software is incredibly hard and the history of PowerPoint 1.0 is facinating.

In the early days they had trouble convincing people of what PowerPoint was and what problem it solved.  Their mockups were impeccable.  The amount of planning and discipline of these 1980s software startups is inspiring.  Sweating Bullets is on the must read list for anybody who studies software development.

Suggested Reading

PDF of Sweating Bullets by Robert Gaskins

Screen Shot 2018-05-15 at 9.13.21 PM.png