Information Computation means a process engaging a computer (a physical device) to process information as a series of actions or steps taken in order to achieve a particular result or help to fulfill a task. The main challenge is that information is abstract, it is a kind of knowledge that cannot be processed directly by any physical device.
This InformationComputation.sln
MS Visual Studio solution contains code snippets that by design are to be used as a set of extended examples to conduct online video courses or class lectures. The examples can also be used alone. To get more about extended examples check out the Programming in Practice - Executive Summary Udemy course.
Generally speaking, two main topics are covered by examples collected in this subsection. That is
- how to deal with the data recognized as the information representation of a state and behavior of a process in concern
- computer behavior description using a program implementing an appropriate algorithm.
To get more about the Information Computation
course on Udemy check out the Information Computation Course Description document.
This repository contains code examples related to the following topics
- Coding System versus Type - abstract information may be represented using a computer-aware stream of signs using a coding system. Because any computer is a binary machine it also must be a binary representation. The main goal of this subsection is to get more on how the coding system we used to represent information - that is abstraction - may be replaced by the type notion that is well known and widely accepted concept for modern programming languages. The types enable us to focus on the domain of values but not low-level values representation. The main goal of this part is the ability to recognize the types as an implementation of the information and algorithm.
- Custom Types The examples address the basic rules of the custom type definitions. Custom types are used to implement information and algorithm in concern because both are abstract and cannot be a direct subject of computation. The examples allow us to distinguish between value and reference types, get background related to static class, and reuse the singleton pattern. All of that we will discuss in the context of the examples gathered in the TP repository. Let me stress that this topic is also an introduction to object-oriented programming so intentionally I don't gather here all the available methods of types definitions.
- Object-oriented Programming - In my opinion, a key to understanding
Information Computation
related topics is a good understanding of the object-oriented programming concept as a method to solve problems involving instance operations of unknown type. Hence, I gonna collect here examples to recall the main principles of this concept. I will remind you of such object-oriented programming terms as class, interface, encapsulation, inheritance, implementation, polymorphism, and so forth. I will pay special attention to the constructs that are characteristic of these terms for example abstract and virtual members. I want to stress that not all programming languages provide the same constructs but we can find many similar ones, so I hope that this discussion will also help to reuse the learning outcomes and port them to other programming languages if needed. We will come back to this topic many times all the time. - Anonymous type - Let me recall that by design the strongly typed programming languages are leveraged. This means that the considered languages encourage and even force designers to use types for internal consistency checking of programs. The rules for checking the compatibility of types, apart from the rules for checking the syntax correctness of the program as one whole, must be recognized as fundamental mechanisms applied for validating the program content at design time. This strong typing approach undoubtedly increases the probability of program correctness in the context of internal information computation. If we want to pull or push data from/to external resources not directly managed by the runtime environment we must answer the question of what type they are. How to harmonize these external data types with the types defined in the program. In general, we can apply type definitions conversion, evaluate types at run time, or apply types correlation. Does it sound strange? I am pretty sure that the answer is yes. Now, the main goal is to learn more about it. Especially, let's talk about how the concept of anonymous type can help with this. I will try also to recall fundamentals related to dynamic type that can be applied to evaluate type at run time. The type conversion will be a subject of independent episodes embedded in separate courses, so I will only mention this mechanism in this lesson.
- Partial Definitions - limiting the scope of our discussion only to methods applicable at design time we know that for the strongly typed programming languages, the type of a variable may be devised by a developer or inferred by the compiler. We must keep in mind that there is a next option. Another possibility is an auto-generated text of the required type definition from metadata using a development tool. The main goal of these examples is to learn more details related to partial definitions that allow us to address this issue and avoid text conflicts. I will try to answer why we need this concept and associated language constructs to implement the separation of concern using this text management mechanism. Partial definitions are used to blend separate parts finally making up a type definition as one whole. The discussion will be general but conducted using a concrete language development environment. Hopefully, you will be able to leverage the learning outcomes in other development environments if needed.
- Generic Definitions - It is obvious that the possibility of reusing the outcome of previous programming work is extremely important because it improves economic efficiency, is beneficial for reliability, and minimizes training costs. Together it decreases the total costs of software program development. The examples gathered in this subsection allow you to learn how new custom types may be defined thanks to applying parametrized templates and improving this way reusability of previous work. We will learn more about generic types definitions. Because the generic definitions ensure repeatability we may recognize them as an alternative to object-oriented programming to a certain extent. This, as we know, decreases the total costs of software development. The main idea behind applying the generic types and methods is the possibility to use a kind of parametrized script to automatic generation the final custom type definition compliant with a template. Thanks to these examples you will gather more detail about the rules governing this text management mechanism.
- Program Layered Design Pattern - The main goal of these code examples is to learn more about the architecture of the computer program in the context of typical responsibilities related to streaming, structural and graphical external data access, and the process of software development. A computer program begins its life cycle as a text that follows the rules of a selected programming language. To decrease the cost and improve the performance of the program development process, the text of the program is often organized into autonomous fragments addressing typical responsibility. There are many design patterns applicable to help implement typical algorithms but the layered model is well-suited to be applied to the program as one whole. The main goal is to address the challenge of how to improve software development performance by applying the layered design pattern to the programs as one whole. We will also examine the benefits expected thanks to organizing the program text in compliance with this design pattern. We will learn this design pattern from the information computation point of view. System architecture and application architecture topics are out of the course scope. The purpose of the gathered here examples is to learn more about how to implement the layered design pattern. Applying these rules should be very easy to use this approach to deploy layers of books, carpets, and so ones. Unfortunately, any computer program begins its life cycle as a text that follows the rules of a selected programming language. You will learn how to decrease the cost and improve the performance of the program development process in the long run by organizing the program text into autonomous parts hierarchically related to each other. There are many design patterns applicable to help implement typical algorithms but the layered model is well-suited to be applied to the program as one whole.
- Inter-layers Communication - The main goal of the examples collected in this subsection is to learn more about the issues related to the deployment of the bidirectional communication of layers. We will start addressing the definition or rather a description of the communication concept pointing out that this term is related to the run-time stage of any program life cycle. Despite this, it must be programmed during the design time, hence, may be recognized as a crucial challenge for any software developer. It should introduce you to the topic of how to implement inter-layer bidirectional control and data flow using a unidirectional layered architecture. The examples are aimed to help deploy the bidirectional communication of layers stack. By design, the layered program design pattern means its organizations, in which we can distinguish independent entities of a program related to each other making a top-down hierarchy. The distinguishing feature of a layer is that all definitions belonging to a layer are self-contained internally in a layer or may refer only to the declarations visible from the layer below. In other words, the top-down relationship means that the layer above only refers to the declarations exposed by the layer below. It was stressed that it is a compile-time pattern. At run-time, we must consider control flow, data flow, and event notification in both directions. This time the examples are focused on deploying bidirectional communication using unidirectional layered architecture.
- Dependency Injection - In this part, I want to conclude topics related to algorithm implementation with a nontrivial example. You will learn more about the fundamentals of a dependency injection design pattern. There are two scenarios where we must bother with a problem that required instance operation referees to the type declaration that is invisible in a place of invoking the operation for some reason. You will learn that in that and similar occurrences, the dependency injection could help. To address this impossibility of instantiating a type in a location where it is invisible, we are using abstract variables to transfer an instance from the creation to the usage location. Previously we used it to implement inter-layer bidirectional communication implemented based on a unidirectional layered software program archetype where types defined in the upper layer are invisible by definitions belonging to the layer beneath. Now it is time to investigate this pattern in a more general context to use this pattern to solve also other problems. Thanks to the attached examples we could investigate the following scenarios: (a) program validation, (b) separation of concerns, (c) dependence on technology, (d) simultaneous development, and (e) determining the sequence of objects creation (populating a graph of objects). All the above topics except the last one (e) can be considered as a problem derived from dependency on invisible type definitions. To get straight to the point, we will try to understand the DI by examining the straightforward examples related to program validation only. Other topics have been already discussed so now we may safely skip detailed discussion of them.