Conceptual Contexts
- Differing Computing Areas Often Share The Same Underlying Concepts
- A Hypergeneric Component Facilitates Accumulative Programming
- Security Benefits
Last updated on 10-16-22.
Differing Computing Areas Often Share The Same Underlying Concepts
Every programming subject currently sits in its own silo
A graphics software engineer might find himself a programming novice when he ventures into an area outside of his expertise, like constructing a personal website with a database behind it; it won't take him as long as a complete beginner to pick up the basics, but it will take time. All of his experience in graphics programming that carries similar concepts with database work is of little assistance. He still needs to dig into database documentation, look up the individual calls and what they do, and examine the syntax. Specifics of web pages need to be looked up constantly as well. Then, he starts tinkering to get the website up and running. If he needs to make use of network sockets, that is another topic altogether, and this routine starts all over again, even though all of these subjects share conceptual characteristics.
In computer programming, acquiring more information does not translate to better mastery. Often it leaves a person collecting facts about how to do specific things. New information should supplement the skills that are already there, tying into a larger picture, but that is normally only true in a small way. Usually, a great deal of time is spent on the specific conventions of a programming subject, and although many aspects feel or look the same as other topics, they never have practical links connecting them.
Here is an illustration of programming silos just talked about. Accessing data for the same underlying concept, row, is given different conventions for different areas of computing, and we give some generalized examples below:
- Image files: pixelsForRow()
- Web Pages: <tr>
- Spreadsheets: spreadsheetRow
- Databases: SELECT row FROM table
- Plain Text Files: stringAtLineNumber()
In a new programming environment, each of these variables will be accessed with the same exact term: — row. The concept is row, then, and the programing environment knows what it is used for according to context.
The system will know, for example, that when — row is placed next to an image, it means something different (a row of pixels) than when it is placed next to a web page table (a row of cells).
Here are other terms that are similarly recurrent across computer programming, but are always represented with unique names for their specific silos:
These are just three terms, but it is striking how broadly they apply across all sorts of subjects in computer programming, from a 3D modeler's scene tree to a filesystem directory, to a data structure (e.g. spatial indexing), to a web page DOM. In each of these topics, there will be very particular ways of handling a tree, a root node, and child nodes.
The following three terms are also very generic:
width
height length
If the subject's context is acknowledged at all times, it will be possible to utilize the same term, length, for a large variety of situations:
- the length of a line
- the length of a stream of bytes
- the length of a string (the character count)
In this case, length is the concept, and the programming environment recognizes all kinds of terms like these. It knows how they are used in different contexts.
The code conventions used to operate on a grid of image pixels will be the same ones used to operate on a table of spreadsheet data. Both share the fact of having rows, columns, and element counts for each.
Access the image's (
img1) row count by typing 🖼 img1rowcount.
Access the data table's column count by typing 📄spreadsheet_1 columncount.
This is more fitting for programming code than any programming language we have today because, with either the row's count or the column's count, these terms could apply to all sorts of situations. The terms are not limited to one specific context, which is what we have today in code, everywhere.
When the context of programming language vocabulary is not acknowledged, a profileration of data types and variable names occurs. Each and every occurrence of a row has to have its own isolated data structure(s) provided or accessed by the programmer.
How to approach most programming situations can be plotted out from the start by the programmer if there is a large body of generic conventions. What the programmer will start with is the programming system's generic conventions and get specific from that point forward. It won't start with what specific names the system needs for each aspect of the program. This will produce programming far superior to looking up or memorizing a multitude of solutions for specific circumstances. The popularity of the website StackOverflow is a consequence of how programming starts with separated definitions for each and every tiny thing.
Taking something obscure: if you want to reduce the number of digits following a decimal point, you don't need to look up any syntax particulars in this scheme because you know the keyword truncate exists. If you add truncate right before the real number, you get the truncated decimal value. But truncate can also truncate a geometric shape, like a cone or a triangle. Combinations of established terms is certainly a bright path for future code.
Today's Emphasis on Individual Functions Creates Thousands of Functions
The focus of programming today is at the functional and practical level, and big concepts are implemented through long lists of function names. Functions that share similar concepts, sitting in different parts of the operating system, are unable to be grouped underneath a single category, to allow approaching differing computing subjects from a single starting point.
But also, today's computing environment is not structured in a way that allows approaching a software project with a broad outline, a loosely defined starting point, and then gradually building up, shaping, and specifying the code's functional aspects, to ultimately arrive at a concrete outcome, an accumulative way of programming in other words.
Instead, the computer requires that the programmer seek out a selection of hundreds or thousands of specific, predefined functions, then use these individual functions in combination, putting them through logic trees, arranging them into a sequence of rigid steps. This programming philosophy aims to deliver a concrete outcome as soon as a single step is taken, and the field of view for the programmer at any point is extremely narrow. Every computational move requires its own, idiomatic function signature. Each task is matched to an isolated function.
The result is that nothing is ever interrelated in the computer for programming. A software engineer always has to look up some amount of information for basic tasks, no matter how experienced he is, because every action of code is rooted in the specific and defined. The volume of tiny pieces to know about the computer becomes extensive and involved, piling on details. There is barely any attempt to apply a concept from one area of computing into another for the purpose of making the computer easily cross-programmable. This topic, cross-programmability, can be described as the use of computers being conceptual first and functional second. In other words, the person starts with row when programming anything containing a row of data, no matter the data type or subject matter.
What Programmers Should Want Are Multi-Terrain Code Keywords
An analogy for cross-programmability in the real world is the expectation that the same kind of golf clubs will work for all golf courses across the world, no matter the courses' variations in terrain. What a golfer cares about is the game of golf first, and the terrain of any specific golf course isn't so important that he has to use a custom set of golf clubs to match it.
But on the computer, there is such a phenomenon. Every golf course that the golfer wishes to play requires that he become proficient with its own, idiosyncratic offering of golf clubs, which produce their own physical effects, because they were made in response to the course's individual landscape. He can play the game normally, on each golf course, only by purchasing golf clubs specific for that course. The result: the golfer's garage is loaded with hundreds of golf clubs, corresponding to where he expects to play. There are golf instructors, not for the game of golf, but for the game as it is played on each specific course. When the golfer enters an unfamiliar course, it is like learning the game all over again in certain ways because each golf club has its specific demands.
Cross-programmability Starts with Identifying Patterns
There are patterns across computers everywhere, and they should each be brought together under a single heading. Although the commands that a programmer uses for describing user interactions with the mouse, keyboard, and computer won't help him when it is time to undertake a networking software project, there are some shared characteristics between the two areas, that there is back and forth between one entity and another, that there is logic and state that sits between them (related to what is called "workflow"). Workflow applies to complex mouse and keyboard interactions in a way that could also be applied to processing network data.
There has been no effort to recognize the overall patterns in computing and establish them as universal foundations for the task of software programming. As it stands today, the commands used to work with a grid of tabular (e.g. spreadsheet) data won't ever be related to the two-dimensional layout of data found in a raster image file, even though both are conceptually the same in respect to holding grids of data. They share this underlying concept, but have no links between them, simply because they are different topics.
This is an opportunity to establish higher-level concepts in computer programming that are implemented to span multiple computing subjects— functions to be conceived of broadly rather than just for a particular subject. If there were such programming schemes in practice today, the programmer would know how to manipulate an image with the same groups of commands that he uses to operate on a table of data; he would know how to approach most tasks without consulting documentation.
The foundations of this kind of programming start with identifying and relating processes that apply across the computer. An image filter operates on a grid of numerical values. This is comprised of rows and columns. But so is a spreadsheet table of data comprised of rows and columns. Likewise, a print design grid that holds page layout elements is a grid. A triangular mesh is also a grid. The values in a math matrix are displayed in grid form, too. So, for programming all of these topics, we would start with grid.
This is identifying conspicuous themes found in the exterior and interior features of many different, mainstream programming topics, and then coalescing them into generic starting points.
The First Move When Writing a Section of Code
To give another example, the approach a programmer takes to make a union of two bezier paths today will have nothing to do with the task of making a union of two string arrays, even though the starting command in both circumstances could be made the same. If it were all that way, the software engineer would be thinking, "I need to combine and make a union," instead of "what is the function to make a union for paths?" and "what is the function to make a union of two arrays?" The gap between those two modes of programming the computer is vast, with our current one sending us into tiny crevices.
Computing areas with shared underlying concepts should share the same initial programmatic approach, for sure, and then gradually specify what they do and what they need, according to their own subject matter and concrete outcomes.
It isn't precisely the same topic, making a union of arrays (or sets) and making a union of bezier paths. They are different fields of study. But for someone who uses or programs a computer, the broader classification is what matters initially. There is a common starting point that will make programming independent of upfront specificity.
Tying the earlier examples together, it is also worth noting that a union operation can be understood by anyone as being applicable to table of data as well as an image file's pixels. You would just have to specify, after calling a generic union operation ∪, how it would relate specifically to either the table cells or the image pixels.
As we all know, wherever a function like "union" sits in a given programming framework, it will exist in separate locations: one union function for a table cell group, one union function for image pixels.
What to do then? In fact, there are set operation symbols available in unicode, including
- ∪ (union)
- ∩ (intersection)
- ∖ (minus).
In a more generically-oriented programming environment, you do not need to express, right away, what you intend to do with these symbols ("I want to make an intersection of pixel data here and there"). You start at a generic level: "the intersection of something," the character ∩ or "the appending of something," the character +. The computer accepts that you intend to do an operation on or with some thing that exists within its wide range of capabilities. Then, you engage in progressively elucidating for the computer what the operation is all about by tacking on modifications, properties, and so on.
If the entire operating system were built up this way, many of the narrowest consulting jobs would become unnecessary, as everyone would know how to approach mundane tasks by starting with generic starting points (e.g. "I need to combine"). Are you wishing to append the contents of one text file to another (+)? Then you will add corresponding commands after that symbol to specify that, eventually arriving at the point you provide the titles of the files to be combined.
This is much more conceptual, as opposed to specific in its functional approach. The expertise sought out for programming would shift from how to make a computer do something within its specific conventions to what the computer is actually doing overall.
Redesign.Codes calls this accumulative programming. It is accumulative because there is buildup in the programmatic process rather than just immediate functions that demand, up front, all of the parameters that are specified.
A Hypergeneric Component Facilitates Accumulative Programming
A hypergeneric component is a Redesign.Codes programming concept. It is a slate onto which you build your programming specifications.
In computing, there are operations and concepts that can be discussed generically: input and output, streams, embedment of resources, etc.
We will start out with the grid hypergeneric component. The name is grid. Its component name doesn't stop at being generic, saying "a table of some data". That would certainly be generic. It is hypergeneric because it goes one level higher, grid, not even saying what general area of computing it pertains to.
What are the characteristics of a grid? There are rows and columns. That is all that is needed to qualify. Possibly it has visual properties, like spacing, if what is being described exists as a graphical representation like an HTML table, but in this type of programming that information will be specified in a cumulative way, arrived at later.
We know that a spacing property is not relevant to the grid of an image's pixels, but an image file is still is laid out as a grid conceptually. So, it is still placed underneath this hypergeneric component— a conceptual programming approach.
Using a grid hypergeneric component you can arrive at, and do work with, any of the following destinations (and others not listed) that have a relationship to a grid:
- Map tiles.
- A calendar.
- A table of spreadsheet data.
- An image file (its pixel locations).
- A graphical switchboard.
- Math matrices.
- A table of text in a page.
- A horizontally-arranged set of UI controls for a software application.
All of these and more are accessible through one universal component: grid. But not right away. You just say grid to start.
From there, you tell the computer what it will do by progressively attaching distinctions that customize it, moving it further away from a hypergeneric grid concept and into the functional and concrete that runs on a computer.
For example, a common usage of a graphic design grid is one that has offset rows. A keyboard qualifies. A keyboard is set on an offset grid, and it has some keys that are wider than others. But it would still start from the hypergeneric grid.
We want to make an onscreen (vector) keyboard that reflects whatever key has been pressed. The list below shows the hypergeneric commands. Note that wherever there are brackets with ellipses ([...]) we have stopped adding commands in order to maintain the brevity of this example.
▦GRID
- will be viewed as graphics (will be graphics-based).
- will have offset rows
- will have spacing
- will have customized or replaced elements
- [...]
- will have elements responding to state changes
- [...]
- final result will be output as vector
- output will be written to a file
- the location of the file is local
- the location of is [...]
- the location of the file is local
- output will be written to a file
The more commands you tack on, the closer you get to a final, concrete result. Sure, in a scheme like this there would be a lot of commands to tack on, but they add up in a way that relates. Additionally, the types of commands used underneath one hypergeneric component (grid) is available to other hypergeneric components, like circle, tree, and more.
Making a Generic Component out of a Hypergeneric Component
A hypergeneric grid component, once it is defined a certain amount (and has not been made to produce a concrete outcome yet), can be named and turned into a subtemplate: a generic component. A generic component is a little closer to a given topic. For example, there might be a generic component called "graphic design grid" and it has already been customized, from the grid hypergeneric component, to produce vector output for the purpose of drawing grids on pages. But, it leaves the rest for the programmer according to his needs.
Here are some examples of some subgeneric components of that design grid generic component:
- grid of ui controls - (any type of control can be placed on a grid)
- calendar - (calendar layout that still permits styling)
Security Benefits
Reverse Engineering Won't Be So Easy
A famous chip designer, responsible for the RISC architecture, was recently quoted as calling C++ "ancient." What does this mean? It does not mean that C++ is not the most powerful way to write code today, or that C++ does not contain advanced features and concepts that push it past where it was decades ago. But what it does mean is that the overall format of C++ is old.
Right now every operating system is a leaky bucket of security concerns, but it is no surprise because there is no way to track so much software that is always written at such a low level. The C language is really not that far away from assembly, C++ is not that far away from C, even though it is regarded as something independent today. C is often preferred by people who program for embedded systems because it is so close to machine instructions. Anything near the vicinity of C is no longer appropriate for the future of software, and it is leaving computer systems open to attack.
When writing software, whenever there is a major debugging error, the IDE will pop open a window showing the programmer the raw assembly code. This is when you are given a stark reminder: the assembly shown is quite close to the functions being written out in plain text code. It makes sense that a lot of hackers can get in there and create trouble.
It is now so easy and straightforward for hackers to take down a large corporation, on all operating systems, that major breaches now number in the dozen every year. It simply is not possible for this to happen if computer programming is restructured in a conceptual way because the hackers will not know where they are when they look at low-level code. None of the operating systems will have been written in the same way, which is what allows hackers to open up a disassembler and start finding ways to wreak havoc. Being a tinkerer won't let you take over a solidly-designed system; it can only let you take over something that is filled with weaknesses. Hackers can always be described in terms of fiddling around; they aren't writing real software.
