Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Languages / C#

Designing strong identifiers with NerdCaps

5.00/5 (1 vote)
12 Feb 2015CPOL12 min read 13.3K   44  
This article offers insight in all aspects of identifiers, and proves that any set of identifiers contains strong evidence which can be used to explore a software model.

Introduction

While new powerful technologies such as LINQ make software design even easier, there is less excuse to neglect details in software design. NerdCaps offers strong analysis for type identifiers, where any set of type names can be translated to a structured self-explanatory expression. This article explains the various assertions of NerdCaps, rendering NerdCaps as a tool and a concept.

This article offers insight in all aspects of identifiers, and proves that any set of identifiers contains strong evidence which can be used to explore a software model. Some concepts in this article are best explained in mathematics or programming language (especially premise assignment), while they are best understood through experimentation with the tool. To ensure simplicity, I have only included NerdCaps Expressions. For a quick impression of NerdCaps, jump to 'Example'.

I suspect that in the future, a subset of NerdCaps will be used outside the field of OOP to uniformize any human-defined identifiers, such as email addresses, product names and forum nicknames, annihilating flaws like 'iPhone'. Websites like c2 Wiki already adopted such formalities in 1995, which were possibly derived from OOP conventions in a similar case.

Note: This article does not apply to trivial problems such as variable naming.

 

Terminology

Note: This section is a reference.

Namespace

A namespace is an abstract notion which designates a certain scope within a range of elements. Every element implies a unique namespace.

Entity

An entity is an abstract notion derived from an element. An alternative element implicitly confirms an entity, while a non-alternative element explicitly confirms an entity. For example: Ae, IAe and AeBase all share the same entity of Ae.

Child

A child is an element which has been assigned to a directory.

Root

A root is a virtual element which serves as the basic point in a tree of elements.

Directory

A directory is an element which serves as the namespace for another element, rendering a hierarchical relationship.

Premise

A premise is an element which asserts the implication of another element. In OOP terms, this term is known as inheritance.

Alternative Element

An alternative element is an element in alternative form. This basically means that the element is masked by an affix, devoiding its status as authority.

Authority

An authority is an element which explicitly confirms a certain entity. Per definition, 'authority' is synonymous with 'non-alternative class'.

Zero-extension

Zero-extension is the absence of an entity in directory assignment, which may occur when two suffixed elements are stacked. For example: AeBase and AeBaseBase form a case of zero-extension.

Exemplar

An exemplar is an element which is subject to directory- or premise assignment.

 

Elements

An element is a component from which an expression can be generated. Multiple elements form a set, so that a complex structure may emerge based on connections between various elements. On an atomic level, an element is a string which exclusively consists of characters in the following range: {0-9, a-z, A-Z}

Note: While the underscore is also conventional for identifiers in edge-cases, it is omitted as a component with structural implications, which beats the purpose of NerdCaps.

On the top-level, an element is parsed into a sequence of words. Three kinds of words exist:

Low Words

A low word primarily consists of alphabetic lowercase characters {a-z}. The first character may be in uppercase {A-Z} for termination from a previous word.

Note: All common words qualify as this kind.

High Words

A high word exclusively consists of alphabetic uppercase characters. In practice, this kind is used to denote acronyms.

Numbers

A number exclusively consists of numeric characters {0-9}. In practice, this kind is used to denote a power which corresponds to the capacity of a type, such as 'Int64'.

Note: A word of this kind cannot be the first word in a sequence because numbers are of auxiliary purpose in a human-readable label. Additionally, leading numbers disable a compiler to differentiate numeric literals from identifiers.

 

Signifiers

A signifier is an element which exclusively serves as a namespace for successive elements, that is; longer non-signifiers which match the signifier. This concept will be further explained in 'Directory Assignment'. The use of signifiers is vital in a non-trivial context to ensure avoidance of collision with Framework components.

To denote a signifier in an element-set, it must be prefixed by '~'.

Example:

~Xe
XeAe

<Translates to>

SX  Xe
CL     XeAe

Note: For readability and ease of access, only use signifiers of one word. To denote multiple words, use an acronym instead.

 

Primes

A prime is a signifier which can be entered from any point within a range of elements, unlike regular signifiers. Reaching elements in a signifier is desirable if it serves as a namespace for generic elements, which are not specific to a certain context. In practice, such elements correspond to OOP constructs defined in linked source files, which is conventional for projects in Visual Studio.

Example:

Ae
~~Xe
XeAe
~Ye
YeAe

<Translates to>

CL  Ae
PM  Xe
CL     XeAe : Ae
SX  Ye
CL     YeAe : XeAe

To denote a prime in an element-set, it must be prefixed by '~~'.

Note: NerdCaps maintains a standard prime named 'Internal'.

Note: In an element-set, only one prime is permitted to avoid conflicts of precedence.

 

Classes

A class is a plain element. This element kind is most essential because it encompasses the ability to form complex structures from an element-set through directory assignment.

Example:

Ae
AeBe
AeBeCe

<Translates to>

CL  Ae
CL     AeBe
CL        AeBeCe

 

Baseclasses

A baseclass is an alternative element by addition of the suffix 'Base'. The use of a baseclass is to declare an entity without claiming a position as authority, so that a non-alternative class could optionally authorize the entity while being subject to premise assignment.

Note: An element of this kind implies that the equivalent OOP construct is modified as 'abstract'.

Note: This pattern is conventional in certain software designs, but is avoided in API's.

 

Interfaces

An interface is an alternative element by addition of the prefix 'I'. An interface corresponds to OOP semantics, where an interface is a template for callable members.

 

Alternative Forms

An alternative form is a format which is defined by the use of an affix, which is either a prefix or suffix.

There is a semantical distinction between prefixed- and suffixed elements. While both implicitly assume a class to authorize the entity described outside the affix, a suffixed element is a class by itself as it allows extension by any other element except a signifier. A prefixed element is not a class because it exclusively allows extension by elements of the same kind, which actually occurs when an authority is missing. A prefixed element is purely oriented towards authority assumption because it semantically lacks concrete value in terms of implementation.

Note: While every suffixed element is a class, it is not possible for prefixed element to assume such class because an element can only contain one affix.

 

Directory Assignment

Directory assignment is the process of resolving namespaces within a range of elements by effectively adding directory registrations to elements while adding elements to directories as children.

For every element, all other elements are compared by matching every word from left to right to determine the winner. The winner is primarily determined by greatest word count. For multiple candidates with the same word count, the winner is determined by the following kind order: {Class > Baseclass > Interface}

Every element kind is subject to unique conditions in comparison:

Note: An incomplete match indicates a result where the suffix failed to match. For such match, the element is still accounted for its entity.

Signifier

  • The counter-element may not be greater in entity word count.
  • Any best match causes a conflict because a signifier does not qualify as an extension, so a signifier solely endures this process to detect conflicts.

Class

  • The counter-element may not be equal or greater in entity word count.
  • If the best match is a prefixed element, or if the best match is incomplete, then a conflict is thrown because such best match is invalid in absence of an authority.

Prefixed Element

  • If the counter-element is a non-alternative class, then it may not be greater in entity word count.
  • If the counter-element is not a non-alternative class, then it may not be greater or equal in entity word count.
  • If the best match is incomplete, then a conflict is thrown because such best match is invalid in absence of an authority.
  • If the best match is equal in entity word count, implying that the best match is an authority, then the exemplar is assigned to the parent of the authority for consistent entity placement.

Suffixed Element

  • If the counter-element is a non-alternative class, then it may not be greater in entity word count.
  • If the counter-element is not a non-alternative class, then it may not be greater or equal in entity word count.
  • If the best match is a prefixed element, then a conflict is thrown because such best match is invalid in absence of an authority.
  • If the best match is a suffixed element under zero-extension, then a conflict is thrown because an entity is missing.
  • If the best match is equal in entity word count, implying that the best match is an authority, then the exemplar is assigned to the parent of the authority for consistent entity placement.

 

Premise Assignment

Premise assignment is the process of resolving premises within a range of elements through traversal and comparison. Premise assignment can be simplified as a form of compounding (as in linguistics), while complemented by the involvement of namespaces and OOP semantics.

The following sequence of operations defines the process:

  1. For every element, a traversal is invoked which starts at the directory of the element, and ends after processing the root.
  2. For every directory in traversal, a recursion is invoked to determine all derivations of the exemplar. The amount of derivations equals the entity word count of the exemplar. For example: The derivations for 'AeBeCe' are 'AeBeCe', 'BeCe' and 'Ce'.
  3. For every derivation, an enumeration of the current directory's child-list is invoked.
  4. For every child, a word sequence comparison between the exemplar and child is invoked.
  5. The comparison succeeds if the child can be fully matched by the derivation from left to right while excluding potential affixes and directory-specific parts for either element.
  6. If the exemplar could not be fully matched by the child, then recursion starting from the child's directory occurs in attempt to complete the match. If the child has a suffix, then it must be matched first while not depleting the exemplar from words.

The following principles apply in the process:

  • An element cannot have itself assigned as premise.
  • Signifiers do not qualify for premise assignment because they are semantically not inheritable.
  • A prime can be traversed if the exemplar is associated with a non-prime signifier.
  • A candidate must be of an equal or lesser kind than the exemplar by the order: {Class > Baseclass > Interface}
  • For multiple candidates distributed over multiple directories, the winner is determined by greatest entity word count. Any second candidate is ignored if it does not exceed in entity word count.
  • For multiple candidates in the same directory, the winner is primarily determined by greatest entity word count. A second candidate with an equal entity word count may replace a prior candidate if its kind is more significant in order {Class > Baseclass > Interface}, or if the kind is equal in order while the prior candidate is not associated with a signifier.

The following examples demonstrate the effects of premise assignment in order of complexity. Premises are denoted by the ':' symbol.

Premise assignment without recursion

Ae
BeAe
CeBeAe

<Translates to>

CL  Ae
CL  BeAe : Ae
CL  CeBeAe : BeAe

Premise assignment with recursion

Ae
AeBe
CeAeBe

<Translates to>

CL  Ae
CL     AeBe
CL  CeAeBe : AeBe

Premise assignment with alternative elements

IAe
AeBase
Ae
AeBe
CeAeBe

<Translates to>

IF  IAe
BS  AeBase : IAe
CL  Ae : AeBase
CL     AeBe
CL  CeAeBe : AeBe

Premise assignment with signifiers

IAe
AeBase
Ae
~~Xe
XeAe
XeAeBe
XeCeAeBe
~Ye
YeCeAeBe

<Translates to>

IF  IAe
BS  AeBase : IAe
CL  Ae : AeBase
PM  Xe
CL     XeAe : Ae
CL        XeAeBe
CL     XeCeAeBe : XeAeBe
SX  Ye
CL     YeCeAeBe : XeCeAeBe

 

Reservation

Reservation is a process which occurs simultaneously with premise assignment. Reservation ensures that for any element, underlying directories and premises are not elected as a premise, this is vital to guard context sensitivity. As a principle, every element in a certain path asserts a unique and incompatible value.

The following examples demonstrate the effects of reservation:

Reservation of directories

Ae
AeAe

<Translates to>

CL  Ae
CL     AeAe

Note: For 'CL(AeAe)', 'CL(Ae)' is dismissed as a premise.

Reservation of premises

Ae
Be
BeAe
BeAeAe

<Translates to>

CL  Ae
CL  Be
CL     BeAe : Ae
CL        BeAeAe

Note: For 'CL(BeAeAe)', 'CL(Ae)' is dismissed as a premise.

 

Expression

NerdCaps relies on expressions to render implications in a certain element-set. An expression is basically a tree, where each node is preambled with a kind indicator, and where each node may be complemented by a premise indicator.

Expressions are formatted as following:

  • Every line begins with a kind indicator.
  • The kind indicator is proceeded by whitespace. The length of the whitespace sequence is a multiple of 4 while excluding 2 standard whitespace characters for termination. The level of depth is determined by the multiple.
  • The whitespace is proceeded by an element indicator, which exactly identifies an element as inputted.
  • The element indicator is optionally complemented by premise indicator, introduced by the symbol ':' which is isolated in single whitespace characters.

Kind indicators are mapped as:

  • CL: Class
  • BS: Baseclass
  • IF: Interface
  • SX: Signifier
  • PM: Prime

 

Sorting

Sorting is a process to ensure that every expression has a uniform appearance. This process applies to each namespace.

The sorting operation is performed by the following conditions in order of significance:

  • Interfaces are greater than baseclasses.
  • Baseclasses are greater than classes.
  • Classes are greater than primes.
  • Primes are greater than signifiers.
  • A is greater than B if A is shorter in length.
  • Final oppositions are resolved by string comparison.

 

Conflicts

Conflicts are errors which occur to ensure semantical validity in a range of elements.

The following conflicts are defined:


MultiplePrimeSignifiers

This conflict indicates that multiple primes exist within the same context where only one prime is allowed.

ElementConflict

This conflict indicates an unbalanced opposition between two elements. This conflict may occur in various situations:

  • An entity absolutely or partially equals a signifier.
  • An element precedes an entity in absence of a non-alternative class to authorize the entity of the element. This occurrence is semantically invalid because non-authoritative elements cannot be reached in a reservation process because they cannot serve as a directory for the entity.
  • Two suffixed elements form a case of zero-extension.

LeadingNumber

This conflict indicates that the first word of an element is a number. This is semantically invalid because an identifier must be a text instead of a quantity.

UnexpectedAffix

This conflict is thrown when a signifier contains an affix, or when an element contains both a prefix and a affix.

 

Suggestions

Suggestions are exclusively a feature of the implementation of NerdCaps. They encourage uniformity for identifiers, but they are not semantically critical.

The following suggestions are defined:

  • NC001: Use pascal case.
  • NC002: Do not start with a number after an interface prefix.
  • NC003: Do not use 1-letter abbreviations.
  • NC004: Use pascal case for acronyms longer than 2 characters.
  • NC005: Do not format numbers with a leading zero.
  • NC006: Resume with pascal case after a number.
  • NC007: Special words are not appropriate in an entity.

 

Example

The following expression is a real demonstration of NerdCaps' capabilities using the CLR namespace 'System.Xml' in DotNet Framework:

IF  IStreamProvider
IF  IHasXmlNode
IF  IApplicationResourceStreamResolver
IF  IFragmentCapableXmlDictionaryWriter
CL  NameTable
CL  UniqueId
SX  Xml
IF     IXmlDictionary
IF     IXmlLineInfo
IF     IXmlNamespaceResolver
IF     IXmlBinaryReaderInitializer
IF     IXmlBinaryWriterInitializer
IF     IXmlMtomReaderInitializer
IF     IXmlMtomWriterInitializer
CL     XmlAttribute
CL        XmlAttributeCollection
CL     XmlComment
CL     XmlConvert
CL     XmlDeclaration
CL     XmlDictionary : IXmlDictionary
CL        XmlDictionaryReader : XmlReader
CL           XmlDictionaryReaderQuotas
CL        XmlDictionaryString
CL        XmlDictionaryWriter : XmlWriter
CL     XmlDocument
CL        XmlDocumentFragment
CL        XmlDocumentType
CL     XmlElement
CL     XmlEntity
CL        XmlEntityReference
CL     XmlException
CL     XmlImplementation
CL     XmlNode
CL        XmlNodeList
CL        XmlNodeReader : XmlReader
CL        XmlNodeChangedEventArgs
CL     XmlNotation
CL     XmlReader
CL        XmlReaderSettings
CL     XmlResolver
CL     XmlText
CL        XmlTextReader : XmlReader
IF           IXmlTextReaderInitializer
CL        XmlTextWriter : XmlWriter
IF           IXmlTextWriterInitializer
CL     XmlWhitespace
CL     XmlWriter
CL        XmlWriterSettings
CL     XmlCharacterData
CL     XmlDataDocument : XmlDocument
CL     XmlLinkedNode : XmlNode
CL     XmlNamespaceManager
CL     XmlNameTable : NameTable
CL     XmlParserContext
CL     XmlProcessingInstruction
CL     XmlQualifiedName
CL     XmlSecureResolver : XmlResolver
CL     XmlSignificantWhitespace : XmlWhitespace
CL     XmlUrlResolver : XmlResolver
CL     XmlValidatingReader : XmlReader
CL     XmlXapResolver : XmlResolver
CL     XmlBinaryReaderSession
CL     XmlBinaryWriterSession
CL     XmlCDataSection
CL     XmlNamedNodeMap

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)