AtmaWeapon
06-24-2007, 01:11 AM
I have never really liked the idea of unlimited software patents. The concept of a software patent is that a company can take some software concept, claim they invented it, and by the patent prevent any other entity from producing a similar software product without paying licensing fees or royalties.
From the outside, it seems like that's perfectly fine; I mean if you invent something you should be able to decide if you want its implementation to be open or if you want to profit exclusively. The problem is the analogy of physical inventions to software is a shaky one. Consider inventions such as the Segway. The device represents something that no one had implemented before. Any attempt to reproduce a device with the same functionality is likely to use the same kinds of machinery, therefore whether it is patentable is without question.
Now consider, for a moment, how software works. Suppose I own a software patent titled "A method for averaging an arbitrary amount of numbers via a graphical user interface". I detail all of the internals of my design, and I'm granted a patent. The problem is, given that vague description I can come up with at least 3 different implementations and I could write code to implement them in 4 different languages without difficulty. Are all 12 of those implementations subject to the patent?
My point is it seems to me that when it comes to works such as software, it is very easy to reproduce the work of another with no knowledge of how they implemented the software AND produce a functionally identical product that varies enough in implementation to be provably uninfluenced by the other. Because of this, I feel software should at most be allowed to be copyrighted. This allows the inventor of an algorithm the exclusive right to profit from the discovery for a limited time, after which other individuals are allowed to produce similar works.
Why did I post this? I came up with this neat idea 2 years ago. I was writing a little utility program and frustrated with now much code needs to be written to do simple mathematical operations. I thought about how easy it would be if I could just drag a few symbols onto a workspace and connect them in such a way that I could visually indicate the flow of data. It would look remarkably like this (http://imagesocket.com/view/blockdiagram577.png ).
That image represents a program that takes a set of numbers of indefinite size and averages them, as done in the product my company develops. There are several patents on this product, to the extent that the development of graphical programming languages is almost exclusively the domain of the company. While it makes me happy that we will remain profitable it also makes me sad that people aren't free to tinker with graphical programming and possibly come up with better implementations. If the software were copyrighted rather than patented, most of its functionality would be past the term of the copyright and available for use without limitation.
For those of you who don't understand why publicly available graphical languages might be nice, compare the image to the functionally equivalent C# code below. It took me 3 minutes to create the graphical code and 10 minutes to produce the C#; the C# is missing some UI beautification I would want to do for widespread distribution but oh well. The C# is split into 2 files because people got confused when Microsoft auto-generated layout code in their file:
Averager.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
namespace Averager
{
public partial class MainForm : Form
{
public MainForm()
{
InitializeComponent();
}
private void UpdateAverage()
{
int sum = 0;
int items = 0;
double average;
foreach (decimal item in lbItems.Items)
{
items++;
sum += (int)item;
}
// coerce the result to be interpreted as double
average = (double)sum / items;
txtResult.Text = average.ToString("f2");
}
private void btnAdd_Click(object sender, EventArgs e)
{
lbItems.Items.Add(nudValue.Value);
UpdateAverage();
}
private void btnRemove_Click(object sender, EventArgs e)
{
if (lbItems.SelectedItem != null)
{
lbItems.Items.Remove(lbItems.SelectedItem);
UpdateAverage();
}
}
}
}
Averager.Designer.cs
amespace Averager
{
partial class MainForm
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.groupBox1 = new System.Windows.Forms.GroupBox();
this.lbItems = new System.Windows.Forms.ListBox();
this.btnAdd = new System.Windows.Forms.Button();
this.btnRemove = new System.Windows.Forms.Button();
this.nudValue = new System.Windows.Forms.NumericUpDown();
this.gbxResults = new System.Windows.Forms.GroupBox();
this.txtResult = new System.Windows.Forms.TextBox();
this.groupBox1.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.n udValue)).BeginInit();
this.gbxResults.SuspendLayout();
this.SuspendLayout();
//
// groupBox1
//
this.groupBox1.Controls.Add(this.nudValue);
this.groupBox1.Controls.Add(this.btnRemove);
this.groupBox1.Controls.Add(this.btnAdd);
this.groupBox1.Controls.Add(this.lbItems);
this.groupBox1.Location = new System.Drawing.Point(12, 12);
this.groupBox1.Name = "groupBox1";
this.groupBox1.Size = new System.Drawing.Size(210, 158);
this.groupBox1.TabIndex = 0;
this.groupBox1.TabStop = false;
this.groupBox1.Text = "groupBox1";
//
// lbItems
//
this.lbItems.FormattingEnabled = true;
this.lbItems.Location = new System.Drawing.Point(3, 47);
this.lbItems.Name = "lbItems";
this.lbItems.Size = new System.Drawing.Size(120, 95);
this.lbItems.TabIndex = 0;
//
// btnAdd
//
this.btnAdd.Location = new System.Drawing.Point(129, 47);
this.btnAdd.Name = "btnAdd";
this.btnAdd.Size = new System.Drawing.Size(75, 23);
this.btnAdd.TabIndex = 1;
this.btnAdd.Text = "Add";
this.btnAdd.UseVisualStyleBackColor = true;
this.btnAdd.Click += new System.EventHandler(this.btnAdd_Click);
//
// btnRemove
//
this.btnRemove.Location = new System.Drawing.Point(129, 119);
this.btnRemove.Name = "btnRemove";
this.btnRemove.Size = new System.Drawing.Size(75, 23);
this.btnRemove.TabIndex = 2;
this.btnRemove.Text = "Remove";
this.btnRemove.UseVisualStyleBackColor = true;
this.btnRemove.Click += new System.EventHandler(this.btnRemove_Click);
//
// nudValue
//
this.nudValue.Location = new System.Drawing.Point(6, 19);
this.nudValue.Name = "nudValue";
this.nudValue.Size = new System.Drawing.Size(117, 20);
this.nudValue.TabIndex = 3;
//
// gbxResults
//
this.gbxResults.Controls.Add(this.txtResult);
this.gbxResults.Location = new System.Drawing.Point(12, 176);
this.gbxResults.Name = "gbxResults";
this.gbxResults.Size = new System.Drawing.Size(210, 44);
this.gbxResults.TabIndex = 1;
this.gbxResults.TabStop = false;
this.gbxResults.Text = "Result";
//
// txtResult
//
this.txtResult.Location = new System.Drawing.Point(3, 16);
this.txtResult.Name = "txtResult";
this.txtResult.ReadOnly = true;
this.txtResult.Size = new System.Drawing.Size(201, 20);
this.txtResult.TabIndex = 0;
//
// MainForm
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(237, 233);
this.Controls.Add(this.gbxResults);
this.Controls.Add(this.groupBox1);
this.Name = "MainForm";
this.Text = "Averager";
this.groupBox1.ResumeLayout(false);
((System.ComponentModel.ISupportInitialize)(this.n udValue)).EndInit();
this.gbxResults.ResumeLayout(false);
this.gbxResults.PerformLayout();
this.ResumeLayout(false);
}
#endregion
private System.Windows.Forms.GroupBox groupBox1;
private System.Windows.Forms.NumericUpDown nudValue;
private System.Windows.Forms.Button btnRemove;
private System.Windows.Forms.Button btnAdd;
private System.Windows.Forms.ListBox lbItems;
private System.Windows.Forms.GroupBox gbxResults;
private System.Windows.Forms.TextBox txtResult;
}
}
*edit* Also don't get me wrong, I love the company and I'm not an activist for this issue, but for the past few years I haven't understood what all the fuss about software patents was and when I saw this product I understood. I am not certain if it would be impossible for someone to independently create a graphical programming language and evade the patents on this software, I only looked up 2 or 3 of the patents and they all applied to "nice" features that aren't necessarily vital to having the language. Still, I am just curious how everyone else feels about software patents.
From the outside, it seems like that's perfectly fine; I mean if you invent something you should be able to decide if you want its implementation to be open or if you want to profit exclusively. The problem is the analogy of physical inventions to software is a shaky one. Consider inventions such as the Segway. The device represents something that no one had implemented before. Any attempt to reproduce a device with the same functionality is likely to use the same kinds of machinery, therefore whether it is patentable is without question.
Now consider, for a moment, how software works. Suppose I own a software patent titled "A method for averaging an arbitrary amount of numbers via a graphical user interface". I detail all of the internals of my design, and I'm granted a patent. The problem is, given that vague description I can come up with at least 3 different implementations and I could write code to implement them in 4 different languages without difficulty. Are all 12 of those implementations subject to the patent?
My point is it seems to me that when it comes to works such as software, it is very easy to reproduce the work of another with no knowledge of how they implemented the software AND produce a functionally identical product that varies enough in implementation to be provably uninfluenced by the other. Because of this, I feel software should at most be allowed to be copyrighted. This allows the inventor of an algorithm the exclusive right to profit from the discovery for a limited time, after which other individuals are allowed to produce similar works.
Why did I post this? I came up with this neat idea 2 years ago. I was writing a little utility program and frustrated with now much code needs to be written to do simple mathematical operations. I thought about how easy it would be if I could just drag a few symbols onto a workspace and connect them in such a way that I could visually indicate the flow of data. It would look remarkably like this (http://imagesocket.com/view/blockdiagram577.png ).
That image represents a program that takes a set of numbers of indefinite size and averages them, as done in the product my company develops. There are several patents on this product, to the extent that the development of graphical programming languages is almost exclusively the domain of the company. While it makes me happy that we will remain profitable it also makes me sad that people aren't free to tinker with graphical programming and possibly come up with better implementations. If the software were copyrighted rather than patented, most of its functionality would be past the term of the copyright and available for use without limitation.
For those of you who don't understand why publicly available graphical languages might be nice, compare the image to the functionally equivalent C# code below. It took me 3 minutes to create the graphical code and 10 minutes to produce the C#; the C# is missing some UI beautification I would want to do for widespread distribution but oh well. The C# is split into 2 files because people got confused when Microsoft auto-generated layout code in their file:
Averager.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
namespace Averager
{
public partial class MainForm : Form
{
public MainForm()
{
InitializeComponent();
}
private void UpdateAverage()
{
int sum = 0;
int items = 0;
double average;
foreach (decimal item in lbItems.Items)
{
items++;
sum += (int)item;
}
// coerce the result to be interpreted as double
average = (double)sum / items;
txtResult.Text = average.ToString("f2");
}
private void btnAdd_Click(object sender, EventArgs e)
{
lbItems.Items.Add(nudValue.Value);
UpdateAverage();
}
private void btnRemove_Click(object sender, EventArgs e)
{
if (lbItems.SelectedItem != null)
{
lbItems.Items.Remove(lbItems.SelectedItem);
UpdateAverage();
}
}
}
}
Averager.Designer.cs
amespace Averager
{
partial class MainForm
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.groupBox1 = new System.Windows.Forms.GroupBox();
this.lbItems = new System.Windows.Forms.ListBox();
this.btnAdd = new System.Windows.Forms.Button();
this.btnRemove = new System.Windows.Forms.Button();
this.nudValue = new System.Windows.Forms.NumericUpDown();
this.gbxResults = new System.Windows.Forms.GroupBox();
this.txtResult = new System.Windows.Forms.TextBox();
this.groupBox1.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.n udValue)).BeginInit();
this.gbxResults.SuspendLayout();
this.SuspendLayout();
//
// groupBox1
//
this.groupBox1.Controls.Add(this.nudValue);
this.groupBox1.Controls.Add(this.btnRemove);
this.groupBox1.Controls.Add(this.btnAdd);
this.groupBox1.Controls.Add(this.lbItems);
this.groupBox1.Location = new System.Drawing.Point(12, 12);
this.groupBox1.Name = "groupBox1";
this.groupBox1.Size = new System.Drawing.Size(210, 158);
this.groupBox1.TabIndex = 0;
this.groupBox1.TabStop = false;
this.groupBox1.Text = "groupBox1";
//
// lbItems
//
this.lbItems.FormattingEnabled = true;
this.lbItems.Location = new System.Drawing.Point(3, 47);
this.lbItems.Name = "lbItems";
this.lbItems.Size = new System.Drawing.Size(120, 95);
this.lbItems.TabIndex = 0;
//
// btnAdd
//
this.btnAdd.Location = new System.Drawing.Point(129, 47);
this.btnAdd.Name = "btnAdd";
this.btnAdd.Size = new System.Drawing.Size(75, 23);
this.btnAdd.TabIndex = 1;
this.btnAdd.Text = "Add";
this.btnAdd.UseVisualStyleBackColor = true;
this.btnAdd.Click += new System.EventHandler(this.btnAdd_Click);
//
// btnRemove
//
this.btnRemove.Location = new System.Drawing.Point(129, 119);
this.btnRemove.Name = "btnRemove";
this.btnRemove.Size = new System.Drawing.Size(75, 23);
this.btnRemove.TabIndex = 2;
this.btnRemove.Text = "Remove";
this.btnRemove.UseVisualStyleBackColor = true;
this.btnRemove.Click += new System.EventHandler(this.btnRemove_Click);
//
// nudValue
//
this.nudValue.Location = new System.Drawing.Point(6, 19);
this.nudValue.Name = "nudValue";
this.nudValue.Size = new System.Drawing.Size(117, 20);
this.nudValue.TabIndex = 3;
//
// gbxResults
//
this.gbxResults.Controls.Add(this.txtResult);
this.gbxResults.Location = new System.Drawing.Point(12, 176);
this.gbxResults.Name = "gbxResults";
this.gbxResults.Size = new System.Drawing.Size(210, 44);
this.gbxResults.TabIndex = 1;
this.gbxResults.TabStop = false;
this.gbxResults.Text = "Result";
//
// txtResult
//
this.txtResult.Location = new System.Drawing.Point(3, 16);
this.txtResult.Name = "txtResult";
this.txtResult.ReadOnly = true;
this.txtResult.Size = new System.Drawing.Size(201, 20);
this.txtResult.TabIndex = 0;
//
// MainForm
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(237, 233);
this.Controls.Add(this.gbxResults);
this.Controls.Add(this.groupBox1);
this.Name = "MainForm";
this.Text = "Averager";
this.groupBox1.ResumeLayout(false);
((System.ComponentModel.ISupportInitialize)(this.n udValue)).EndInit();
this.gbxResults.ResumeLayout(false);
this.gbxResults.PerformLayout();
this.ResumeLayout(false);
}
#endregion
private System.Windows.Forms.GroupBox groupBox1;
private System.Windows.Forms.NumericUpDown nudValue;
private System.Windows.Forms.Button btnRemove;
private System.Windows.Forms.Button btnAdd;
private System.Windows.Forms.ListBox lbItems;
private System.Windows.Forms.GroupBox gbxResults;
private System.Windows.Forms.TextBox txtResult;
}
}
*edit* Also don't get me wrong, I love the company and I'm not an activist for this issue, but for the past few years I haven't understood what all the fuss about software patents was and when I saw this product I understood. I am not certain if it would be impossible for someone to independently create a graphical programming language and evade the patents on this software, I only looked up 2 or 3 of the patents and they all applied to "nice" features that aren't necessarily vital to having the language. Still, I am just curious how everyone else feels about software patents.