Good Ideas 2003

This is a repository of computer software concepts which I feel are truly novel, and yet have not been universally adopted. While I have chosen to highlight those valuable aspects by making reference to existing implementations when possible, the reader is encouraged to consider the novel aspect itself, not the specific implementation.

If you know of good ideas which I don't have listed here, please email them to me at jeske@chat.net [mailto].


OperatingSystems
  Security: 
      VSTa's heirarchial security model - allows you to
        create new protection domains 'below' your own,
        facilitating things such as sandboxing and 
        OS supported virus protection. In VSTa, a browser
        or mail client can create its own lower kernel-level 
        protection (i.e. user.jeske.mail).  Because this
        lower protection level would be made to only have access to
        displaying UI and writing files to the mail directory,
        your system could not be compromised or infected with 
        Viruses through that program.

  Filesystems:
     Netapp's WAFL filesystem. Similar in some ways to
       today's journaled filesystems. However, the design
       fundamentals, coupled with a small amount of NVRAM
       lead to drastically better performance. In WAFL,
       no blocks are ever modified in place. All blocks
       which must be changed are written contigiously to 
       a new area of the disk, and then "linked in" in a
       single atomic step. This allows you to achieve close
       to the streaming write performance of the disk, 
       by always writing new blocks in contigious regions. 
       A small amount of overhead is incurred because you must
       also rewrite all indirect blocks which point to the 
       new datablocks, all the way up to the superblock.


  Networking:
     Exokernel Packet dispatching filters: The MIT Exokernel
       has a novel networking stack design which allows 
       truly-layered protocol handlers, without terrible
       performance penalties. This is achieved by uploading
       small 'packet filtering programs' (written in a 
       custom language so they are safe) into the kernel 
       which can identify packet types and subtypes.
       The kernel merges the filter programs into a single
       'test tree', so that it does not have to repeat
       byte value comparisons. 

Programming Languages:

  String Handling:

     Python's "%" operator: Python introduced '%' as a 
       binary operator on strings. This allows any code to
       easily do sprintf() style formatting in a visually
       compact, yet readable fashion. It has a better
       performance basis than C++'s cout<< overloading, 
       because it's a single function call per format 
       string, not per element added. It also supports named 
       format elements if handed a
       hash-table instead. For Python the trick of keeping
       this a simple binary operator lies in the existance
       of a "tuple" type which holds an arbitrary number of
       elements. For other languages, this would be
       equivilant to an operator with a variable number of
       arguments.
 
         Ex:    "Hey %s, how are you today?" % dave
                "%d rats, %d cats" % (rats,cats)

  Type-Conformance/Interfaces:

     Sather's implicit interface definition: Sather has a 
       unique feature where every class implicitly declares
       an interface with the type of the class. This means
       that you can always write a type-compatible replacement
       for a class which inherits no code. It also removes 
       the odd trouble of people testing for "object is a class"
       when they should be testing for "object implements an
       interface", because the former does not exist.

       In [all] other strong typed programming languages,
       if a library makes use of a certain class, and they
       don't think to declare it as an interface or 
       abstract class, then you are stuck using their
       implementation instead of yours. 

       Of course for this to be truly useful, you need to
       be able to bind in a new version of the class to the
       global class factory, so when the library creates
       a "new" instance, you can provide a different class.
       (see .NET assembly binding)


  Type Binding:

     C/C++ style inherited type context: In the C/C++ days 
       of #include(ing) header files, when a programmer
       #included a library API, that library API in turn
       normally included the headers of its dependencies. 
       This meant that one could include one base object 
       header, and easily make use of all return types and 
       necessary argument types. For example:

         // C++
         #include <HttpFetch>

         void do_fetch(void) {
           HttpFetch aFetch = 
               new HttpFetch(new URL("http://www.yahoo.com/"));
           Stream myResult = 
               aFetch.getResult();
     
           char buf[200];
           int read;

           while (read = myResult.read(buf,199)) {
             buf[read]=0;
             cout << buf; 
             // ...
           }
         }

       Header files have slew of problems which needed to be 
       fixed. However, as modern languages replaced 
       headers with namespaces and module systems,
       somehow the programmer was saddled with the
       extra work of importing not only the module
       he was using, but also all the modules which
       contain arguments and return types he needs
       to use. This makes the import section a chore
       instead of a tool, because (a) the programmer has
       to dig up what modules the return types are
       declared in and (b) it no longer simply explains 
       the root of dependencies for this file. For
       example:

          // Java / C# esq
          import System.Web.Http.HttpFetch;  
          import System.Web.URL; 
          import System.FileIO.Stream; 

          void do_fetch(void) {
           HttpFetch aFetch = 
               new HttpFetch(new URL("http://www.yahoo.com/"));
           Stream myResult = 
               aFetch.getResult();

           print myResult.read();
          }

     Extension of existing (Binary) Classes: Objective-C 
       introduced the concept of loading a set of new 
       methods onto an existing class. This was called 
       'Category-Loading', and it allowed an existing class 
       to be extended. COM nearly provides a similar mechanism 
       through a pattern called Object Aggregation. In this
       pattern, a COM Interface is merged into an  
       existing object, without the implementations being coupled. 
       SELF provided a similar pattern called 'traits' or 'mixins'. 
       Finally, TOM provides an formal extension mechanism 
       whereby you can add or replace method implementations 
       in an existing binary class after the fact.

       This type of aspect provides some of the same features 
       as Multiple Inheritence without many of the drawbacks.

       Aspects like this allow for the useful extension 
       of built-in classes (such as adding a new type of
       string formatter to Strings, or a new method of
       serialization to other objects).

       Aspects like this also allow for a different type of
       code reuse I think of as 'top-half code reuse'.
       Instead of reusing a library in two applications,
       top-half code-reuse is a means by which you repurpose
       an application by giving the library it uses new
       functionality. One powerful means by which you can
       do this is by extending an existing class with a few
       new methods which only need to be called in isolated
       places. This allows your application to function as
       before, and your new methods let the class do new
       things. (such as adding printing functionality to
       your app by adding a .targetTo(printer) method
       to the base View class). In languages without 
       class extension mechanisms, If you do not control
       the source code to the base-classes, and classes
       are being instantiated elsewhere, this type of
       resuse is impossible. Categories, or other
       extensions allow you to extend that classs anyhow.

     .NET Assemblies: In .NET code is provided in the
       form of an Assembly. Each DLL is an Assembly, as 
       is your application itself. The .NET runtime keeps
       track of the types bound to each assembly, so that
       when an assembly instantiates a new object, it
       gets an object of the type bound to that individual
       assembly. This allows more flexible ways for different
       versions of code to live harmoniously together. 
       
       For example, you import a library which internally
       needs to use "v1.0" of "HtmlStringBuilder", but your
       code also needs to use v2.0 of "HtmlStringBuilder".
       As long as you don't need to pass the class across
       the boundary between their code and yours, everything
       works great and nobody is the wiser. In other runtime
       environments (like Java, and in rare cases even in 
       standard UNIX shared library binding) this versioning 
       can become a problem.


  Packaging:

     Nextstep app-wrappers and bundles: Nextstep grouped
       all application datafiles into a single item known 
       as an "app-wrapper". While the wrapper was merely 
       a special directory, this drastically simplified 
       application installation and management. Application
       data was distinctly divivided into (a) non-mutable 
       data-files and libraries supplied inside the 
       wrapper, (b) user preference data which is stored
       through a specific api which abstracts away the
       storage location, and (c) the document datafiles
       for the application.

     Nextstep's passive type-registry: Instead of managing
       a central mime-type registry through application 
       installers, and manual coordination, such as in the
       Windows registry, Nexstep required applications to
       passively export information about mimetypes and
       other exported services. This assured that 
       applications themselves are easily installed, merely
       by copying the application to a new location, and are
       easily uninstalled, by merely deleting the application.
       A central type-registry cache is generated by scanning
       available application wrappers. In this system
       there is no central Windows-registry like database to
       be managed or become out of date. It also means that
       applications are easily relocated by merely copying
       them to a new location, without making them out of date
       with respect to central registry entries.
 
       Sadly, while this scheme provides elegance in
       the new MacOS X, KDE and Gnome have not yet 
       adopted it.

     Java JAR files: Java allows application files to be
       joined together into a single ZIP archive. This
       archive can contain not only code binaries, but also
       a hierarchy of images, sounds, and any other required
       application data. This drastically simplifies the
       distribution of application files, and enforces
       non-mutable application data.



  Run-Time execution Optimization:
   
     SELF's Hotspot VM (later turned into Java's HotSpot VM):
       SELF is a fully weak/dynamic typed language akin to
       Smalltalk in base execution speed. To speed up execution,
       the SELF team developed a dynamic run-time compilation
       and recompilation system which would (a) profile the
       types which actually occur at polymorphic type sites,
       and (b) compile custom versions of method calls which
       were optimized for popular types (with downstream
       code inlined!). 

       Since SELF is a weak typed language like
       Smalltalk, all type sites are polymorphic, and this lead
       to large amounts of memory overhead. However, a similar
       method might be employed on a simpler static/strong
       typed language which would allow all methods to be
       considered virtual, while making code use static jumps
       (instead of indirect jumps) for (a) virtual methods 
       which are not overridden in any loaded classes, or 
       (b) inner-loop call sites where a small number of 
       classes are frequently present.

  Elegance of Expression:

     Aspect Oriented Programming (as in AspectJ for Java):
       Xerox PARC developed a method of keeping code small
       while added whole-program optimization 'aspects' by
       using an AspectWeaver to combine the simple logical
       program with it's whole-program aspects, and output
       the much larger final program code.

       This method seeks to buck the trend that the first
       10% of the work gives you 90% of the solution, while
       the remaining 10% of the solution makes up 90% of
       the work. For example, a simple image processing
       algorithm expressed in scheme might be only 80
       chararacters long. However, to implement an efficient
       version of that algorithm in C with tuned buffer sizes
       and processor specific SIMD instructions, would 
       require far more code. AOP seeks to have those 
       other optimizations expressed just a simply and
       concretely, and let the AspectWeaver do the work
       of weaving together the simple aspects and your 
       simple algorithm into a complex program.

User Interface:

  Folder Navigation:

     'drop folder to go there': Apple Nav Services (OS 8.x) and
       BeOS allowed you to drop a folder icon onto an open or 
       save panel to have the panel go there. This provided 
       a needed bridge between the finder UI and the open/save 
       panel. Without it, saving a document into a folder which 
       you already have open in the finder can be an annoying 
       experience.

     Shelves: Several systems have created intermediate mechanisms 
       for drag-and-drop operations. First you grab the 
       item and drag it to a temporary location, then you
       go find the target, and drop on the target. This prevents
       you from having to open both the source and the target to
       perform a drag-and-drop operation. Sometimes these shelves 
       allow you to locate commonly used items centrally for
       frequent use. Nextstep's filemanager is the best 
       shelf-implemenation I've used. It allowed you
       to drag groups of files or folders onto a 'shelf' area at
       the top of a filemanager window. The Apple newton
       used the side of the screen as a shelf for clipboard
       opeations. IBM's OS/2 allowed you to right-click and 
       'pickup' an object into a single-item shelf attached to
       your pointer. You could navigate around as normal, and then
       finally 'drop' the item you were carrying. Apple's
       edge-of-screen folder docking is another form of shelf.
       in OS 8/9 you can drag a folder to the side of the screen
       where it will become a tab. Clicking or dragging over
       the tab will open the folder.

     Spring loaded folders: MacOS drag-and-drop behavior 
       introduced a method known as spring-loaded folders. While
       dragging a file to a destination, hovering briefly over
       a folder icon would cause that folder to spring open,
       allowing you to zip through several levels of hierarchy
       while dragging. I personally prefer shelves.

     Windows/Nextstep style separation of path and filename:
       Keyboard navigation is an important part of the
       advanced user experience in any system. In order to
       be able to keyboard navigate the filesystem from a
       Save Panel, one needs to be able to keyboard 
       nagivate the paths without erasing the suggested 
       filename. Windows and Next (now MacOS X) both have 
       this correct. However, the majority of Save panels 
       on UNIX, from Motif to GTK, erase the the text of the 
       suggested filename when you use keys to navigate the 
       directory structure. Some of them even erase the
       filename when you select a directory with the mouse!

  Misc UI:

     'Inspector' Floating Windows: NeXTStep first formalized
       the concept of a app-specific floating inspector
       windows. To make this work, they introduced the concept
       of their being two 'active' windows on screen, one 
       is the main window (the selected document window),
       while the other is the key window (where you input
       focus is). When selecting an inspector, the last
       selected document window is the main window, while the
       inspector is the key window. This allows the capability
       for proper keyboard focus, and reasonable user feedback,
       while using a floating window.

       One drawback of this scheme (and the Mac/Next
       single application menu metaphor) is it's 
       incompatibility with the common power-user's 'Focus
       Follows Mouse' window focus behavior.

  Dialogs:

     'Window Attached Dialogs': MacOS X introduced the concept
       of Dialog Sheets. This allowed a Modal dialog to 
       apply to only a single window by attaching itself
       to that window, partially obscuring view of the window.
       This makes far more sense than arbitrarily locking up
       an entire application because of an operation which
       really only affects a single window.