Mixed-case SOUL: Difference between revisions
m (→Background) |
mNo edit summary |
||
Line 1: | Line 1: | ||
You can compose a <var class="product">User Language</var> request in case-insensitive mode. | You can compose a <var class="product">User Language</var> (now <var class="product">SOUL</var>) request in case-insensitive mode. | ||
When in this mode, all elements of a <var class="product"> | When in this mode, all elements of a <var class="product">SOUL</var> program excepting ''literal strings'' are processed after converting lowercase letters to uppercase. | ||
===Background=== | ===Background=== | ||
One of the principles generally accepted in object-oriented programming is that variable | One of the principles generally accepted in object-oriented programming is that variable | ||
Line 24: | Line 25: | ||
Regardless of the chosen scheme for capitalizing, mixed case is useful for providing code readability. | Regardless of the chosen scheme for capitalizing, mixed case is useful for providing code readability. | ||
This is true not just for compound variable names, but for <var class="product"> | This is true not just for compound variable names, but for <var class="product">SOUL</var> | ||
statements in general — imagine if books were written entirely in uppercase. | statements in general — imagine if books were written entirely in uppercase. | ||
To facilitate the use of coding style common to most object-oriented languages, | To facilitate the use of coding style common to most object-oriented languages, | ||
and to make <var class="product"> | and to make <var class="product">SOUL</var> more readable, <var class="product">SOUL</var> includes enhanced support for mixed case as of <var class="product">Model 204</var> V7.5. | ||
Historically, <var class="Product">[[Model 204]]</var> <var class="product">User Language</var> | Historically, <var class="Product">[[Model 204]]</var> <var class="product">User Language</var> was actually a case-sensitive | ||
language with uppercase keywords. | language with uppercase keywords. | ||
This means that keywords such as IF, THEN, FOR, ADD, etc. had to be | This means that keywords such as IF, THEN, FOR, ADD, etc. had to be | ||
written in uppercase. | written in uppercase. | ||
There are basically three approaches to providing support for mixed case: | There are basically three approaches to providing support for mixed case: | ||
<ol> | |||
<li>Case-sensitive with lowercase or mixed-case keywords. This is the approach used in languages such as [http://en.wikipedia.org/wiki/C_%28programming_language%29 C] and [http://en.wikipedia.org/wiki/Java_%28programming_language%29 Java]. Unfortunately, it was too late for this approach in <var class="product">User Language</var> as the language already has case-sensitivity with uppercase keywords. While it might have been possible to use this approach with lowercase variants of all keywords, such an approach would have been complex, and the case-sensitivity for variable names would make migration to mixed-case code extremely difficult as explained in the next item. | |||
<li>Case-insensitive for keywords but case-sensitive for variable names. A few languages use this approach, but it is quite complex to implement because it makes case-insensitivity of tokens depend upon context. Furthermore, it makes code migration extremely difficult — all references to a variable must be changed to the correct mixed-case variant at once before any of them can be changed. This can be very difficult to do, especially for ''Common'' variables that are used in many different pieces of code, so it is likely that any case-sensitive approach would result in some variables remaining indefinitely in uppercase. | |||
<li>Case-insensitivity for keywords and variable names. Because this seemed to provide the best migration path to using mixed case in existing applications, this approach was taken in the <var class="product">SOUL</var>. It is probably for these very reasons that many other languages with uppercase keyword roots such as [http://en.wikipedia.org/wiki/Visual_Basic Visual Basic], [http://en.wikipedia.org/wiki/COBOL Cobol], [http://en.wikipedia.org/wiki/Fortran Fortran], and many others have taken the same approach toward providing support for mixed case. | |||
</ol> | |||
It is worth noting that, at least in theory, case-insensitive <var class="product">User Language</var> is a major backward compatibility problem. | It is worth noting that, at least in theory, case-insensitive <var class="product">User Language</var> is a major backward compatibility problem. | ||
Before the | Before the mixed-case support, ''%customer'' was a different variable from ''%Customer'' or ''%CUSTOMER''. | ||
from ''%Customer'' or ''%CUSTOMER''. | |||
Fortunately, because of <var class="product">User Language</var>'s requirement for uppercase-only keywords, few people took advantage of this case-sensitivity | Fortunately, because of <var class="product">User Language</var>'s requirement for uppercase-only keywords, few people took advantage of this case-sensitivity | ||
because it just looked “funny” to have mixed-case variables | because it just looked “funny” to have mixed-case variables | ||
afloat in a sea of uppercase keywords: | afloat in a sea of uppercase keywords: | ||
<p class="code">IF %status = 'new' THEN | |||
READ SCREEN newCustomer | |||
IF %newCustomer:PFKEY EQ 3 THEN | |||
STOP | |||
END IF | END IF | ||
END IF | |||
</p> | |||
So, ''probably'' most existing <var class="product">User Language</var> applications will work | So, ''probably'' most existing <var class="product">User Language</var> applications will work | ||
fine in case-insensitive mode with no modifications. | fine in case-insensitive mode with no modifications. | ||
However, since there is no way for the <var class="product"> | However, since there is no way for the <var class="product">SOUL</var> to know that this is the case, | ||
programmers must indicate that programs are to be case-insensitive. | programmers must indicate that programs are to be case-insensitive. | ||
Line 63: | Line 67: | ||
in mixed case. | in mixed case. | ||
For example, field ''RECTYPE'' could be referred to as ''recType'' when | For example, field ''RECTYPE'' could be referred to as ''recType'' when | ||
case-insensitive <var class="product"> | case-insensitive <var class="product">SOUL</var> is enabled. | ||
Translation of tokens to uppercase also means that compiler error | Translation of tokens to uppercase also means that compiler error | ||
messages will sometimes indicate names or keywords in uppercase, even though | messages will sometimes indicate names or keywords in uppercase, even though | ||
Line 72: | Line 76: | ||
===What is affected=== | ===What is affected=== | ||
If <var class="product"> | If <var class="product">SOUL</var> case-insensitivity is enabled, these entities become case-insensitive: | ||
<ul> | |||
<li>'''SOUL keywords'''. For example: <code>For</code>, <code>If</code>, <code>Then</code>, <code>eq</code>. | |||
<li>'''Names of members of SOUL classes'''. For example: [[XmlDoc API]], [[File classes|File class]], and [[HTTP Helper]] methods and variables. | |||
<li>'''Variable elements'''. For example: %variables, Screen/Image names and items, Class/Structure members. Note, however, that in this mode you cannot define two variable elements whose names differ only because some letters have different case. | |||
<li>'''Labels and subroutine names'''. <p class="note"><b>Note: </b>In this mode, you cannot define two labels whose names differ only because some letters are different case. </p> | |||
<li>'''Field names'''. <p class="note"><b>Note: </b>In this mode, you cannot access field names containing lowercase letters. </p> | |||
<li>'''$functions'''. <p class="note"><b>Note: </b>In this mode, you cannot access $functions containing lowercase letters. </p> | |||
<li>'''Procedure names''' (on the Include statement). <p class="note"><b>Note: </b>In this mode, you cannot include procedures whose names contain lowercase letters. </p> | |||
<li>'''SOUL object documentation'''. Keywords and variable name references use mixed case. Keywords will generally be indicated by an uppercase first letter. | |||
</ul> | |||
===What is not affected=== | ===What is not affected=== | ||
If <var class="product"> | If <var class="product">SOUL</var> case-insensitivity is enabled, these entities '''do not''' become case-insensitive: | ||
<ul> | |||
<li>'''Model 204 commands''' (except for Begin, which is discussed below). Command processing usually works well, however, if you use *UPPER for command input, and let the modifications to the Model 204 editor (including the <var>[[SIREDIT parameter|SIREDIT]]</var> parameter and the editor ''CASE'' command) be in effect for working on <var class="product">SOUL</var>. | |||
<li>'''Quoted strings''' (in a <var class="product">SOUL</var> request). For example: <code>'Caps help with veryLongNames'</code>. | |||
<li>'''Literal contents of a Text/Html block'''. In a Text/Html block, case is preserved for all elements except those enclosed in the evaluation brackets (curly braces). In the following example, <code>empName</code> and <code>empAddress</code> are references to fields named EMPNAME and ADDRESS, respectively: | |||
<p class="code">Html | |||
Name: {empName} | |||
Address: {empAddress} | |||
End Html </p> | |||
<li>'''Non-compilation elements'''. Case-insensitive processing applies only to program elements encountered during compilation. For example, when setting a value for a fieldname variable or for Screen or Image indirection, the value must exactly match the name. If you have a field named EMPNAME and you reference it with a fieldname variable, the value used must be all uppercase: | |||
<p class="code">Begin | |||
%x String Len 20 | |||
%x = 'EMPNAME' | |||
FR | |||
Print %%x | |||
End For | |||
End </p> | |||
</ul> | |||
===How to enable and disable=== | ===How to enable and disable=== | ||
You can enable case-insensitive <var class="product"> | You can enable case-insensitive <var class="product">SOUL</var> in one of these ways: | ||
<ul> | |||
<li>Start a program with a mixed-case or lowercase Begin statement. | |||
Because the following programs begin with mixed-case Begin statements, | <li>Use the <code>Sirius Case ToUpper</code> compiler directive. | ||
<li>Use the <var>[[COMPOPT parameter|COMPOPT]]</var> system parameter to globally enable case-insensitive <var class="product">SOUL</var>. | |||
Because the following programs begin with mixed-case <var>Begin</var> statements, | |||
they are compiled with case-insensitivity: | they are compiled with case-insensitivity: | ||
<p class="code">b | |||
print 'Mixed case UL is easy' | |||
end </p> | |||
Or: | |||
<p class="code">Begin | |||
Print 'Style is everything' | |||
End </p> | |||
Sometimes, however, one might be working on <var class="product">SOUL</var> that is Included | |||
in many outer programs, some of which might not have been converted to | |||
Sometimes, however, one might be working on <var class="product"> | |||
in many outer programs some of which might not have been converted to | |||
case-insensitivity yet. | case-insensitivity yet. | ||
In such a case, it is possible to enable internal translation to uppercase | In such a case, it is possible to enable internal translation to uppercase | ||
(and so case-insensitivity) with the | (and so case-insensitivity) with the <code>Sirius Case</code> compiler directive: | ||
Specifying | <p class="code">Sirius Case {ToUpper | Leave} </p> | ||
Specifying <code>ToUpper</code> requests internal uppercase translation; <code>Leave</code> means no such translation. | |||
If procedure ''P'' contains a complex subroutine that might | If procedure ''P'' contains a complex subroutine that might | ||
be included in outer procedures, some of which might not have been converted | be included in outer procedures, some of which might not have been converted | ||
to use case-sensitivity, you can insert a Sirius Case directive | to use case-sensitivity, you can insert a <var>Sirius Case</var> directive | ||
at the top of procedure: | at the top of procedure: | ||
<p class="code">sirius case toUpper | |||
subroutine mixedUp(%confusion is float) | |||
... | |||
The | end subroutine </p> | ||
The <var>Sirius Case</var> directive affects case translation in Included | |||
procedures unless explicitly overridden in those procedures. | procedures unless explicitly overridden in those procedures. | ||
The | The <var>Sirius Case</var> setting does '''not''' affect the procedure | ||
that Included the procedure with the setting | that Included the procedure with the setting | ||
(so, case-sensitivity in a procedure can never be changed by an Included procedure). | (so, case-sensitivity in a procedure can never be changed by an Included procedure). | ||
Because the | Because the <var>Sirius Case</var> directive is a compiler directive, it is not | ||
affected by any programming block structures (such as | affected by any programming block structures (such as <var>For</var> loops). | ||
It simply affects all lines of code physically after the directive. | It simply affects all lines of code physically after the directive. | ||
<code>Sirius Case Leave</code> can be used to turn off case-insensitivity in | |||
cases where case-sensitivity is required or desired. | cases where case-sensitivity is required or desired. | ||
Note, though, that in such cases, all <var class="product"> | Note, though, that in such cases, all <var class="product">SOUL</var> keywords must be in uppercase. | ||
====The COMPOPT system parameter==== | ====The COMPOPT system parameter==== | ||
The system parameter <var>[[COMPOPT parameter|COMPOPT]]</var> facilitates migration to mixed-case <var class="product">SOUL</var>. | |||
COMPOPT is a | <var>COMPOPT</var> is a Model 204 bitmask parameter that must be set in the CCAIN (User 0 input) stream. | ||
The bits in COMPOPT have the following meanings: | The bits in <var>COMPOPT</var> have the following meanings: | ||
<dl> | <dl> | ||
<dt>X'01' | <dt>X'01' | ||
<dd>If on, all procedures start out in | <dd>If on, all procedures start out in <code>Sirius Case ToUpper</code> mode, | ||
whether or not they begin with a mixed-case | whether or not they begin with a mixed-case <var>Begin</var> statement. | ||
<code>Sirius Case ToUpper</code> mode translates all unquoted tokens to uppercase, so | |||
<var class="product"> | <var class="product">SOUL</var> statements, keywords, variable names, etc. may be written in mixed case. | ||
By setting the | By setting the <var>COMPOPT</var> X'01' bit, a site is essentially enabling mixed-case <var class="product">SOUL</var> almost everywhere. | ||
<dt>X'02' | <dt>X'02' | ||
<dd>If on, | <dd>If on, <code>Sirius Case Leave</code> compiler directives are to be ignored: | ||
if | if <code>Sirius Case ToUpper</code> is in effect, it remains in effect even | ||
if a | if a <code>Sirius Case Leave</code> directive is encountered. | ||
Setting the | Setting the <var>COMPOPT</var> X'02' bit along with the X'01' bit enables mixed-case <var class="product">SOUL</var> | ||
everywhere, thus ensuring consistent language processing throughout an | everywhere, thus ensuring consistent language processing throughout an Online. | ||
Online. | |||
<dt>X'04' | <dt>X'04' | ||
<dd>If on, image or image-item names, either literal or in variables, | <dd>If on, image or image-item names, either literal or in variables, | ||
are to be automatically converted to uppercase before being used in methods or | are to be automatically converted to uppercase before being used in methods or | ||
$functions. | $functions. | ||
Since mixed-case <var class="product"> | Since mixed-case <var class="product">SOUL</var> is accomplished by translating unquoted tokens to | ||
uppercase, this case conversion for image or image-item names is the runtime | uppercase, this case conversion for image or image-item names is the runtime | ||
equivalent of the compiler mixed-case support. | equivalent of the compiler mixed-case support. | ||
<p> | |||
Setting the <var>COMPOPT</var> X'04' bit enables image and image-item names that | |||
Setting the | appear as literals in <var class="product">SOUL</var> programs to be entered in mixed case. | ||
appear as literals in <var class="product"> | |||
The only time this might be a problem is if there are true mixed-case image | The only time this might be a problem is if there are true mixed-case image | ||
or image-item names in an application. | or image-item names in an application. </p> | ||
<p> | |||
A true mixed-case image or image-item name is one written in mixed case, | A true mixed-case image or image-item name is one written in mixed case, | ||
either inside quotation marks (image and image-item names can ''indeed'' | either inside quotation marks (image and image-item names can ''indeed'' | ||
be put in quotes) or without | be put in quotes) or without <code>Sirius Case ToUpper</code> in effect. | ||
In general, neither of these is too likely, so true mixed-case image or | In general, neither of these is too likely, so true mixed-case image or | ||
image-item names are not likely in most applications. | image-item names are not likely in most applications. </p> | ||
</dl> | </dl> |
Revision as of 00:31, 15 October 2013
You can compose a User Language (now SOUL) request in case-insensitive mode. When in this mode, all elements of a SOUL program excepting literal strings are processed after converting lowercase letters to uppercase.
Background
One of the principles generally accepted in object-oriented programming is that variable names and method names should be meaningful, that is, be full words or phrases rather than abbreviations or shorthands. For example, it is generally considered better to call a variable %FIRSTNAME rather than %FN. The reason for this is that most programmers spend much more time reading code than writing it, and meaningful variable names make reading much easier than terse abbreviations. And even when writing code, programmers will typically spend more time thinking about what they are writing than actually typing it and, here again, the thinking process is facilitated with meaningful names.
Meaningful names often involve creation of compound words as variable names such as %OLDESTCHILDBIRTHDATE. As this example illustrates, however, these names can become difficult to read as they become more descriptive. One way to deal with this problem is with the use of separator characters such as underscores or periods, as in %OLDEST_CHILD_BIRTH_DATE or %OLDEST.CHILD.BIRTH.DATE. The problem with this approach, however, is that it can make code look like “special-character soup” with a mish-mash of inter- and intra-variable separator characters which makes visual parsing difficult. The approach most commonly used in object-oriented programming is to use case to separate words in a compound word variable name, for example, %OldestChildBirthDate. There are basically two standards for compound word capitalization: the camel case format, where the first word is not capitalized as in %oldestChildBirthDate, and the Pascal format (after the programming language) where the first word is capitalized, as in %OldestChildBirthDate.
Regardless of the chosen scheme for capitalizing, mixed case is useful for providing code readability. This is true not just for compound variable names, but for SOUL statements in general — imagine if books were written entirely in uppercase. To facilitate the use of coding style common to most object-oriented languages, and to make SOUL more readable, SOUL includes enhanced support for mixed case as of Model 204 V7.5.
Historically, Model 204 User Language was actually a case-sensitive language with uppercase keywords. This means that keywords such as IF, THEN, FOR, ADD, etc. had to be written in uppercase. There are basically three approaches to providing support for mixed case:
- Case-sensitive with lowercase or mixed-case keywords. This is the approach used in languages such as C and Java. Unfortunately, it was too late for this approach in User Language as the language already has case-sensitivity with uppercase keywords. While it might have been possible to use this approach with lowercase variants of all keywords, such an approach would have been complex, and the case-sensitivity for variable names would make migration to mixed-case code extremely difficult as explained in the next item.
- Case-insensitive for keywords but case-sensitive for variable names. A few languages use this approach, but it is quite complex to implement because it makes case-insensitivity of tokens depend upon context. Furthermore, it makes code migration extremely difficult — all references to a variable must be changed to the correct mixed-case variant at once before any of them can be changed. This can be very difficult to do, especially for Common variables that are used in many different pieces of code, so it is likely that any case-sensitive approach would result in some variables remaining indefinitely in uppercase.
- Case-insensitivity for keywords and variable names. Because this seemed to provide the best migration path to using mixed case in existing applications, this approach was taken in the SOUL. It is probably for these very reasons that many other languages with uppercase keyword roots such as Visual Basic, Cobol, Fortran, and many others have taken the same approach toward providing support for mixed case.
It is worth noting that, at least in theory, case-insensitive User Language is a major backward compatibility problem. Before the mixed-case support, %customer was a different variable from %Customer or %CUSTOMER. Fortunately, because of User Language's requirement for uppercase-only keywords, few people took advantage of this case-sensitivity because it just looked “funny” to have mixed-case variables afloat in a sea of uppercase keywords:
IF %status = 'new' THEN READ SCREEN newCustomer IF %newCustomer:PFKEY EQ 3 THEN STOP END IF END IF
So, probably most existing User Language applications will work fine in case-insensitive mode with no modifications. However, since there is no way for the SOUL to know that this is the case, programmers must indicate that programs are to be case-insensitive.
Perhaps somewhat counter-intuitively, case-insensitivity is achieved by internally translating all unquoted tokens to uppercase. That is, %customer, %Customer, and %CUstOMer all refer to the same variable because they all get internally translated to %CUSTOMER before being processed. Similarly, if, If, and IF all get translated to IF before being compiled. This translation is useful in allowing reference to existing uppercase fieldnames in mixed case. For example, field RECTYPE could be referred to as recType when case-insensitive SOUL is enabled. Translation of tokens to uppercase also means that compiler error messages will sometimes indicate names or keywords in uppercase, even though they were entered in mixed case.
The following sections summarize the entities affected by uppercase translation and describe how to invoke it.
What is affected
If SOUL case-insensitivity is enabled, these entities become case-insensitive:
- SOUL keywords. For example:
For
,If
,Then
,eq
. - Names of members of SOUL classes. For example: XmlDoc API, File class, and HTTP Helper methods and variables.
- Variable elements. For example: %variables, Screen/Image names and items, Class/Structure members. Note, however, that in this mode you cannot define two variable elements whose names differ only because some letters have different case.
- Labels and subroutine names.
Note: In this mode, you cannot define two labels whose names differ only because some letters are different case.
- Field names.
Note: In this mode, you cannot access field names containing lowercase letters.
- $functions.
Note: In this mode, you cannot access $functions containing lowercase letters.
- Procedure names (on the Include statement).
Note: In this mode, you cannot include procedures whose names contain lowercase letters.
- SOUL object documentation. Keywords and variable name references use mixed case. Keywords will generally be indicated by an uppercase first letter.
What is not affected
If SOUL case-insensitivity is enabled, these entities do not become case-insensitive:
- Model 204 commands (except for Begin, which is discussed below). Command processing usually works well, however, if you use *UPPER for command input, and let the modifications to the Model 204 editor (including the SIREDIT parameter and the editor CASE command) be in effect for working on SOUL.
- Quoted strings (in a SOUL request). For example:
'Caps help with veryLongNames'
. - Literal contents of a Text/Html block. In a Text/Html block, case is preserved for all elements except those enclosed in the evaluation brackets (curly braces). In the following example,
empName
andempAddress
are references to fields named EMPNAME and ADDRESS, respectively:Html Name: {empName} Address: {empAddress} End Html
- Non-compilation elements. Case-insensitive processing applies only to program elements encountered during compilation. For example, when setting a value for a fieldname variable or for Screen or Image indirection, the value must exactly match the name. If you have a field named EMPNAME and you reference it with a fieldname variable, the value used must be all uppercase:
Begin %x String Len 20 %x = 'EMPNAME' FR Print %%x End For End
How to enable and disable
You can enable case-insensitive SOUL in one of these ways:
- Start a program with a mixed-case or lowercase Begin statement.
- Use the
Sirius Case ToUpper
compiler directive. - Use the COMPOPT system parameter to globally enable case-insensitive SOUL.
Because the following programs begin with mixed-case Begin statements,
they are compiled with case-insensitivity:
b print 'Mixed case UL is easy' end
Or:
Begin Print 'Style is everything' End
Sometimes, however, one might be working on SOUL that is Included in many outer programs, some of which might not have been converted to case-insensitivity yet.
In such a case, it is possible to enable internal translation to uppercase (and so case-insensitivity) with the
Sirius Case
compiler directive:Sirius Case {ToUpper | Leave}
Specifying
ToUpper
requests internal uppercase translation;Leave
means no such translation.If procedure P contains a complex subroutine that might be included in outer procedures, some of which might not have been converted to use case-sensitivity, you can insert a Sirius Case directive at the top of procedure:
sirius case toUpper subroutine mixedUp(%confusion is float) ... end subroutine
The Sirius Case directive affects case translation in Included procedures unless explicitly overridden in those procedures. The Sirius Case setting does not affect the procedure that Included the procedure with the setting (so, case-sensitivity in a procedure can never be changed by an Included procedure).
Because the Sirius Case directive is a compiler directive, it is not affected by any programming block structures (such as For loops). It simply affects all lines of code physically after the directive.
Sirius Case Leave
can be used to turn off case-insensitivity in cases where case-sensitivity is required or desired. Note, though, that in such cases, all SOUL keywords must be in uppercase.The COMPOPT system parameter
The system parameter COMPOPT facilitates migration to mixed-case SOUL. COMPOPT is a Model 204 bitmask parameter that must be set in the CCAIN (User 0 input) stream. The bits in COMPOPT have the following meanings:
- X'01'
- If on, all procedures start out in
Sirius Case ToUpper
mode, whether or not they begin with a mixed-case Begin statement.Sirius Case ToUpper
mode translates all unquoted tokens to uppercase, so SOUL statements, keywords, variable names, etc. may be written in mixed case. By setting the COMPOPT X'01' bit, a site is essentially enabling mixed-case SOUL almost everywhere. - X'02'
- If on,
Sirius Case Leave
compiler directives are to be ignored: ifSirius Case ToUpper
is in effect, it remains in effect even if aSirius Case Leave
directive is encountered. Setting the COMPOPT X'02' bit along with the X'01' bit enables mixed-case SOUL everywhere, thus ensuring consistent language processing throughout an Online. - X'04'
- If on, image or image-item names, either literal or in variables,
are to be automatically converted to uppercase before being used in methods or
$functions.
Since mixed-case SOUL is accomplished by translating unquoted tokens to
uppercase, this case conversion for image or image-item names is the runtime
equivalent of the compiler mixed-case support.
Setting the COMPOPT X'04' bit enables image and image-item names that appear as literals in SOUL programs to be entered in mixed case. The only time this might be a problem is if there are true mixed-case image or image-item names in an application.
A true mixed-case image or image-item name is one written in mixed case, either inside quotation marks (image and image-item names can indeed be put in quotes) or without
Sirius Case ToUpper
in effect. In general, neither of these is too likely, so true mixed-case image or image-item names are not likely in most applications.