├── .gitignore ├── .idea ├── .gitignore ├── codeStyles │ ├── Project.xml │ └── codeStyleConfig.xml ├── dbnavigator.xml ├── gradle.xml ├── kotlinc.xml ├── misc.xml ├── runConfigurations │ ├── AbstractClassExampleKt.xml │ ├── BoopExampleKt.xml │ ├── CoroutineExampleKt.xml │ ├── CoroutineVsThreadExampleKt.xml │ ├── FunctionalExampleKt.xml │ ├── InterfaceExampleKt.xml │ ├── LiskovSubstitutionPrincipleExampleKt.xml │ ├── MultipleInheritanceExampleKt.xml │ ├── StructuredExampleKt.xml │ ├── ThreadExampleKt.xml │ ├── TimeComplexityExampleKt.xml │ ├── TypesExampleKt.xml │ └── UsingClassesAsNameSpacesKt.xml ├── uiDesigner.xml └── vcs.xml ├── 02-TheEssentialQuestion-WhatAreWeComputing.md ├── 03-Hardware.md ├── 04-DataStructures.md ├── 05-Software.md ├── 06-HighLevelLanguages.md ├── 07-SoftwareDesign.md ├── 08-StructuredProgramming.md ├── 09-ClassOrientedProgramming.md ├── 10-FunctionalProgramming.md ├── 11-BackToObjectOrientedProgramming.md ├── 12-ParallelProcessing.md ├── 13-Conclusion.md ├── How_to_program_from_ground_up.iml ├── README.md ├── assets ├── 10mb_hard_disk.png ├── 2dArraysInC.png ├── 2d_arrays.png ├── 4004_simu_part.gif ├── 6502.png ├── 8-bit-binary.png ├── 8-bit-counting-2.png ├── ASCII-binary.png ├── BDUF.png ├── BDUF2.png ├── Computer_block_diagram.png ├── DRAM.png ├── MPU.png ├── Map.png ├── NAND_equivalent.png ├── NAND_gate.png ├── NAND_gate_package.png ├── ParallelProgramming │ ├── 2Options.png │ ├── VennDiagramParallelConcurrent.png │ └── sequential-concurrent-parallel.png ├── ROM.png ├── Why_NAND_gates_are_special.png ├── abacus.png ├── abacus2.png ├── agile-deliver-sooner-not-faster.png ├── agile-tm-r-c.png ├── alan_kay.png ├── andersons-law.png ├── arrays.png ├── ascii_hexadecimal.png ├── beads_on_string.png ├── bigo.png ├── bjarne2.png ├── bjarnestroustrup.png ├── break_thrus.png ├── chip-wired-to-package.png ├── click-green-arrow.png ├── computer_speed_miscommunicate.png ├── core_memory.png ├── cuneiform.png ├── electrical_outlet.png ├── electromagnet-with-switch.png ├── electromagnet.png ├── functional-chart-annotated-old.png ├── functional-chart-updated.png ├── functional-programming.png ├── hexadecimal.png ├── hollerith_counter.png ├── kotlin-book.png ├── linkedList.png ├── logic-gate-package.png ├── logicGateSymbols.png ├── magnetic_viewer.png ├── mermaid_test.md ├── motivational_debt.png ├── mutability-chart.png ├── new_compassionate_dev.png ├── pacman_bytes.png ├── paper_ledger.png ├── phyiscal_indentations.png ├── plugs_and_adapters.png ├── pointer.png ├── proceduralProgrammerMadeLoops.bas ├── proceduralUnrolledLoops.bas ├── proceduralWithForLoop.bas ├── proceduralWithGosub.bas ├── proceduralWithGoto.bas ├── programs_for_people.png ├── punched_card.png ├── pyramid_of_results.png ├── queue.png ├── race-condition-quote.png ├── seven_segment │ ├── 7-segment-BCD-block-diagram-displaying-5.webp │ ├── 7-segment-display-truth-table.webp │ ├── 7-segment-display.webp │ ├── 74HC42.jpg │ ├── BCD-to-7-Segment-Display-Decoder.png │ ├── BCD-to-7-segment-Decoder-Design-Using-Basic-Gates.jpg │ ├── Internal-Schematic-Common-Cathode-7-Segment-LED-Display.png │ ├── Inverter-Gate-and-NAND-gate-under-50x-microscope.png │ ├── Schematic-of-BCD-to-Decimal-Decoder.png │ └── Seven_segment_01_Pengo.jpg ├── simpleSwitch.png ├── spiral_model.png ├── spiral_of_evolution.png ├── stack.png ├── strings.png ├── test.md ├── the_ic.png ├── things-to-know.png ├── thread-time-diagram.png ├── title.png ├── toaster.png ├── transistor-electron-microscope.png ├── transistor_vs_tube.png ├── trash-driven-dev.png ├── tree.png ├── tutorial-tar-pits.png ├── tv_with_plug.png ├── vacuum_tube.png ├── vacuum_tube_diagram.png ├── williams_tube.png ├── williams_tube2.png ├── williams_tube3.png └── yegor_bugayenko.png ├── build.gradle.kts ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── settings.gradle.kts └── src └── main └── kotlin ├── Main.kt ├── abstractClassExample.kt ├── boopExample.kt ├── controlledVisibilityExample.kt ├── coroutineExample.kt ├── coroutineVsThreadExample.kt ├── functionalExample.kt ├── inheritanceExample.kt ├── interfaceExample.kt ├── liskovSubstitutionPrincipleExample.kt ├── multipleInheritanceExample.kt ├── sideEffectsExample.kt ├── structuredExample.kt ├── threadExample.kt ├── timeComplexityExample.kt ├── typesExample.kt └── usingClassesAsNameSpaces.kt /.gitignore: -------------------------------------------------------------------------------- 1 | .gradle 2 | build/ 3 | !gradle/wrapper/gradle-wrapper.jar 4 | !**/src/main/**/build/ 5 | !**/src/test/**/build/ 6 | 7 | ### IntelliJ IDEA ### 8 | .idea/modules.xml 9 | .idea/jarRepositories.xml 10 | .idea/compiler.xml 11 | .idea/libraries/ 12 | *.iws 13 | *.iml 14 | *.ipr 15 | out/ 16 | !**/src/main/**/out/ 17 | !**/src/test/**/out/ 18 | 19 | ### Eclipse ### 20 | .apt_generated 21 | .classpath 22 | .factorypath 23 | .project 24 | .settings 25 | .springBeans 26 | .sts4-cache 27 | bin/ 28 | !**/src/main/**/bin/ 29 | !**/src/test/**/bin/ 30 | 31 | ### NetBeans ### 32 | /nbproject/private/ 33 | /nbbuild/ 34 | /dist/ 35 | /nbdist/ 36 | /.nb-gradle/ 37 | 38 | ### VS Code ### 39 | .vscode/ 40 | 41 | ### Mac OS ### 42 | .DS_Store -------------------------------------------------------------------------------- /.idea/.gitignore: -------------------------------------------------------------------------------- 1 | # Default ignored files 2 | /shelf/ 3 | /workspace.xml 4 | # GitHub Copilot persisted chat sessions 5 | /copilot/chatSessions 6 | -------------------------------------------------------------------------------- /.idea/codeStyles/Project.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 11 | 12 | 13 | 14 | 15 | 21 | 22 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /.idea/codeStyles/codeStyleConfig.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | -------------------------------------------------------------------------------- /.idea/gradle.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 16 | 17 | -------------------------------------------------------------------------------- /.idea/kotlinc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.idea/runConfigurations/AbstractClassExampleKt.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 20 | -------------------------------------------------------------------------------- /.idea/runConfigurations/BoopExampleKt.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 20 | -------------------------------------------------------------------------------- /.idea/runConfigurations/CoroutineExampleKt.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 20 | -------------------------------------------------------------------------------- /.idea/runConfigurations/CoroutineVsThreadExampleKt.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 20 | -------------------------------------------------------------------------------- /.idea/runConfigurations/FunctionalExampleKt.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 20 | -------------------------------------------------------------------------------- /.idea/runConfigurations/InterfaceExampleKt.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 20 | -------------------------------------------------------------------------------- /.idea/runConfigurations/LiskovSubstitutionPrincipleExampleKt.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 20 | -------------------------------------------------------------------------------- /.idea/runConfigurations/MultipleInheritanceExampleKt.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 20 | -------------------------------------------------------------------------------- /.idea/runConfigurations/StructuredExampleKt.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 20 | -------------------------------------------------------------------------------- /.idea/runConfigurations/ThreadExampleKt.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 20 | -------------------------------------------------------------------------------- /.idea/runConfigurations/TimeComplexityExampleKt.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 20 | -------------------------------------------------------------------------------- /.idea/runConfigurations/TypesExampleKt.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 20 | -------------------------------------------------------------------------------- /.idea/runConfigurations/UsingClassesAsNameSpacesKt.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 20 | -------------------------------------------------------------------------------- /.idea/uiDesigner.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /02-TheEssentialQuestion-WhatAreWeComputing.md: -------------------------------------------------------------------------------- 1 | # THE ESSENTIAL QUESTION IN COMPUTING - What Are We Representing with Digital Information? 2 | - Everything in computing is REPRESENTING digital information "as" something _else_. 3 | - Kinds of representations through history: 4 | 5 | > DIGITAL COMPUTER TECHNIQUES & PRINCIPLES 1962 U.S. NAVY FILM UNIVAC IBM ELECTRODATA 6 | > - https://www.youtube.com/watch?v=hTJi7Ct6MfY 7 | 8 | - ## Knots & Beads on a string - prehistoric, 6000 BC to 1500 AD 9 | 10 | [](https://www.peruforless.com/blog/quipu/) 11 | 12 | - ## Physical indentations in clay — 8000 BC to 100 AD 13 | 14 | [](https://www.thoughtco.com/clay-tokens-mesopotamian-writing-171673) 15 | [](https://www.thoughtco.com/clay-tokens-mesopotamian-writing-171673) 16 | 17 | - ## Beads on an abacus - 3000 BC to present 18 | 19 | [](https://en.wikipedia.org/wiki/Abacus) 20 | 21 | - ## Ink Marks on paper - 3000 BC to present 22 | 23 | [](https://www.moderntreasury.com/journal/history-of-ledgers) 24 | 25 | - ## Positions of sticks seen at a distance (Semaphores) - 1790s to 1850s 26 | > - TeleCommunication: Semaphore Systems 27 | > - https://www.youtube.com/watch?v=muMXPVCMI5o 28 | 29 | - ## Punched Holes in a paper card - 1800s to 1970s 30 | - Vast improvement over the paper ledger 31 | - Collection of data was standardized, fast and could be read by a machine 32 | - Data collected from the 1890 US Census was the first large scale use of punched cards 33 | - Allowed for the first "programmable" machines that could be used to perform relatively complex tasks 34 | like sorting and counting of specific data 35 | 36 | [](https://en.wikipedia.org/wiki/Punched_card) 37 | [](https://en.wikipedia.org/wiki/Hollerith_machine) 38 | 39 | > - 1889 Herman Hollerith Census Machine by TMC which became IBM 40 | > - https://www.youtube.com/watch?v=9HXjLW7v-II 41 | > - PUNCHED CARD DATA PROCESSING INTRODUCTION IBM 42 | > - https://www.youtube.com/watch?v=etu-cH-nkIA 43 | 44 | - ## Remnants of photons hitting a piece of glass coated with a thin layer of phosphor - 1940s to 1980s 45 | 46 | [](https://en.wikipedia.org/wiki/Williams_tube) 47 | [](https://en.wikipedia.org/wiki/Williams_tube) 48 | [](https://ub.fnwi.uva.nl/computermuseum/williamstube.html) 49 | 50 | > - Cathode ray tube - Maltese Cross (NCPQ) 51 | > - https://www.youtube.com/watch?v=aT_hzeeFhgE 52 | > - Cathode ray tube magnetic deflection by horseshoe magnet 53 | > - https://www.youtube.com/watch?v=IkcHPmuDw7A 54 | > - Cathode rays deflection using an electromagnet perpendicular to the beam 55 | > - https://www.youtube.com/watch?v=NFeJ0XbY1J8 56 | > - Manchester Baby and the birth of Computer Memory 57 | > - https://www.youtube.com/watch?v=SpqayTc_Gcw 58 | 59 | - ## Magnetic Phenomenon - 1950s to present 60 | - Electronically detectable areas on magnetizable material, or the presence of a magnetic field in a specific area 61 | 62 | > Magnetic Fields "Bending" Light Paths 63 | > - https://www.youtube.com/watch?v=GpEi-jSmcoA 64 | 65 | - Core Memory - 1955 to 1975 66 | 67 | [](https://en.wikipedia.org/wiki/Core_memory) 68 | 69 | - Magnetic Tape - 1928 to present 70 | - "Sequential" access to data, like a cassette tape or a VHS tape. 71 | 72 | [](https://www.youtube.com/watch?v=aZOxn8ggX8w) 73 | > The Magnetic Tape Viewer - see the sound on a tape 74 | > - https://www.youtube.com/watch?v=aZOxn8ggX8w 75 | 76 | - Magnetic Disk - 1956 to present 77 | - "Random" access to data, like a record player or a CD player, and uses mechanical means to access the data 78 | 79 | - [](https://en.wikipedia.org/wiki/IBM_305_RAMAC) 80 | 81 | - ## Tiny electrical charge of a capacitor (a simple gap between metal plates) in a tiny area of space - 1960s to present 82 | - DRAM (Dynamic Random Access Memory) Chip (10x magnification), not mechanical at all, just electrical. 83 | 84 | [](https://en.wikipedia.org/wiki/Dynamic_random-access_memory) 85 | 86 | - ## Creating ANY machine capable of using "Boolean Logic" enables humans to create complex, custom general solutions to certain kinds of problems. 87 | - The problems must be able to be represented with binary information and the solution must be able to be 88 | represented with a series of logical operations. 89 | - By building up from the simple logic of `AND`, `OR`, and `NOT` operations, humans can create an 90 | arbitrarily complex sequence of logical operations. 91 | - These logical operations are sequenced in time to create ["State Machines"](https://www.youtube.com/watch?v=lffJJbqt1fk) that can perform complex tasks 92 | and solve complex problems. A state machine is simply a way of representing the problem that changes over time 93 | controlled by a series of logical operations & conditions that lead to certain states and available actions. 94 | - These logical operations are built up using patterns called "algorithms" grouped together in "programs" that 95 | can be executed by any digital computer, no matter what the underlying hardware is. 96 | 97 | > ## All of this "technology" is based on human ingenuity and cleverness to exploit certain properties of naturally occurring phenomenon in a way to create some "useful human work". 98 | >> ### The machines cannot possibly "know" anything about the problem or solution, and NEVER WILL. 99 | 100 | ### It's just following the logical operations that humans have carefully designed to represent the problem and represent a solution. 101 | 102 | - ## Spiral Model of Development of Techniques in Computing 103 | - As knowledge and techniques in computing have developed, they have built upon each other in a spiral pattern. 104 | 105 | [](https://en.wikipedia.org/wiki/Spiral_model) 106 | - Ideas and techniques from the past are often re-discovered and re-used in new ways. 107 | 108 | - [Continue Reading - Hardware](./03-Hardware.md) 109 | - [Back to Index](README.md) -------------------------------------------------------------------------------- /06-HighLevelLanguages.md: -------------------------------------------------------------------------------- 1 | # High-Level Languages (1957-Present) 2 | ###### high-level-languages 3 | - ### BIG IDEA - English-like commands are easier for people to read and understand than cryptic assembly language. 4 | 5 | - High-level meaning more friendly to humans to work with, not necessarily more powerful or faster for the 6 | computer to execute. 7 | - The first high-level languages were merely Assemblers that naively translated the mnemonics directy into machine 8 | code for the CPU. 9 | - The next step was to create a language that was more "abstracted" meaning "general purpose" and "portable" 10 | than assembly language, meaning source code from one machine could be run on another machine with a different CPU. 11 | - All languages, no matter how sophisticated, must eventually translated into machine code for a CPU to execute. 12 | - The High-level languages allowed for more widespread adoption of computers and programming, as the languages were 13 | easier to learn and use than Assembly Language. 14 | 15 | ## Programming Styles 16 | ###### programming-styles 17 | - The first programming styles were direct descedants of assembly language, and worked in the same way. 18 | - This way of working is generally referred to as "imperative" programming, as the programmer is giving the 19 | computer the exact set of steps to perform to solve a problem. There is another style of programming called 20 | "declarative" which we shall discuss later. 21 | - The Impact of BASIC (Beginner's All-purpose Symbolic Instruction Code) on the world of programming cannot be 22 | overstated. It was the first language that was easy to learn and use, and was widely adopted by schools and 23 | hobbyists. 24 | > - BASIC at 50 (Bill Gates Cameo) 25 | > - https://www.youtube.com/watch?v=gxo9LVIgOiI 26 | > - Birth of BASIC 27 | > - https://www.youtube.com/watch?v=WYPNjSoDrqw 28 | > - BASIC: The Famous Programming Language in 100 Seconds 29 | > - https://www.youtube.com/watch?v=SrhcpOWScNM 30 | 31 | # Procedural Programming Style (1957-Present) 32 | ###### procedural-programming 33 | - ### BIG IDEA - Using `GOTOs` to jump around the program was an unscalable idea leading to unmaintainable code! We need to a better way! 34 | 35 | - Procedural code is executed top to bottom, one line at a time. 36 | - Control flow is done with `IF` and `GOTO` statements. 37 | - `GOTO` was still commonly used to control flow of execution, as most people didn't know how to use 38 | "subroutines" yet. 39 | - `GOTO` was easier to understand, at least first... (DUN, Dun, dun...) 40 | - This style of programming was extremely successful from 1957 to 1990's, and is still used today mostly in banking. 41 | > Computing and Computers - Batch Processing - BBC2 - 1980 42 | > - https://www.youtube.com/watch?v=fAselhq0Q8g 43 | 44 | > - Online playground to try these programs in Applesoft BASIC (from the 1980's Apple IIe) 45 | > - https://www.calormen.com/jsbasic/ 46 | - Some examples of Procedural languages are "Fortran" and "BASIC" and "COBOL." 47 | 48 | - ## Example of the Problem with Abusing the `GOTO` Command in Procedural Programming Style BASIC 49 | - ###### abusing-goto 50 | ```Text 51 | 5 REM PROGRAM TO ADD 2 NUMBERS, PRINT RESULT <-- "REM" is a "remark" or "comment" 52 | 10 LET X = 10 <-- "LET" is a "expression" because it assigns a value to a variable; All variables are global and mutable. 53 | 20 LET Y = 32 54 | 30 GOTO 100 <-- "GOTO" is a "statement" that changes the next line to execute to a different line. 55 | 40 PRINT "Output: "; Z 56 | 50 GOTO 150 57 | 60 IF X = 10 THEN GOTO 190 58 | 70 GOTO 10 59 | 100 REM ADD 2 NUMBERS, RESULT IN Z 60 | 110 LET Z = X + Y <-- All variables are global and mutable 61 | 120 GOTO 40 62 | 150 PRINT "THIS GOTO STUFF CAN GET CONFUSING" 63 | 160 GOTO 60 64 | 190 PRINT "HOW DID I GET HERE?" 65 | 220 END 66 | 67 | RUN 68 | 69 | Output: 42 70 | THIS GOTO STUFF CAN GET CONFUSING 71 | HOW DID I GET HERE? 72 | 73 | ``` 74 | - [Click for source code to copy and paste into the BASIC playground: `proceduralWithGoto.bas`](assets/proceduralWithGoto.bas) 75 | 76 | - ## Solution: The Painful Push for Subroutines & Some Structure 77 | - ###### solution-subroutines 78 | - ### BIG IDEA - Reusable functions and procedures to avoid "spaghetti code" and enable working on teams. 79 | 80 | - Programmers were eventually forced into using "subroutines" to deal with extreme overuse of `JUMP` and `GOTO` 81 | statements common to programming at that time which lead to extremely confusing, unreadable and unmaintainable 82 | "spaghetti code", so named because of the way the `GOTO` statements would jump around the program and get mixed 83 | up like a plate of spaghetti. 84 | - These subroutines are referred to "functions," "procedures," and "methods" in modern programming languages. 85 | - The "subroutines" are usually called and returned using a "stack" to keep track of where the program left off, 86 | instead of having to use `GOTO` statements 87 | - Variables were usually "global" and "mutable" which lead to "side effects" and hard to understand "state" of the program 88 | - Each program was very "linear," "sequential," "imperative," and not portable or reusable, which lead to a lot of waste 89 | - Data and Code were kept separate. 90 | - Code was loaded into the computer, and then data was separately loaded and processed in "batches" 91 | - ### Example of Procedural BASIC with Subroutines and `GOSUB`'s 92 | - (the `GOSUB` command means `GO` to a "`SUB`routine"): 93 | ```Text 94 | 5 REM PROGRAM TO ADD 2 NUMBERS, PRINT RESULT USING GOSUB 95 | 10 LET X = 10 96 | 20 LET Y = 32 97 | 30 GOSUB 100 98 | 40 PRINT "Output 1: "; Z 99 | 50 LET X = 110 100 | 70 GOSUB 100 101 | 80 PRINT "Output 2: "; Z 102 | 90 END 103 | 100 REM ADD X + Y NUMBERS, RESULT IN Z <-- This start of a "subroutine", REM is a "remark" or "comment" and is ignored by the program 104 | 110 LET Z = X + Y 105 | 120 RETURN <-- end of a "subroutine", return execution to the line after the "GOSUB" statement 106 | 107 | RUN 108 | 109 | Output 1: 42 110 | Output 2: 142 111 | 112 | ``` 113 | - [Click for source code to copy and paste into the BASIC playground: `proceduralWithGosub.bas`](assets/proceduralWithGosub.bas) 114 | 115 | - ## Problem: Naive Solutions to Common Programmer Problems Lead to for High-Level Language Features 116 | - ###### naive-solutions 117 | - One problem with the low-level languages is that every programmer was left to their own creativity in how to 118 | structure their code, and this lead to a lot of "reinventing the wheel" and strange solutions that were hard to 119 | understand and maintain. 120 | - ### Example of a Common Naive Solution to Looping using `GOSUB` 121 | - This approach is called an "unrolled loop", because each step is imperative and "unrolled" from the loop. 122 | - Interesting note: compilers will often "unroll" loops to make the code faster because it reduces the number of 123 | "conditional" statements that the CPU has to execute. 124 | ```Text 125 | 5 REM PROGRAM TO DEMO "WITHOUT LOOPS" TO CREATE A CUMULATIVE ADDITION TABLE 126 | 10 LET A = 1 127 | 20 GOSUB 400 128 | 30 PRINT A, B 129 | 40 LET A = A + 1 130 | 50 GOSUB 400 131 | 60 PRINT A, B 132 | 70 LET A = A + 1 133 | 80 GOSUB 400 134 | 90 PRINT A, B 135 | 100 LET A = A + 1 136 | 110 GOSUB 400 137 | 120 PRINT A, B 138 | 130 LET A = A + 1 139 | 140 GOSUB 400 140 | 150 PRINT A, B 141 | 160 LET A = A + 1 142 | 170 GOSUB 400 143 | 180 PRINT A, B 144 | 190 LET A = A + 1 145 | 200 GOSUB 400 146 | 210 PRINT A, B 147 | 220 LET A = A + 1 148 | 230 GOSUB 400 149 | 240 PRINT A, B 150 | 250 LET A = A + 1 151 | 260 GOSUB 400 152 | 270 PRINT A, B 153 | 280 LET A = A + 1 154 | 290 GOSUB 400 155 | 300 PRINT A, B 156 | 310 END 157 | 400 REM ADD A PLUS B, RESULT IN B 158 | 410 LET B = A + B 159 | 420 RETURN 160 | 161 | RUN 162 | 163 | Output: 164 | 1 1 165 | 2 3 166 | 3 6 167 | 4 10 168 | 5 15 169 | 6 21 170 | 7 28 171 | 8 36 172 | 9 45 173 | 10 55 174 | 175 | ``` 176 | - [Click for source code to copy and paste into the BASIC playground: `proceduralUnrolledLoops.bas`](assets/proceduralUnrolledLoops.bas) 177 | 178 | - ## Problem: Imperative "Looping" Style Leftover From Assembly Language 179 | - ###### problem-imperative-looping 180 | - An example of common way of creating loops was to use `GOTO` and variables as indexes (also called "counters" or "iterators" or "loop variables") 181 | - In this case, its easy to see that the variable "A" is being used as an index to control the loop 182 | that repeats the code between line 20 and 50, 10 times. 183 | - This is OK for small programs, but when programs become larger and more complex, it becomes more difficult to understand exactly what the 184 | variables are used for, especially in a large program with many variables. 185 | - This style of programming is called "imperative" programming, as the programmer is giving the computer the exact set of steps to perform to solve a problem. 186 | ```Text 187 | 5 REM PROGRAM TO DEMO "FOR LOOP" TO CREATE A CUMULATIVE ADDITION TABLE 188 | 10 LET A = 1 189 | 20 GOSUB 100 190 | 30 PRINT A, B 191 | 40 LET A = A + 1 192 | 50 IF A <= 10 THEN GOTO 20 <-- This is the "loop" that repeats the code between line 20 and 50, 10 times 193 | 60 END 194 | 100 REM ADD A PLUS B, RESULT IN B 195 | 110 LET B = A + B 196 | 120 RETURN 197 | 198 | RUN 199 | 200 | Output: 201 | 1 1 202 | 2 3 203 | 3 6 204 | 4 10 205 | 5 15 206 | 6 21 207 | 7 28 208 | 8 36 209 | 9 45 210 | 10 55 211 | ``` 212 | - [Click for source code to copy and paste into the BASIC playground: `proceduralProgrammerMadeLoops.bas`](assets/proceduralProgrammerMadeLoops.bas) 213 | 214 | - ## Solution: Use a High-Level Language Command (Like `FOR`/`NEXT`) to Create a "Standard" Loop instead of `GOTO` and `IF` 215 | - ###### solution-declarative-for-loop 216 | - ### BIG IDEA - We can standardize common use-cases (like looping) into the language to reduce programming time, communicate intent of code to other people and minimize errors. 217 | 218 | - The `FOR` "loop" command was introduced to replace the programmer-implemented `GOTO` looping 219 | implementations, as an attempt to make procedural code more structured and readable. 220 | - Now, when a programmer sees the `FOR` command, they know that a loop is being created, and they can 221 | easily understand the structure of the loop, saving time and reducing errors. 222 | - Using `FOR` in this way is much easier to understand and maintain than the previous examples. 223 | - Using the language command `FOR` in this way is also called `declarative` programming, as the programmer is 224 | declaring what they want to happen, rather than imperatively telling the computer what to do step by step. 225 | 226 | - ### Example using BASIC's `FOR` Loop 227 | ```Text 228 | 5 REM PROGRAM TO DEMO "FOR LOOP" TO CREATE A CUMULATIVE ADDITION TABLE 229 | 10 FOR A = 1 TO 10 STEP 1 <-- The "FOR" statement changes the value of "A" from 1 to 10, incrementing by 1 at each NEXT statement 230 | 15 GOSUB 100 231 | 20 PRINT A, B 232 | 30 NEXT A <-- Execution continues at line after the "FOR" statement (15), unless "A" is 10, then it goes to next line (40) 233 | 40 END 234 | 100 REM ADD A PLUS B, RESULT IN B 235 | 110 LET B = A + B 236 | 120 RETURN 237 | 238 | RUN 239 | 240 | Output: 241 | 1 1 242 | 2 3 243 | 3 6 244 | 4 10 245 | 5 15 246 | 6 21 247 | 7 28 248 | 8 36 249 | 9 45 250 | 10 55 251 | ``` 252 | - [Click for source code to copy and paste into the BASIC playground: `proceduralWithForLoop.bas`](assets/proceduralWithForLoop.bas) 253 | > ### NOTE: The process we just went through "to change code but doesn't change behavior" is called "Refactoring" and is a common practice in programming to make code more readable and maintainable. 254 | 255 | - [Continue Reading - Software Design](./07-SoftwareDesign.md) 256 | - [Back to Index](README.md) 257 | -------------------------------------------------------------------------------- /07-SoftwareDesign.md: -------------------------------------------------------------------------------- 1 | # Software Design 2 | 3 | - ### BIG IDEA — How do we talk about these things with other people efficiently and effectively? 4 | 5 | ## Algorithms - How are we gonna solve this? 6 | ###### algorithms 7 | - ### BiG IDEA - Let's give names to the clever ways we humans have found to solve problems. 8 | 9 | - Algorithms are just a set of instructions that are used to solve a problem or perform a task, all based on the 10 | cleverness and creativity of the designer. People have invented many ways to solve problems, and some of these 11 | are so common that they have been given names, like "sorting" and "searching" algorithms. 12 | > - Binary Search Algorithm - Code walk-through and Complexity Analysis 13 | > - https://www.youtube.com/watch?v=LdjkZ2vQapI 14 | > - Animated Interactive Visualizations with pseudocode for many common data structures 15 | > - https://www.cs.usfca.edu/~galles/visualization/Algorithms.html 16 | > - Quick Sort [Visual Explanation] 17 | > - https://www.youtube.com/watch?v=WprjBK0p6rw 18 | > - 15 Sorting Algorithms in 6 Minutes 19 | > - https://www.youtube.com/watch?v=kPRA0W1kECg 20 | > - Sorting Algorithms Explained Visually 21 | > - https://www.youtube.com/watch?v=RfXt_qHDEPw 22 | 23 | ## Time Complexity - How long is this gonna take? 24 | ##### time-complexity 25 | - ### BiG IDEA — Let's have a standard way to communicate about how long an algorithm or program will take to execute. 26 | 27 | - The "time complexity" of a program is a measure of how the "running time" of the program grows as the "input size" 28 | of the program grows. 29 | - Also known as "Algorithmic Complexity" or "Big O notation" 30 | - The "time complexity" is usually expressed as a "big O" notation, which is a way to express the "upper bound" of 31 | the "running time" of the program, ie: the worst case scenario. 32 | - The "big O" notation is a way to express the "upper bound" or maximum expected of the worst-case running time of a program. 33 | - 6 Common Types of Time Complexity: 34 | - O(1) - "Constant Time" - The running time of the program does not change as the input size of the program grows. 35 | - O(n) - "Linear Time" - The running time of the program grows as the input size of the program. 36 | - O(n^2) - "Quadratic Time" - The running time of the program grows as the square of the input size of the program. 37 | - O(n^3) - "Cubic Time" - The running time of the program grows as the cube of the input size of the program. 38 | - O(log n) - "Logarithmic Time" - The running time of the program grows as the logarithm of the input size of the program. 39 | - O(n log n) - "Linearithmic Time" - The running time of the program grows as the product of the input size of the program and the logarithm of the input size of the program. 40 | 41 | [](https://www.youtube.com/watch?v=XMUe3zFhM5c) 42 | 43 | > - Learn Big O notation in 6 minutes 📈 44 | > - https://www.youtube.com/watch?v=XMUe3zFhM5c 45 | 46 | - ### Shorthand Guide & Sample Code 47 | - ###### time-complexity-example 48 | - If you are doing a simple lookup in an array, it's O(1) because the time it takes to find the value in the array 49 | does not change as the size of the array grows. 50 | - If you are looping over items, it's O(n) because the time it takes to loop over the items grows as the size of the 51 | array grows. 52 | - If you are looping over items that are also looping over items, it's O(n^2) because the time it takes to loop over 53 | the items grows as the square of the size of the array grows. 54 | - Each time you add another loop, the time complexity grows as the square of the size of the array grows. 55 | - If you are doing a binary search, and each time you search you are cutting the size of the array in half, 56 | it's O(log n) 57 | 58 | ```Kotlin 59 | // Program in Kotlin to illustrate the time complexity of various operations 60 | // Note: The `//` symbols means the rest of the line is comment, it is not part of the program, it's just for explanation and is ignored by the compiler. 61 | 62 | // Algorithm: Binary Search 63 | // Perform binary search a sorted array - O(log n) 64 | // Returns the index of the value in the array, or -1 if the value is not found. 65 | fun Array.binarySearch(value: Int): Int { 66 | var low = 0 67 | var high = size - 1 68 | while (low <= high) { 69 | val mid = (low + high) / 2 // search 1/2 of the array each loop 70 | val midVal = this[mid] 71 | when { 72 | midVal < value -> low = mid + 1 73 | midVal > value -> high = mid - 1 74 | else -> return mid // ends the looping when the value is found 75 | } 76 | } 77 | 78 | return -1 // -1 = value not found 79 | } 80 | 81 | fun randomInt(max: Int): Int = (0..max).random() // <-- O(1) - Simple Lookup 82 | 83 | // Algorithm: Quick Sort 84 | // Perform recursive quicksort - O(n log n) 85 | // Returns a new sorted array. 86 | fun Array.quickSort(): Array { 87 | if (size < 2) return this 88 | val pivot = this[randomInt(size - 1)] 89 | 90 | val less = filter { it < pivot }.toTypedArray().quickSort() // recursive call 91 | val equal = filter { it == pivot }.toTypedArray() 92 | val greater = filter { it > pivot }.toTypedArray().quickSort() // recursive call 93 | 94 | return less + equal + greater 95 | } 96 | 97 | 98 | // Start of the program 99 | fun main() { 100 | val x: Array = Array(100) { randomInt(100) } // <-- O(n) - Fill Array `x` with 100 random integers 101 | 102 | val a: Int = x[50] // <-- O(1) - Simple Lookup 103 | 104 | for (i in 0 until x.size) { // <-- O(n) - Single Loop over items 1 time 105 | println(x[i]) 106 | } 107 | 108 | for (i in 0 until x.size) { // <-- O(n^2) - Double Loop over items (squared) 109 | for (j in 0 until x.size) { // <-- O(n) 110 | println(x[i] + x[j]) 111 | } 112 | } 113 | 114 | // Notice this one will take MUCH, MUCH longer than the previous ones. 115 | for (i in 0 until x.size) { // <-- O(n^3)- Triple Loop over items (cubed) 116 | for (j in 0 until x.size) { // <-- O(n^2) 117 | for (k in 0 until x.size) { // <-- O(n) 118 | println(x[i] + x[j] + x[k]) 119 | } 120 | } 121 | } 122 | 123 | val sorted: Array = x.quickSort() // <-- O(n log n) - Fastest known sorting algorithm for general case. 124 | val y = sorted.binarySearch(50) // <-- O(log n) - Searches a sorted array for a value, halving the search space each loop. 125 | } 126 | 127 | // << NO OUTPUT - Just code illustrating the time complexity of the operations >> 128 | // << - Run the live code example to generate output >> 129 | ``` 130 | > Live Code Example: [Time Complexity Example](src/main/kotlin/timeComplexityExample.kt) 131 | 132 | ## Communicating Software Designs Visually 133 | ##### communicating-software-designs 134 | - ### BIG IDEA — How can we use drawings and diagrams to visually communicate about software designs? 135 | 136 | - ### The Box, The Line and The Conceptual Layers 137 | - At the time when structured programming became popular, ideas around "Software Design" were developed to help 138 | people create more complex software systems with increasingly more complex requirements and coordinating work 139 | with larger teams of people working together a shared codebase. 140 | > - Software Design: Ep1 : 1st law of Software Design (The Box) 141 | > - https://www.youtube.com/watch?v=2icF3vvsxH8 142 | > - Software Design: Ep2 : 2nd Law of Software Design (The Line) 143 | > - https://www.youtube.com/watch?v=fh1a74WWvJQ 144 | > - Software Design: Ep3 : Conceptual Layers 145 | > - https://www.youtube.com/watch?v=8R7hoC3OuPo 146 | > - Software Design: Ep4 : 3rd Law of Software Design 147 | > - https://www.youtube.com/watch?v=nCxhJ_51fjA 148 | 149 | ## Some Thoughts on Common Software Production Methodologies 150 | ##### some-thoughts-on-common-software-production-methodologies 151 | - ### BIG IDEA — Are there ways to organize the work of discovering solutions and designing software that are better than others? 152 | 153 | - ### Waterfall 154 | - Was never a thing, it was a straw-man argument. Winston Royce, the creator the term "Waterfall," made it 155 | clear on **page 2** of his famous 1970 paper _"Managing the Development of Large Software Systems"_ that he was not advocating 156 | for the "Waterfall" process, but was trying to make a point about how software development was being managed like 157 | a manufacturing process, and it is a **_counter-productive way to manage the knowledge work._** 158 | > - It's Time For Waterfall To DIE 159 | > - https://www.youtube.com/watch?v=o3jDLVCpH1E 160 | > - Managers never read the second page, and took it as a "best practice". _Poor Winston Royce._ 161 | > - Note to self: _Always put the most important information on the first page._ 162 | 163 | - ### Scrum 164 | - Can we use what worked in Japanese car production with Japanese culture to have the same success in software development? Nope. 165 | - Scrum is a "production management" methodology that was developed for managing the production of cars, and it 166 | was soon co-opted into the _"Agile® Certification Business"_ and turned into a "one-size-fits-all" process that was 167 | supposed to work for any kind of general software development, and it doesn't. 168 | 169 | > - Scrum is bad 170 | > - https://www.youtube.com/watch?v=eTjVA4HcDWA 171 | > - Scrum is bad 2 (ie: Scrum is irrelevant) 172 | > - https://www.youtube.com/watch?v=5oPg08__v78 173 | > - Jim Coplien On What Agile Really Means 174 | > - https://www.youtube.com/watch?v=OFrUI3_tbGk&t=838s 175 | 176 | - ### Agile 177 | - Great start, good and useful concepts, but... 178 | - Widely misunderstood, misapplied, and soon co-opted into "Agile©®™ Certification©®™ Business." 179 | > [](assets/agile-tm-r-c.png) 180 | > - Agile Architecture Part 1 - Allen Holub 181 | > - https://www.youtube.com/watch?v=0kRCFVGpX7k&t=155s 182 | > - Agile is Over (Or Not) with Allen Holub 183 | > - https://youtu.be/6e-o8lTwBNw?si=cq95Pi2K8-YytSHj 184 | > - Kevlin Henney — The Case for Technical Excellence 185 | > - https://www.youtube.com/watch?v=LLEXAdO3X1o 186 | 187 | - ### SAFe 188 | - Another overcomplicated process that tries to "productionize" the software development process. 189 | - It's a "one-size-fits-all" process that was supposed to work for all kinds of software development, and it doesn't. 190 | 191 | - ## I call all of the above (and supporting hyped-books and hyped-conferences) the **"Age of Conference©®™ Driven Development"** 192 | - The problems around planning and organizing ever-larger teams, and increasingly complex problems became so onerous 193 | that many people looked far and wide for _ANY_ solution to gain a foothold on the process and make it more 194 | predictable and manageable. Unfotunately, knowledge work is FUNDAMENTALLY risky and not possible to plan 195 | because its a process of DISCOVERY, not a process of manufacturing. 196 | - The biggest risk to manage in software development is that _**WE MAY NEVER FIND**_ a workable solution in 197 | the time allotted. _This is not changeable. It's a fundamental limitation of all knowledge work._ 198 | 199 | - ### Dealing with the principal risks involved with knowledge work is the core problem in all software development. 200 | 201 | - ## The Problem with Applying "Production Management" Methodologies to Software Development Knowledge Work 202 | - The main issues with all these approaches is that they assume that software development is just another 203 | manufacturing process, and that the people who are doing the work are just another kind of "resource" that 204 | can be managed like a replaceable manufactuing worker on an assembly line. 205 | - Software development is fundamentally knowledge work and a process of discovery. The people who are doing 206 | the work are not interchangeable cogs but "knowledge workers" who are doing creative work that requires a lot of 207 | thinking and discussion and failed attempts before success, and does not have predictable outcomes. 208 | - The "Agile Manifesto" was written to address this problem, and to help people understand that software development 209 | is a fundamentally different kind of work than manufacturing, and that the people who are doing the work are 210 | fundamentally different kinds of workers than the people who work in manufacturing. This was a good thing. 211 | - The problem is that the Agile movement was soon co-opted into the "Agile® Certification Business" and turned 212 | into a "one-size-fits-all" process that was supposed to work for all kinds of software development, and it 213 | doesn't. It's a cargo cult that does not work for most teams, as most teams implement the "Rules™®©" directly without 214 | understanding the spirit of the agile rules, _which there are no rules_... just some values: 215 | 216 | - ### The 4 Values of the Agile Manifesto 217 | - The Agile Manifesto was written to address the problem of trying to manage software development like a manufacturing 218 | process, and to help people understand that software development is fundamentally different than manufacturing. 219 | - The 4 Values of the Agile Manifesto are: 220 | 1. Individuals and interactions over processes and tools. 221 | 2. Working software over comprehensive documentation. 222 | 3. Customer collaboration over contract negotiation. 223 | 4. Responding to change over following a plan. 224 | 225 | - #### While we value the items on the right, we value the items on the left more. 226 | 227 | - ### We Live Inside Our Experiences and Beliefs, Which Build Our Reality 228 | > [](assets/pyramid_of_results.png) 229 | [](assets/new_compassionate_dev.png) 230 | [](assets/motivational_debt.png) 231 | [](assets/computer_speed_miscommunicate.png) 232 | [](assets/programs_for_people.png) 233 | 234 | - ### The fundamental idea of Agile is "RESPONDING to CHANGE." 235 | - How can we make software development more flexible and faster to respond to changes and refinements in the 236 | requirements of software? 237 | - Cumbersome processes allow managers to "monitor" using charts and graphs is a standard way for businesses 238 | to manage risk in a manufacturing environment, but it's not a good way to manage risk for knowledge work. 239 | - Agile was a response to the progression towards more and more cumbersome processes that were driving projects 240 | to a standstill. It was a way to get back to the "heart" of software development, which is "respond to change." 241 | - It's primary result is working in much smaller steps, and being able to change direction quickly and easily 242 | based on what is discovered taking those small steps. 243 | - Each small step creates some kind of "valuable working software" that can be shown to the customer, and the 244 | customer can then give feedback on the working software, and the software can be changed based on that feedback. 245 | > ### Key finding of the Agile Manifesto 246 | > - Humans rarely know what they want UNTIL they experience what they _don't_ want, the solution is to work 247 | iteratively and get feedback often, integrate that feedback to make sure we are building the best 248 | _known_ solution at the time. 249 | 250 | > [](assets/agile-deliver-sooner-not-faster.png) 251 | 252 | - [Continue Reading - Class Oriented Programming](./09-ClassOrientedProgramming.md) 253 | - [Back to Index](README.md) 254 | -------------------------------------------------------------------------------- /08-StructuredProgramming.md: -------------------------------------------------------------------------------- 1 | ## Structured Programming 1960s-Present 2 | 3 | - ### BIG IDEA - Put different parts of a program into distinct sections, or "code blocks" or "scopes" to limit the visibility of variables and functions from other parts of the program. This is done to reduce the cognitive load for understanding code, make modifying code easier and enabling portable re-use of code via libraries. 4 | 5 | ### Scopes 6 | ###### scopes 7 | - No more `GOTO` statements, ONLY subroutines and conditional branching (`if-then-gosub`'s) are allowed. 8 | - "Scopes" define the visibility of variables and functions to other parts of the program. 9 | - Scopes are also called: 10 | - "code blocks" 11 | - "blocks" 12 | - "local" 13 | - "inner" 14 | - "nested" 15 | - "enclosed inside" 16 | - "contained within" 17 | - "limited in" 18 | - "restricted to" 19 | - "encapsulated" 20 | - "private" 21 | - "protected" 22 | - "hidden" 23 | - "isolated" 24 | 25 | > JEEPERS CREEPERS! That's a lot of names for the same thing, people! 26 | >> ### Humans like to give many names to things that are important and/or common problems to manage. 27 | 28 | - The concept of scopes was introduced to limit the use of "globally mutable" variables and visibility of functions. 29 | - This is the origin of "encapsulation" and first introduced to limit the visibility of the "local" variables 30 | and functions to only the "scope" or "block" that they were defined in, and to limit the "side effects" of the program. 31 | - Scopes have names and can be nested inside other scopes, and the local variables and functions are only visible 32 | to the scope that they are defined in. The inner scope has access to it's outer scope as well. 33 | _But_ the outer scope does not have access to the inner scope. 34 | - By reducing the "cognitive area" that needs to be understood. it makes the program easier to understand and maintain and 35 | allows for larger teams to work on the same program without stepping on each other's toes. 36 | - This is the main reason for the "Structured Programming" approach, as it was the first time that the "state" 37 | of the program was structured and encapsulated into localized scopes or "code blocks" 38 | 39 | > Names of the scope symbols: 40 | > - `{` and `}` are called "curly brackets" or "curly braces." 41 | > - `(` and `)` are called "parentheses", "parens" and sometimes "round brackets." 42 | > - `[` and `]` are called "square brackets" or just "brackets." (not confusing at all... 😬) 43 | > - `<` and `>` are called "angle brackets" or "chevrons." 44 | > - `/*` and `*/` are called "comment delimiters." 45 | > - `//` is called the "comment symbol." 46 | 47 | - Example of structured language (C): 48 | - Note: The `//` symbols means the rest of the line is comment, it is not part of the program, 49 | it's just for explanation and is ignored by the compiler. 50 | ```C 51 | // C program to demonstrate the use of scope in structured programming. 52 | #include // <-- Include the standard input/output library. 53 | 54 | int main() { // <-- start of the program & "opens" the scope, `int` means the function returns an integer, `main` is the name of the function. 55 | int x = 10; // Assigns the value of 10 to the variable `x` of type `int` (integer) 56 | int y = 100; 57 | 58 | { // <-- The "open curly bracket" denotes the start of a scope. This is an "inner" or "nested" scope. 59 | int y = 32; // Inside the brackets is "Inner" or "Local" to the scope. 60 | int z = 55; // <-- Only visible to the scope it's defined in, ie: this one. 61 | 62 | x = x + y; // <-- Uses the local variable `y` and variable `x` from the Outer `main` function scope. 63 | 64 | { // <-- another "nested" scope, or "inner" scope, or "local" scope. 65 | int y = 72; // <-- This is a different `y` than the one in the `main` scope. 66 | printf("%d %d\n", x, y); // <-- Print the value of y as a decimal number, ("\n" means "go to next line") 67 | // (%d means use decimal value of x and y, 42 and 72.) 68 | } // <-- The "close curly bracket" denotes the end of the scope. 69 | 70 | printf("%d %d %d\n", x, y, z); // <-- Print the value of x, y, and z as a decimal number 71 | // (%d means use decimal value of x, y, and z, 42, 32, and 55.) 72 | } // <-- The "close bracket" denotes the end of the scope. 73 | 74 | printf("%d %d\n", x, y); // <-- Print the value of x and y as a decimal number 75 | // (%d means use decimal value of x and y, 42 and 100.) 76 | // printf("%d", z); // <-- This line would cause a "compile error" because the variable "z" is not visible in this scope. 77 | 78 | } // <-- The "close curly bracket" denotes the end of the `main` scope. 79 | 80 | 81 | // Output: 82 | // 42 72 83 | // 42 32 55 84 | // 42 100 85 | ``` 86 | - Copy and Paste the above code into an online C compiler to see the output: https://www.onlinegdb.com/online_c_compiler 87 | - Live Code Example in Kotlin: [Structured Programming Example with Scopes: `structuredExample.kt`](src/main/kotlin/structuredExample.kt) 88 | 89 | ```mermaid 90 | flowchart RL 91 | 92 | subgraph main_scope["main() scope"] 93 | y01["y=100"] 94 | x1["x=10"] 95 | x3 ---> x1 96 | x2 --> x1 97 | subgraph innerScope["an inner scope"] 98 | x2["x"] 99 | y2["y=32"] 100 | z1["z=55"] 101 | z2 --> z1 102 | subgraph nestedScope["a nested scope"] 103 | y3["y=72"] 104 | x3["x"] 105 | z2["z"] 106 | end 107 | end 108 | 109 | printf2 110 | end 111 | 112 | subgraph stdio["stdio.h"] 113 | printf{{"function printf(…) { … }"}} 114 | end 115 | 116 | printf2{{"printf(…)"}} ----> printf:::Object 117 | 118 | classDef Object fill:#55F, stroke:#FFF, stroke-width:3px, color:#fff 119 | ``` 120 | 121 | ### Types 122 | ##### types 123 | - The concept of custom types (or "kinds") was introduced to define more complex groupings of primitives to be seen as a single type. 124 | - Procedural languages only had a few primitive types: "integer," "character," "string of characters" or "array" 125 | - Having "structured" types allowed for more complex data to be defined and used in the program, instead of only using the primitive types. 126 | - Primitive types are: `int`, `long`, `float`, `char`, and `bool` (note the `bool` type was not introduced until later in C++ and C99.) 127 | - Primitive types are the "building blocks" of all other types defined in `struct`-s 128 | - Example of Types (C): 129 | ```C 130 | // C program to demonstrate the use of "primitive types" and "structs" in structured programming. 131 | #include // <-- Include the standard input/output library. 132 | 133 | struct Point { // <-- `Point` is a programmer-defined type that is made up of other types (Structure or "struct".) 134 | int x; 135 | int y; 136 | char colorIdChar; // <-- `char` is a type that represents a single ASCII character (1 byte.) 137 | }; 138 | 139 | int main() { 140 | int x = 5; 141 | float y = 6.128; 142 | char z = 'A'; 143 | struct Point p = { 10, 42, 'G' }; // <-- `p` is a variable of type `Point` that is `assigned` values of 10, 42, and 'G'. 144 | 145 | printf("Output: %d %f %c %d %d %c", 146 | x, y, z, p.x, p.y, p.colorIdChar); 147 | } 148 | 149 | // Output: 5 6.128000 A 10 42 G 150 | 151 | ``` 152 | - Copy and Paste the above code into an online C compiler to see the output: https://www.onlinegdb.com/online_c_compiler 153 | - Live Code Example in Kotlin: [Types Example: `typesExample.kt`](src/main/kotlin/typesExample.kt) 154 | 155 | - This allowed easier code reuse and easier to understand state of the program than procedural languages. 156 | - Structured programming allowed the creation of "libraries" and "modules" to be easily produced to create standard subroutines and 157 | data structures into complete software packages and system utilities and frameworks to be used by other programmers. 158 | - This allowed for more complex programs to be created and maintained by smaller teams of programmers. 159 | - C started the concept of "published interfaces" that could be imported into another program and used to 160 | provide the functionality of libraries. 161 | - These libraries were just collections of functions and data structures that were related to each other for a specific task. 162 | - Structured languages allowed for much more portable and reusable code than procedural languages as they were not 163 | tied to any specific computer hardware or operating system. The computer manufacturer only had to create the 164 | compiler for their particular machine, and then the same code could be run on any machine that had a compiler 165 | for the language. 166 | 167 | ### Comparing C to Assembly Language 168 | ##### c-to-assembly-language 169 | - C was meant to be a "high-level portable shorthand" for Assembly Language, which was a high-level shorthand for Machine Language. 170 | - All of high-level languages are eventually compiled into machine language by a compiler program. 171 | > - Comparing C to machine language - Ben Eater 172 | > - https://www.youtube.com/watch?v=yOyaJXpAYZQ 173 | > - How computer processors run conditions and loops 174 | > - https://www.youtube.com/watch?v=Ui6QyzcD3_E 175 | 176 | 177 | ### Bonus: History of Procedural to Structured Programming 178 | > - Procedural Programming: It’s Back? It Never Went Away - Kevlin Henney [ACCU 2018] 179 | > - https://www.youtube.com/watch?v=mrY6xrWp3Gs 180 | > - History and Spirit of C - Olve Maudal 181 | > - https://www.youtube.com/watch?v=xGVRF-Y--hI 182 | 183 | - [Continue Reading - Class Oriented Programming](./09-ClassOrientedProgramming.md) 184 | - [Back to Index](README.md) 185 | -------------------------------------------------------------------------------- /10-FunctionalProgramming.md: -------------------------------------------------------------------------------- 1 | # Functional Programming (FP) 1950s-Present 2 | ###### functional-programming 3 | - ### BIG IDEA - Shared mutable state is a complex problem, especially for parallel processing tasks. 4 | 5 | > [](assets/functional-chart-updated.png) 6 | 7 | - ### The Functional style requires: 8 | 1) #### Calling functions will NEVER change anything outside the function being called. 9 | - ie: "pure functions," 10 | - "no side effects," 11 | - "side-effect free," 12 | - "no shared mutable state." 13 | 14 | - ### All these phrases mean "A function that doesn't change any program state outside of it's own scope." 15 | 16 | - _They don't seem to count the "program counter" or "stack pointer" as "state" though..._ 17 | - They mean the "state" of the program's data, not necessarily the "state" of the program's execution. 18 | #### 19 | 20 | 2) #### Functions passed in with the same values will ALWAYS return the same value as a result. 21 | - ie: "deterministic", 22 | - "referentially transparent", 23 | - "idempotent," 24 | - "stateless," 25 | - "pure," 26 | - "no shared mutable state." 27 | 28 | - ### All these phrases mean "A function that doesn't change anything outside of it's own scope, and always returns the same result for the same input." 29 | 30 | 3) #### Functions can be passed as arguments to other functions. 31 | - ie: "higher-order functions," 32 | - "lambdas", 33 | - "closures", 34 | - "first-class citizen functions," 35 | - "anonymous functions", 36 | - "function literals." 37 | 38 | - ### All these mean "functions can be passed as arguments to other functions, just like any other variable." 39 | 40 | > ## ⚠️ EXCESSIVE WORD-INVENTION-FOR-THE-SAME-DEFINITION ALERT!!! 41 | > > SEE WHAT I MEAN WITH ALL THE NAMES FOR THE SAME THING? 😐🤪🤨😳😒? 42 | > ### 🛑 ATTENTION COMPUTER SCIENCE PEOPLE: 43 | > ### 🤨 Please, consider stopping with all the names for the same exact concepts!!!!! I know you gotta make sales, but come on! 44 | > 45 | > > _YOU **MAY** HAVE A MEDICAL CONDITION:_ 46 | > > - **_"Sesquipedalianism"_** refers to the tendency to use long words or create unnecessarily complex words when simpler ones would suffice, often resulting in verbose or convoluted language. It can also describe the habit of inventing new words or phrases for concepts that already have well-established terms. 47 | > > - _This behavior is often seen as pretentious or pedantic._ 48 | > 49 | > > #### I'm purposely _**NOT**_ going to mention Functors, Monads, or Applicatives... c'mon mannnnnn... 😒 50 | 51 | ## Immutability & No Side Effects 52 | ###### immutability-no-side-effects 53 | - Mutability means something can be changed, and immutability means it cannot be changed once it's created. 54 | - Functional Programming style's main idea is to avoid "side effects" and "shared mutable state" of the program. 55 | - One way is to is to make the state of the program read-only. 56 | - Changes can only be made by calling a function to create a new state based on the a copy of the old state, 57 | and then returning the new program state as the result. 58 | - The BOOP ("Back-to Object Oriented Programming") style is a form of Functional Programming as the state of the 59 | program is immutable and passed as arguments. 60 | to the functions, and a new state is returned as the result of the calls to the functions. 61 | > [](assets/functional-programming.png) 62 | 63 | - It's more of a style of programming than a paradigm as it can be used in any language, but it's most effective 64 | in languages that are designed to be functional from the ground up. 65 | - New states of the program can be created by passing in the state of the program as arguments to program functions, 66 | and a new state is returned as the result of the calls to the functions. 67 | - This makes the program easier to understand and maintain, and allows for parallel ("concurrent") programming 68 | to be done far more easily. 69 | 70 | > ### ❤️😍💓 _Immutability eliminates whole classes of bugs that are caused by side effects that plague COP-style programs._ 71 | > 72 | > #### Remember the banking example from the Procedural Programming section? 73 | > - Where the bank computer manager talks about only making copies of the data and not changing the original data? 74 | > - https://youtu.be/fAselhq0Q8g?si=3t_GnlWiybu3Bvg6&t=1032 75 | 76 | - Functions are "first-class citizens" and can be passed as arguments to other functions, just like normal variables and objects. 77 | - This allows customization of functions by passing in another function as an argument to be used in processing. 78 | - This allows the functions to be "composed" together to create new functions from existing functions. 79 | - These functions are called "lambdas," "closures," "anonymous functions" or "function literals," 80 | and "higher-order functions" all interchangeably. 81 | - It's all just functions! 82 | - Examples of functional languages are "Lisp", "Clojure" and "Javascript" and "Kotlin" 83 | 84 | ### Code Example demonstrating Side Effects (Kotlin): 85 | ###### sideEffectsExample 86 | ```Kotlin 87 | // Kotlin code to demonstrate side effects, pedantically. 88 | fun main() { 89 | var x = 0 // <-- Defines a variable that will be "affected" or "mutated" by the lambda. 90 | val add = { a: Int, b: Int -> // <-- Defines a lambda that takes two Ints and returns an Int. 91 | val result = a + b + x 92 | x = x + a // <-- Create a "side effect" by changing the value of `x` outside the lambda. 93 | 94 | result // <-- Return the result of the addition including the side effect. 95 | } 96 | 97 | println(add(1, 2)) // <-- Print expected value the first time called (3). 98 | 99 | println(add(1, 2)) // <-- Print the UNEXPECTED value the second time called (4) due to the side effect. 100 | } 101 | 102 | // Output: 103 | // 3 // <-- This value of is what we expected, only the first time though... 104 | // 4 // <-- This value of is not what we expected due to the side effect. 105 | 106 | 107 | ``` 108 | > Live Code Example: [Side Effects Example](src/main/kotlin/sideEffectsExample.kt) 109 | 110 | ### Code Example of Functional style (Kotlin): 111 | ###### functionalExample 112 | ```Kotlin 113 | fun main() { 114 | val addFunc = { x: Int, y: Int -> x + y } // <-- Defines a lambda that takes 2 integers and returns the sum of the integers. 115 | val multiplyFunc = { x: Int, y: Int -> x * y } // <-- Defines a lambda that takes 2 integers and returns the product of the integers. 116 | val firstThenSecond = { // <-- Defines a lambda that takes 4 arguments, 2 functions and 2 integers, and returns the result of the 2 functions. 117 | first: (Int, Int) -> Int, // <-- 🟡 Accepts a lambda that takes 2 integers and returns an integer, it's executed first. 118 | second: (Int, Int) -> Int, // <-- 🔴 Accepts a lambda that takes 2 integers and returns an integer, it's executed second. 119 | a: Int, b: Int -> 120 | second(first(a, b), b) // <-- Calls the `first` lambda with the 2 integers (a & b), 121 | // then calls the `second` lambda with the result of `first()` and the 2nd integer (b) 122 | } 123 | 124 | val result = firstThenSecond(addFunc, multiplyFunc, 10, 2) // <-- 🟠 calls the lambda with the 2 functions and 2 integers 125 | // using the "first class citizen" variables that each 126 | // contain a function as a value (also called a lambda.) 127 | println(result) // result will be 24 128 | 129 | val resultUsingAnonymousFunctions = 130 | firstThenSecond( // <-- Calls the `firstThenSecond` lambda with the 2 "anonymous functions" and 2 integers. 131 | { a, b -> a + b }, // <-- Defines an "anonymous function" that takes 2 integers and returns the sum of the integers. 132 | { a, b -> a * b }, // <-- Defines an "anonymous function" that takes 2 integers and returns the product of the integers. 133 | 10, 2 134 | ) 135 | println(resultUsingAnonymousFunctions) // result will be 24 136 | } 137 | 138 | main() 139 | 140 | // Output: 141 | // 24 142 | // 24 143 | ``` 144 | > Live Code Example: [Functional Example](src/main/kotlin/functionalExample.kt) 145 | 146 | ## Function Evaluation Sequence 147 | ```mermaid 148 | flowchart TB 149 | 150 | note["The function call chain 151 | for the Functional Example program. 152 | ◇❖◇ 153 | "] 154 | 155 | start((("🟠 1. Start here"))) ==> Z 156 | 157 | X[" `first` points to `add` function "] ==>|"🟡 3. Calls function with x= 10, y= 2"| addFn{{" 158 | func add(…) @F8BC76FC = 159 | ✚ { x,y -> return x+y } 160 | ⌺"}} 161 | Y[" `second` points to `multiplyFunc`"] ==>|"🔴 5. Calls function with x=12, y=2"| multiplyFn{{" 162 | func multiply(…) @48C6CE7B = 163 | ╳ { x,y -> return x*y } 164 | ⌺"}} 165 | Z["val result = firstThenSecond(addFunc, multiplyFunc, 10, 2)"] ==>|"🔵 2. Calls function with params"| firstThenSecondFunc{{" 166 | func firstThenSecond(…) @A8C6CE7B = 167 | ⏩ { first, second, a, b -> second(first(a, b), b) } 168 | ⌺"}} 169 | 170 | addFn ==>|"🔵 4. returns result ❪12❫ into `second` 171 | function's `a` parameter"| firstThenSecondFunc 172 | multiplyFn ==>|"🔵 6. returns result ❪24❫"| firstThenSecondFunc 173 | firstThenSecondFunc ==>|"🔵 7. returns result ❪24❫"| Z 174 | firstThenSecondFunc -.-> X 175 | firstThenSecondFunc -.-> Y 176 | 177 | ``` 178 | ### How Flow of Execution Travels in the Functional Example 179 | 180 | ```mermaid 181 | flowchart LR 182 | subgraph main["func main()"] 183 | 184 | X["val `addFunc` = @F8BC76FC"] ==>|"🟠 START HERE: 1. Stores pointer to function"| addFn{{" 185 | func add(…) @F8BC76FC = 186 | ✚ { x,y -> return x+y } 187 | ⌺"}} 188 | Y["val `multiplyFunc` = @48C6CE7B"] ==>|"🔵 2. Stores pointer to function"| multiplyFn{{" 189 | func multiply(…) @48C6CE7B = 190 | ╳ { x,y -> return x*y } 191 | ⌺"}} 192 | Z["val `firstThenSecond` = @A8C6CE7B"] ==>|"🔵 3. Stores pointer to function"| firstThenSecondFunc{{" 193 | func firstThenSecond(…) @A8C6CE7B = 194 | ⏩ { first, second, a, b -> second(first(a, b), b) } 195 | ⌺"}} 196 | 197 | D -.->|`firstThenSecond` points to function| firstThenSecondFunc 198 | firstThenSecondFunc -...->|"🟡 7. Calls `first`"| addFn 199 | firstThenSecondFunc -...->|"🔴 9. Calls `second`"| multiplyFn 200 | 201 | subgraph result["🔵 4. val `result` = firstThenSecond(first= addFunc, second= multiplyFunc, a= 10, b= 2)"] 202 | resultInner["Result of firstThenSecond(…)"] ==> E 203 | D("Evaluate ⏩ firstThenSecond(…)_= second(first(a,b), b)") ==>|"🔵 5. Calls"| first 204 | subgraph firstThenSecond[" 🔵 6. firstThenSecond(…) internal calls..."] 205 | first("🟡 7. Calls `first`(…) = `✚ addFunc(a,b)`")==>|"🔵 8. Returns result into `second` function's `a`"| second 206 | second("🔴 9. Calls `second`(…) = `╳ multiplyFunc(a,b)`") ==>|"🔵 10. Returns result"| resultInner 207 | 208 | %% Show where return to firstThenSecond 209 | %% second("calls second(…) = `╳ multiplyFunc(a,b)`") ==>|🔵 6. returns result| D 210 | end 211 | end 212 | E("Stores returned result in variable `result`") ==>|"🔵 11. Variable `result` passed to"| F 213 | F["print(`result`)"]==>|"🔵 END 12. program ends"| G 214 | 215 | %% Show the function pointers for the lambda 216 | %% first -..->|`first` points to function| addFn 217 | %% second -...->|`second` points to function| multiplyFn 218 | end 219 | G("🖥️ main()") 220 | 221 | ``` 222 | 223 | # Side Quest on "Declarative" Programming 224 | > - Notice that many of the diagrams in this document are written in a language that uses "declarative" style programming. 225 | > - Mermaid is a "Domain Specific Language" (DSL) used to create the diagrams in a declarative style using only human-readable text code. 226 | > - This allows for more flexible and maintainable diagrams that can be created and maintained in a text file opposed to using a graphics editor. 227 | > - Allows to be rendered in many different formats, including SVG, PNG, and PDF, and is responsive to different screen sizes. 228 | > - ### I can change the diagram layout and style by changing the code, and the diagram will update automatically, avoiding the need to manually redraw the diagram in a graphics editor. 229 | > 230 | > - [https://mermaid.js.org/](https://mermaid.js.org/intro/) 231 | >> ### More on Declarative Programming: 232 | >> - 'Declarative Thinking, Declarative Practice' - Kevlin Henney [ ACCU 2016 ] 233 | >> - https://www.youtube.com/watch?v=nrVIlhtoE3Y 234 | >> - HTML IS a Programming Language (Imperative vs Declarative) - Computerphile 235 | >> - https://www.youtube.com/watch?v=4A2mWqLUpzw 236 | >> - You Should Use Sequence Diagrams 237 | >> - https://www.youtube.com/watch?v=DaP6z2CsVhM 238 | 239 | 240 | - [Continue Reading - Back-to-Object Oriented Programming](11-BackToObjectOrientedProgramming.md) 241 | - [Back to Index](README.md) -------------------------------------------------------------------------------- /13-Conclusion.md: -------------------------------------------------------------------------------- 1 | # Conclusion 2 | 3 | ## Programming Paradigms are Just Different Styles to Structure and Organize Software 4 | ###### paradigms 5 | - The different paradigms are not better or worse than each other, they are just different styles to structure the 6 | state and behavior of software to provide a solution. 7 | - Paradigms are not independent, Different paradigms can be combined to create a program that is easier to understand and maintain. 8 | - Paradigms are not frozen and are constantly evolving as new ideas are added to the software development 9 | methods to make creating software easier and more effective. 10 | - Each paradigm has its own benefits, costs, and trade-offs that must be considered when 11 | choosing which paradigm is appropriate for a particular problem. 12 | ### Often, the best solution is the simplest one. 13 | - Paradigms are not dogma, and should not be followed blindly, but should be used as a guide to help 14 | structure and organization the program to be easiest to understand and change. 15 | 16 | ## You Can Only Learn Programming By Actually Programming 17 | ###### learning_programming 18 | - The best way to learn programming that I've found is to physically copy (actual typing) other programs and change them. 19 | - ### You can read all the books and watch all the videos you want, but you will not learn programming until you actually start solving problems, and seeing how other people solve them is a great start. 20 | - ## IT IS **_VERY IMPORTANT_** THAT YOU TRY TO CHANGE THE CODE AFTER YOU HAVE COPIED IT. _THIS IS CRITICAL._ 21 | - Doing "code katas" and "coding challenges" are a great way to practice programming and learn new programming 22 | languages and paradigms. 23 | - But after you know the mechanics, the bigger challenge is to learn how to structure and organize the state and 24 | behavior of the software to be easiest to understand and change. 25 | - This is a life-long learning process, and how to arrange ideas and concepts to make them easier to understand 26 | and change is a skill that takes time and practice to develop, and only comes with experience and some luck. 27 | 28 | > # Stop Studying Programming 29 | > - https://www.youtube.com/watch?v=QMbx0dTWJIQ 30 | > 31 | > ### BEWARE THE PROGRAMMING TUTORIAL TAR-PITS 32 | > - Always code-along with the tutorial, and change it afterward to make sure you understand. 33 | > - Learn how to save your projects to GitHub, it's not hard, and you will be able to track your progress. 34 | > > ### If you ONLY just watch, it WILL BE A COMPLETE waste of time, even though you _**THINK**_ you understand it. 35 | > > 36 | > > [](https://www.youtube.com/watch?v=QMbx0dTWJIQ) 37 | 38 | # QUIT LOOKING FOR SHORT-CUTS 39 | ###### short-cuts 40 | - The biggest problem I've seen with people trying to learn programming is that they are looking for a short-cut. 41 | - QUIT IT AND GET IN THERE AND START TYPING AND CHANGING CODE. 42 | - All developers must pay the same price to learn programming, and that price is time and effort. 43 | 44 | [](assets/things-to-know.png) 45 | 46 | ## Programming Will Always Be a Human Activity - AI Cannot Possibly Solve Everything and Requires Human Guidance 47 | ###### programming-is-human 48 | - Solution methods will become a bit more abstract in the future using tools like GitHub copilot, but the 49 | programmer will still need to know all these details to get the machine to do EXACTLY what they want it to do. 50 | - We are always going to need people who have various tastes and understandings about humans and the world to 51 | create software that is useful and effective FOR THOSE PARTICULAR HUMANS. 52 | 53 | > - What to do about the AI? 54 | > - https://youtu.be/bdTFfkDp9Gc 55 | > - Coder Takes - The Truth About Web Dev Jobs vs CS Degrees vs Boot-camps vs Self Taught 56 | > - https://youtu.be/UTehRqykJrw 57 | > - Coder Takes - Golden Handcuffs & Side Hustle Dreams 58 | > - https://youtu.be/9Avfwdk8wfE 59 | 60 | ## My Favorite Book on Learning Kotlin 61 | - ### I prefer learning how to program a new language using a book. They are usually much more thought out than videos. It also forces you to read and write. Physical copies are the preferred mode, as you can write notes on the pages, and IT IS TOTALLY OK AND RECOMMENDED THAT YOU DO THAT. 62 | - Big Nerds Ranch Guide to Kotlin Programming (2nd Edition) 63 | - https://www.informit.com/store/kotlin-programming-the-big-nerd-ranch-guide-9780136891055 64 | 65 | [](assets/kotlin-book.png) 66 | 67 | >###### [DONT CICLK TIHS LNIK](https://libgen.is/book/index.php?md5=EACC909D4C5A81DAD454C283064E1034) 68 | 69 | > # $\textcolor{yellow}{Please\ consider\ giving\ me\ a\ STAR\ as\ THANKS!\ ⭐️ 🤩\}$ 70 | 71 | ## History Graph of Selected Programming languages Referenced In This Document 72 | ###### history-graph 73 | > Keynote session: The History of Programming - Mark Rendle [DevCon 2016] 74 | > - https://youtu.be/Tr9E_vzKRVo 75 | 76 | ```mermaid 77 | graph TB 78 | MachineLanguage{{Machine Language}} -->|human readable mnemonics| AssemblyLanguage 79 | AssemblyLanguage{{Assembly Language}} -.->|Procedural & Interpreted|Basic 80 | AssemblyLanguage{{Assembly Language}} -->|Procedural|COBOL 81 | AssemblyLanguage{{Assembly Language}} -->|Procedural|Fortran 82 | AssemblyLanguage{{Assembly Language}} -->|Structured|Algol68 83 | AssemblyLanguage{{Assembly Language}} -->|Structured + low-level|BCPL 84 | AssemblyLanguage{{Assembly Language}} -->|Structured|C 85 | AssemblyLanguage{{Assembly Language}} -->|List-oriented|Lisp 86 | 87 | COBOL{{"COBOL"}} -.->|"Easy to 88 | Learn Syntax 89 | ⚡️️"|Basic 90 | Basic{{"BASIC"}} ---> VisualBasic 91 | Fortran{{"Fortran"}} -.->|"Evaluate 92 | Formulas 93 | ✨"|Basic 94 | Algol68{{Algol60, Algol68}} -.->|"for structures, 95 | scopes & syntax 96 | ⚡️️ 97 | "|C 98 | BCPL{{"BCPL"}} -->|"for types, structures 99 | low-level compilation 100 | ✨"|C 101 | Algol68 --> BCPL 102 | BCPL --> Simula67 103 | Algol68 --> Simula67 104 | Simula67{{"Simula67"}} -.->|"for pointers & 105 | other concepts 106 | ✨"|C 107 | Simula67 -.->|for OOP ideas|Smalltalk 108 | C{{"C"}} -->Cplusplus 109 | C -.->Smalltalk 110 | Simula67 -.->|for COP ideas|Cplusplus 111 | Cplusplus{{"C++"}} -->|for COP/pseudo-OOP ideas|Java 112 | Smalltalk -..->|"absconded OOP term 🫤 113 | & some ideas 114 | 🤔🤨🧐"|Cplusplus 115 | Java{{Java}} -->Kotlin 116 | Java -->CSharp 117 | CSharp{{"C#"}} 118 | Fortran -.->Algol68 119 | Smalltalk{{"Smalltalk 120 | Originator of term OOP 121 | 🙂"}} -.->|for OOP ideas|Javascript 122 | Smalltalk -.->|for OOP ideas|Ruby 123 | Smalltalk -.->|"encapsulation 124 | messaging 125 | 🙂"|HyperTalk 126 | Basic -.-> |"for Interpreted & 127 | interactive 128 | ⚡️"|Smalltalk 129 | AssemblyLanguage-.->|"for self-modifying 130 | code @ runtime 131 | ✨"|Smalltalk 132 | 133 | Lisp{{"Lisp"}} -.->|internal syntax|Javascript 134 | Java--->|for syntax|Javascript 135 | Kotlin{{Kotlin}} 136 | Ruby{{Ruby}} 137 | HyperTalk{{HyperTalk}} 138 | Javascript{{Javascript}} 139 | VisualBasic{{"Visual Basic"}} 140 | 141 | X("X") ---> |means Y descended from X.| Y("Y") 142 | A("A") -..-> |means A influenced B.| B("B") 143 | Note("Conceptual Inheritance Graph of Selected Languages. 144 | OOP Ideas = classes, inheritance, polymorphism. 145 | 146 | Not exhaustive, not to time scale. 147 | ⨭⨂⨀⨁⨮") 148 | 149 | ``` 150 | 151 | - [Back to Index](README.md) 152 | -------------------------------------------------------------------------------- /How_to_program_from_ground_up.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [](https://www.youtube.com/playlist?list=PLzUxWOrVXB4QHsURai1GmmhmqAUVNbfno) 2 | 3 | # How to Program From The Ground Up (with Minimal BS) 4 | ©2024 Chris Athanas 5 | 6 | A follow-along guide for anyone who wants a solid understanding of software development as a semi-historical 7 | walk through the essential parts of computing leading to present day software development paradigms. 8 | 9 | This is not a thorough deep dive into any one topic, but a broad overview of the core concepts and principles 10 | that are missing from most programming tutorials and courses. My goal is to give you the context about 11 | why things are the way they are in computing, and how they came to be that way, and the issues and problems that 12 | arose from things being that way. 13 | 14 | I have found that it's far more important to understand the process that people went through to create the 15 | current solutions than to understand the mechanical details of how the solutions work. Many details about 16 | the disadvantages and limitations are often left out when teaching these techniques, or worse, simply not known or dismissed as 17 | irrelevant due to ignorance. 18 | 19 | > ### $\textcolor{yellow}{Please\ consider\ giving\ me\ a\ STAR\ as\ THANKS!\ ⭐️ 🤩\}$ 20 | 21 | This document is a reference and follow along guide for my video series on YouTube: 22 | - [YouTube Series - How to Program From The Ground Up (with Minimal BS)](https://www.youtube.com/playlist?list=PLzUxWOrVXB4QHsURai1GmmhmqAUVNbfno) 23 | 24 | Check out the discussion group: https://twitter.com/i/communities/1759753866219040980 25 | 26 | # Table of Contents 27 | - [Introduction](#introduction) 28 | - [The Essence of Computing](02-TheEssentialQuestion-WhatAreWeComputing.md) Pre-history to Present Day 29 | - [Hardware](03-Hardware.md) 1700s to Present Day 30 | - Using Natural Phenomenon to Represent Human Information 31 | - [The Wire & the Light Bulb & the Battery](03-Hardware.md#the-wire--the-battery) 32 | - [The Simple Switch](03-Hardware.md#the-simple-switch) 33 | - [The Magnificent Magnet](03-Hardware.md#the-magnificent-electromagnet) 34 | - [The Raucous Relay](03-Hardware.md#the-raucous-relay) 35 | - [The Voracious Vacuum Tube](03-Hardware.md#the-voracious-vacuum-tube) 36 | - [The Tiny Transistor](03-Hardware.md#the-tiny-transistor) 37 | - [The Interchangeable Integrated Chip (IC)](03-Hardware.md#the-interchangeable-integrated-chip-ic) 38 | - [Why are NAND gates so special?](03-Hardware.md#nand-gates) 39 | - [The Mighty Microprocessor](03-Hardware.md#the-mighty-microprocessor) 40 | - [The Configurable Computer](03-Hardware.md#the-configurable-computer) 41 | - [Data Structures](04-DataStructures.md) Pre-history to Present Day 42 | - How Do Humans Represent Data in Binary in Computers? 43 | - [Numbers](04-DataStructures.md#numbers) 44 | - [Characters](04-DataStructures.md#characters) 45 | - ["Data Structures"](04-DataStructures.md#data-structures) 46 | - [Array](04-DataStructures.md#array) 47 | - [String](04-DataStructures.md#string) 48 | - [Pointer](04-DataStructures.md#pointer) 49 | - [Stack](04-DataStructures.md#stack) 50 | - [Queue](04-DataStructures.md#queue) 51 | - [Linked List](04-DataStructures.md#linked-list) 52 | - [Map](04-DataStructures.md#map) 53 | - [Tree](04-DataStructures.md#tree) 54 | - [Graph](04-DataStructures.md#graph) 55 | - [Software](05-Software.md) 1800s to Present Day 56 | - How to Represent Human Problems in a Digital Computer? 57 | - [Machine Code](05-Software.md#machine-code) 58 | - [Representation of Data in Computer Memory](05-Software.md#representation-of-data) 59 | - [Binary Counting](05-Software.md#binary-counting) 60 | - [Hexadecimal Counting](05-Software.md#hexadecimal-counting) 61 | - [Standardized ASCII](05-Software.md#standardized-ascii) 62 | - [The Minimum Components of a Computer System](05-Software.md#minimum-components) 63 | - [The CPU/MPU](05-Software.md#the-cpu-mpu) 64 | - [The Clock](05-Software.md#the-clock) 65 | - [Program Counter](05-Software.md#program-counter) 66 | - [Common Machine Language Opcodes](05-Software.md#common-opcodes) 67 | - [Fetch-Decode-Execute Cycle of the CPU](05-Software.md#fetch-decode-execute-cycle) 68 | - [Registers](05-Software.md#registers) 69 | - [Arithmetic Logic Unit (ALU)](05-Software.md#alu) 70 | - [Control Unit](05-Software.md#control-unit) 71 | - [Assembly Language](05-Software.md#assembly-language) 72 | - [Common Assembly Language Operations](05-Software.md#common-assembly-operations) 73 | - [Variables](05-Software.md#variables) 74 | - [Subroutines](05-Software.md#subroutines) 75 | - [High-Level Languages](06-HighLevelLanguages.md#high-level-languages) 1950s to Present Day 76 | - How can we make programming easier and more understandable for humans? 77 | - [Programming Styles](06-HighLevelLanguages.md#programming-styles) 78 | - [Procedural Programming](06-HighLevelLanguages.md#procedural-programming) 79 | - [Problem: Abusing GOTO](06-HighLevelLanguages.md#abusing-goto) 80 | - [Solution: Subroutines](06-HighLevelLanguages.md#solution-subroutines) 81 | - [Problem: Naive Solutions](06-HighLevelLanguages.md#naive-solutions) 82 | - [Problem: Imperative Looping](06-HighLevelLanguages.md#problem-imperative-looping) 83 | - [Solution: Declaritive Looping](06-HighLevelLanguages.md#solution-declarative-for-loop) 84 | - [Software Design](07-SoftwareDesign.md) 1960s to Present Day 85 | - How can we organize and communicate the solution to a problem in a way that is understandable? 86 | - [Algorithms](07-SoftwareDesign.md#algorithms) 87 | - [Time Complexity](07-SoftwareDesign.md#time-complexity) 88 | - [Shorthand Guide & Sample Code](07-SoftwareDesign.md#time-complexity-example) 89 | - [Communicating Software Designs Visually](07-SoftwareDesign.md#communicating-software-designs) 90 | - [Some Thoughts on Common Software Production Methodologies](07-SoftwareDesign.md#some-thoughts-on-common-software-production-methodologies) 91 | - [Structured Programming](08-StructuredProgramming.md) 1960s-Present 92 | - Can we give some kind of standard way of organizing and communicating the solution to a problem? 93 | - [Scopes](08-StructuredProgramming.md#scopes) 94 | - [Types](08-StructuredProgramming.md#types) 95 | - [Comparing C to Assembly Language](08-StructuredProgramming.md#c-to-assembly-language) 96 | - [Class Oriented Programming (COP)](09-ClassOrientedProgramming.md) 1980s-Present 97 | - Can we simulate real-world objects easier than with procedural or structured programming? 98 | - [COP Tried to Introduce a New Style of Programming, But Ended With Mixed Results](09-ClassOrientedProgramming.md#cop-tried-to-introduce) 99 | - [Design of C++](09-ClassOrientedProgramming.md#design-of-c-plus-plus) 100 | - [Encapsulation](09-ClassOrientedProgramming.md#encapsulation) 101 | - [Simplistic Overview of a Class and an Object Instance of the Class](09-ClassOrientedProgramming.md#simplistic-overview) 102 | - [Sophisticated Diagram of a Class and Object Instance](09-ClassOrientedProgramming.md#sophisticated-diagram) 103 | - [Instantiation or "Allocating Memory" for an Object of a Certain Class](09-ClassOrientedProgramming.md#instantiation) 104 | - [Object Instance Variable Values = "State" of the Object](09-ClassOrientedProgramming.md#object-instance-variable-values) 105 | - [Problem: Using Classes and Objects as "Name-Spaces/Scopes" Lead to Procedural-Style Code Implementations](09-ClassOrientedProgramming.md#using-classes-and-objects-as-name-spaces) 106 | - [Problems Arising from Abusing Static Methods and Attributes](09-ClassOrientedProgramming.md#problems-arising-from-abusing-static) 107 | - [Diagram of A Class Used as a "Name-Space" for Static Methods](09-ClassOrientedProgramming.md#static-methods) 108 | - [Interfaces](09-ClassOrientedProgramming.md#interfaces) 109 | - [Inheritance](09-ClassOrientedProgramming.md#inheritance) 110 | - [Problems Arising from the Abuse of Inheritance](09-ClassOrientedProgramming.md#problems-arising-from-the-abuse-of-inheritance) 111 | - [Abstract Classes](09-ClassOrientedProgramming.md#abstract-classes) 112 | - [Polymorphism](09-ClassOrientedProgramming.md#polymorphism) 113 | - [Controlled Visibility of Variables and Methods](09-ClassOrientedProgramming.md#controlled-visibility) 114 | - [Allowing for "Multiple Inheritance" in C++ was a mistake, and it was removed from Java, Kotlin and C# for very good reasons](09-ClassOrientedProgramming.md#multiple-inheritance-removed) 115 | - ["Design Patterns"](09-ClassOrientedProgramming.md#design-patterns) 116 | - [Functional Programming (FP)](10-FunctionalProgramming.md) 1950s-Present 117 | - Can we structure our code in a way to have less bugs and be easier to understand? 118 | - [Immutability & No Side Effects](10-FunctionalProgramming.md#immutability-no-side-effects) 119 | - [Functional Programming Style](10-FunctionalProgramming.md#functionalExample) 120 | - [Back-to Object Oriented Programming (BOOP)](11-BackToObjectOrientedProgramming.md) 1970s-Present 121 | - Can we re-visit the original principles of OOP to make software easier to understand and maintain? 122 | - [A word of caution about BOOP style](11-BackToObjectOrientedProgramming.md#boop-caution) 123 | - [Banned Patterns in BOOP](11-BackToObjectOrientedProgramming.md#banned-patterns-in-boop) 124 | - [Why is Class-Oriented Programming (COP) so bad?](11-BackToObjectOrientedProgramming.md#why-is-cop-bad) 125 | - [Back-to Object Oriented Programming Example](11-BackToObjectOrientedProgramming.md#boop-example) 126 | - [Parallel Processing (also called "Concurrent" Programming)](12-ParallelProcessing.md) 1960s-Present 127 | - Can we make our programs run faster by doing more than one thing at a time? 128 | - [Threads](12-ParallelProcessing.md#threads) 129 | - [Race Condition - Diagram](12-ParallelProcessing.md#race-condition-diagram) 130 | - [Fixing the threads "race condition" problem using "Atomic" updates](12-ParallelProcessing.md#atomic-updates) 131 | - [Fixing the Race Condition - Diagram](12-ParallelProcessing.md#atomic-updates-diagram) 132 | - [Coroutines](12-ParallelProcessing.md#coroutines) 133 | - [Fixing the Coroutine race condition problem using "Atomic" updates](12-ParallelProcessing.md#fixing-updates-with-coroutines) 134 | - [Coroutines are Much Faster Than Threads](12-ParallelProcessing.md#coroutines-vs-threads) 135 | - [Conclusion](13-Conclusion.md) 136 | - [Paradigms](13-Conclusion.md#paradigms) 137 | - [You Can Only Learn Programming By Actually Programming](13-Conclusion.md#learning_programming) 138 | - [Quit Looking for Short-Cuts](13-Conclusion.md#short-cuts) 139 | - [Programming is Always a Human Activity](13-Conclusion.md#programming-is-human) 140 | - [Computer Language Inheritance and Influence Map](13-Conclusion.md#history-graph) 141 | 142 | ## Introduction 143 | - This is a "how-to" guide for anyone interested in creating software who needs an overview of techniques and concepts 144 | used, from the fundamentals of physical logic representation to high-level programming languages and 145 | the "`how`" and "`why`" of the various paradigms and methodologies used in software development. 146 | 147 | - ### My Goal is to Have You: 148 | - Understand more the `why` and `how` of programming, not just the `what` and mechanical explanations. 149 | - This is my curated list of information to take you on a realistic and grounded journey of understanding 150 | the essential part of computing to create effective software. 151 | - There will be some technical details, but only enough to understand the fundamental principles, not to be an expert. 152 | - I cover the areas that I had difficulty understanding when I was learning to program. 153 | - This is more-or-less a historical walk through `WHY` things are the way they are in computing, and `HOW` they came to be that way. 154 | 155 | > I have since discovered that the majority of my confusion derived from how things were presented to me. 156 | > Instructors often completely misunderstood correct application and limits of metaphors and lacked real-world 157 | > experience of the things they were teaching. Many just repeated what they were taught without understanding. 158 | > When challenged about their knowledge, they would often become defensive and dismissive, and sometimes even hostile. 159 | 160 | > Many of the concepts are, in retrospect, full of needless jargon and unnecessary complexity. I now understand that 161 | > the complexity was often used to make the instructor seem more knowledgeable and to make the subject seem more 162 | > difficult than it actually is. 163 | 164 | > I would like to say at the outset that there is a TREMENDOUS number of technical-sounding words with all 165 | > referring to the same basic core ideas. I will do my best to be as consistent as possible, and also work to 166 | > point out the multiple definitions and reduce the jargon and clarify the core meanings and ideas. 167 | 168 | ## The Essence of Computing 169 | - People used to do all computing by hand, and now we use various machines to do the same thing, 170 | in a much faster and more reliable way. 171 | - When we use a machine to do computing, we are just using the machine to represent the problem and the 172 | solution in a different way. 173 | - The machine knows nothing about the problem. it's only following orders created by clever humans using 174 | boolean logic to represent the problem and its sequence of actions to solve it. 175 | - Each operation in the computer was once done by teams of people working in groups, logically delineated in 176 | nearly the same way as the computer's components are arranged. 177 | - There were specialized roles for each person, for example, the "storage" would be a set of filing cabinets 178 | and a clerk to store and retrieve them. 179 | - This is now done by the "hard drive" and the "file system" in the computer. 180 | - The arithmetic would be done by a person called a "calculator" who would perform the operations and record the results. 181 | - This is now done by the "Arithmetic Logic Unit" and stored in the "Registers" in the computer. 182 | 183 | ## SOME IMPORTANT ITEMS TO KEEP IN MIND 184 | - THERE IS NO MAGIC IN COMPUTING, ONLY _HUMAN_ CLEVERNESS, _HUMAN_ SYSTEMIC THINKING AND _HUMAN_ INGENUITY 185 | USED TO SOLVE _HUMAN_ PROBLEMS. 186 | - If you hear anyone say _"it's magic"_ or _"it's a black box"_ or _"it's kind of like a person,"_ 187 | they are: 188 | 1) Being lazy, 189 | 2) Or indicating it's not relevant at the moment, 190 | 3) Or (USUALLY) they don't understand the problem or the solution enough to explain it and become hand-wavy. 191 | 192 | - ## ITS ALWAYS JUST _HUMAN_ CLEVERNESS AND INGENUITY, THE IDEA OF REPRESENTING ONE THING AS ANOTHER, NOTHING MORE. 193 | 194 | - The machines CAN _NEVER_ UNDERSTAND the problem or the solution in the way humans conceive of the problem. 195 | - These machines are only following the logical operations that humans have carefully designed to represent 196 | the problem and a solution "space." There is no inherent "understanding" in the machine, and can never be. 197 | - The only way the machine would ever know the full human context of the problem (and the solution) is if 198 | the machine ACTUALLY was a human, and then it would be a _human_, and not a machine. 199 | - Mistaking the machine for having intelligence is known as "The Eliza Effect" and is a common mistake 200 | made by people who don't understand the limits of the machine's capabilities. 201 | 202 | # How To Install and Run The Samples In This Guide 203 | - [Install IntelliJ IDEA Community Edition](https://www.jetbrains.com/idea/download/) 204 | - [How to clone this Project from Github to your local machine](https://www.jetbrains.com/guide/java/tips/clone-project-from-github/#:~:text=Clone%20a%20project%20from%20the%20IntelliJ%20IDEA%20welcome%20screen&text=Click%20Get%20from%20VCS%2C%20specify,into%20an%20IntelliJ%20IDEA%20project.) 205 | - Navigate to this `README.md` file in the project and click on the links to the live sample code. 206 | - In the left-hand gutter, click on the green arrow to run the sample code. 207 | 208 | []() 209 | 210 | - [Continue Reading - The Essential Question](02-TheEssentialQuestion-WhatAreWeComputing.md) 211 | - [Back to Index](README.md) 212 | 213 | -------------------------------------------------------------------------------- /assets/10mb_hard_disk.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/realityexpander/How_to_program_from_ground_up/5112d50b95f4a03347faec6495e0c7004bf9fbff/assets/10mb_hard_disk.png -------------------------------------------------------------------------------- /assets/2dArraysInC.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/realityexpander/How_to_program_from_ground_up/5112d50b95f4a03347faec6495e0c7004bf9fbff/assets/2dArraysInC.png -------------------------------------------------------------------------------- /assets/2d_arrays.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/realityexpander/How_to_program_from_ground_up/5112d50b95f4a03347faec6495e0c7004bf9fbff/assets/2d_arrays.png -------------------------------------------------------------------------------- /assets/4004_simu_part.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/realityexpander/How_to_program_from_ground_up/5112d50b95f4a03347faec6495e0c7004bf9fbff/assets/4004_simu_part.gif -------------------------------------------------------------------------------- /assets/6502.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/realityexpander/How_to_program_from_ground_up/5112d50b95f4a03347faec6495e0c7004bf9fbff/assets/6502.png -------------------------------------------------------------------------------- /assets/8-bit-binary.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/realityexpander/How_to_program_from_ground_up/5112d50b95f4a03347faec6495e0c7004bf9fbff/assets/8-bit-binary.png -------------------------------------------------------------------------------- /assets/8-bit-counting-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/realityexpander/How_to_program_from_ground_up/5112d50b95f4a03347faec6495e0c7004bf9fbff/assets/8-bit-counting-2.png -------------------------------------------------------------------------------- /assets/ASCII-binary.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/realityexpander/How_to_program_from_ground_up/5112d50b95f4a03347faec6495e0c7004bf9fbff/assets/ASCII-binary.png -------------------------------------------------------------------------------- /assets/BDUF.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/realityexpander/How_to_program_from_ground_up/5112d50b95f4a03347faec6495e0c7004bf9fbff/assets/BDUF.png -------------------------------------------------------------------------------- /assets/BDUF2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/realityexpander/How_to_program_from_ground_up/5112d50b95f4a03347faec6495e0c7004bf9fbff/assets/BDUF2.png -------------------------------------------------------------------------------- /assets/Computer_block_diagram.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/realityexpander/How_to_program_from_ground_up/5112d50b95f4a03347faec6495e0c7004bf9fbff/assets/Computer_block_diagram.png -------------------------------------------------------------------------------- /assets/DRAM.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/realityexpander/How_to_program_from_ground_up/5112d50b95f4a03347faec6495e0c7004bf9fbff/assets/DRAM.png -------------------------------------------------------------------------------- /assets/MPU.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/realityexpander/How_to_program_from_ground_up/5112d50b95f4a03347faec6495e0c7004bf9fbff/assets/MPU.png -------------------------------------------------------------------------------- /assets/Map.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/realityexpander/How_to_program_from_ground_up/5112d50b95f4a03347faec6495e0c7004bf9fbff/assets/Map.png -------------------------------------------------------------------------------- /assets/NAND_equivalent.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/realityexpander/How_to_program_from_ground_up/5112d50b95f4a03347faec6495e0c7004bf9fbff/assets/NAND_equivalent.png -------------------------------------------------------------------------------- /assets/NAND_gate.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/realityexpander/How_to_program_from_ground_up/5112d50b95f4a03347faec6495e0c7004bf9fbff/assets/NAND_gate.png -------------------------------------------------------------------------------- /assets/NAND_gate_package.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/realityexpander/How_to_program_from_ground_up/5112d50b95f4a03347faec6495e0c7004bf9fbff/assets/NAND_gate_package.png -------------------------------------------------------------------------------- /assets/ParallelProgramming/2Options.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/realityexpander/How_to_program_from_ground_up/5112d50b95f4a03347faec6495e0c7004bf9fbff/assets/ParallelProgramming/2Options.png -------------------------------------------------------------------------------- /assets/ParallelProgramming/VennDiagramParallelConcurrent.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/realityexpander/How_to_program_from_ground_up/5112d50b95f4a03347faec6495e0c7004bf9fbff/assets/ParallelProgramming/VennDiagramParallelConcurrent.png -------------------------------------------------------------------------------- /assets/ParallelProgramming/sequential-concurrent-parallel.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/realityexpander/How_to_program_from_ground_up/5112d50b95f4a03347faec6495e0c7004bf9fbff/assets/ParallelProgramming/sequential-concurrent-parallel.png -------------------------------------------------------------------------------- /assets/ROM.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/realityexpander/How_to_program_from_ground_up/5112d50b95f4a03347faec6495e0c7004bf9fbff/assets/ROM.png -------------------------------------------------------------------------------- /assets/Why_NAND_gates_are_special.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/realityexpander/How_to_program_from_ground_up/5112d50b95f4a03347faec6495e0c7004bf9fbff/assets/Why_NAND_gates_are_special.png -------------------------------------------------------------------------------- /assets/abacus.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/realityexpander/How_to_program_from_ground_up/5112d50b95f4a03347faec6495e0c7004bf9fbff/assets/abacus.png -------------------------------------------------------------------------------- /assets/abacus2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/realityexpander/How_to_program_from_ground_up/5112d50b95f4a03347faec6495e0c7004bf9fbff/assets/abacus2.png -------------------------------------------------------------------------------- /assets/agile-deliver-sooner-not-faster.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/realityexpander/How_to_program_from_ground_up/5112d50b95f4a03347faec6495e0c7004bf9fbff/assets/agile-deliver-sooner-not-faster.png -------------------------------------------------------------------------------- /assets/agile-tm-r-c.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/realityexpander/How_to_program_from_ground_up/5112d50b95f4a03347faec6495e0c7004bf9fbff/assets/agile-tm-r-c.png -------------------------------------------------------------------------------- /assets/alan_kay.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/realityexpander/How_to_program_from_ground_up/5112d50b95f4a03347faec6495e0c7004bf9fbff/assets/alan_kay.png -------------------------------------------------------------------------------- /assets/andersons-law.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/realityexpander/How_to_program_from_ground_up/5112d50b95f4a03347faec6495e0c7004bf9fbff/assets/andersons-law.png -------------------------------------------------------------------------------- /assets/arrays.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/realityexpander/How_to_program_from_ground_up/5112d50b95f4a03347faec6495e0c7004bf9fbff/assets/arrays.png -------------------------------------------------------------------------------- /assets/ascii_hexadecimal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/realityexpander/How_to_program_from_ground_up/5112d50b95f4a03347faec6495e0c7004bf9fbff/assets/ascii_hexadecimal.png -------------------------------------------------------------------------------- /assets/beads_on_string.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/realityexpander/How_to_program_from_ground_up/5112d50b95f4a03347faec6495e0c7004bf9fbff/assets/beads_on_string.png -------------------------------------------------------------------------------- /assets/bigo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/realityexpander/How_to_program_from_ground_up/5112d50b95f4a03347faec6495e0c7004bf9fbff/assets/bigo.png -------------------------------------------------------------------------------- /assets/bjarne2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/realityexpander/How_to_program_from_ground_up/5112d50b95f4a03347faec6495e0c7004bf9fbff/assets/bjarne2.png -------------------------------------------------------------------------------- /assets/bjarnestroustrup.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/realityexpander/How_to_program_from_ground_up/5112d50b95f4a03347faec6495e0c7004bf9fbff/assets/bjarnestroustrup.png -------------------------------------------------------------------------------- /assets/break_thrus.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/realityexpander/How_to_program_from_ground_up/5112d50b95f4a03347faec6495e0c7004bf9fbff/assets/break_thrus.png -------------------------------------------------------------------------------- /assets/chip-wired-to-package.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/realityexpander/How_to_program_from_ground_up/5112d50b95f4a03347faec6495e0c7004bf9fbff/assets/chip-wired-to-package.png -------------------------------------------------------------------------------- /assets/click-green-arrow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/realityexpander/How_to_program_from_ground_up/5112d50b95f4a03347faec6495e0c7004bf9fbff/assets/click-green-arrow.png -------------------------------------------------------------------------------- /assets/computer_speed_miscommunicate.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/realityexpander/How_to_program_from_ground_up/5112d50b95f4a03347faec6495e0c7004bf9fbff/assets/computer_speed_miscommunicate.png -------------------------------------------------------------------------------- /assets/core_memory.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/realityexpander/How_to_program_from_ground_up/5112d50b95f4a03347faec6495e0c7004bf9fbff/assets/core_memory.png -------------------------------------------------------------------------------- /assets/cuneiform.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/realityexpander/How_to_program_from_ground_up/5112d50b95f4a03347faec6495e0c7004bf9fbff/assets/cuneiform.png -------------------------------------------------------------------------------- /assets/electrical_outlet.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/realityexpander/How_to_program_from_ground_up/5112d50b95f4a03347faec6495e0c7004bf9fbff/assets/electrical_outlet.png -------------------------------------------------------------------------------- /assets/electromagnet-with-switch.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/realityexpander/How_to_program_from_ground_up/5112d50b95f4a03347faec6495e0c7004bf9fbff/assets/electromagnet-with-switch.png -------------------------------------------------------------------------------- /assets/electromagnet.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/realityexpander/How_to_program_from_ground_up/5112d50b95f4a03347faec6495e0c7004bf9fbff/assets/electromagnet.png -------------------------------------------------------------------------------- /assets/functional-chart-annotated-old.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/realityexpander/How_to_program_from_ground_up/5112d50b95f4a03347faec6495e0c7004bf9fbff/assets/functional-chart-annotated-old.png -------------------------------------------------------------------------------- /assets/functional-chart-updated.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/realityexpander/How_to_program_from_ground_up/5112d50b95f4a03347faec6495e0c7004bf9fbff/assets/functional-chart-updated.png -------------------------------------------------------------------------------- /assets/functional-programming.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/realityexpander/How_to_program_from_ground_up/5112d50b95f4a03347faec6495e0c7004bf9fbff/assets/functional-programming.png -------------------------------------------------------------------------------- /assets/hexadecimal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/realityexpander/How_to_program_from_ground_up/5112d50b95f4a03347faec6495e0c7004bf9fbff/assets/hexadecimal.png -------------------------------------------------------------------------------- /assets/hollerith_counter.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/realityexpander/How_to_program_from_ground_up/5112d50b95f4a03347faec6495e0c7004bf9fbff/assets/hollerith_counter.png -------------------------------------------------------------------------------- /assets/kotlin-book.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/realityexpander/How_to_program_from_ground_up/5112d50b95f4a03347faec6495e0c7004bf9fbff/assets/kotlin-book.png -------------------------------------------------------------------------------- /assets/linkedList.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/realityexpander/How_to_program_from_ground_up/5112d50b95f4a03347faec6495e0c7004bf9fbff/assets/linkedList.png -------------------------------------------------------------------------------- /assets/logic-gate-package.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/realityexpander/How_to_program_from_ground_up/5112d50b95f4a03347faec6495e0c7004bf9fbff/assets/logic-gate-package.png -------------------------------------------------------------------------------- /assets/logicGateSymbols.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/realityexpander/How_to_program_from_ground_up/5112d50b95f4a03347faec6495e0c7004bf9fbff/assets/logicGateSymbols.png -------------------------------------------------------------------------------- /assets/magnetic_viewer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/realityexpander/How_to_program_from_ground_up/5112d50b95f4a03347faec6495e0c7004bf9fbff/assets/magnetic_viewer.png -------------------------------------------------------------------------------- /assets/mermaid_test.md: -------------------------------------------------------------------------------- 1 | 2 | ```mermaid 3 | flowchart LR 4 | 5 | catMakeSoundFunctionPointer -- calls --> catMakeSound 6 | subgraph catObject["[object instance Cat@19FCA68D]"] 7 | catAgeData["`age: 3`"] 8 | catMakeSoundFunctionPointer["`method makeSound(): 9 | calls 10 | function @C62F3842`"] 11 | end 12 | catAgeData -- stores value of --> catAgeInt 13 | 14 | catAbstractAgeInt -- expects --> catAgeInt 15 | abstractMethodMakeSound -- expects --> catMakeSound 16 | catAgeInt -- implements --> catAbstractAgeInt 17 | subgraph classCat["class Cat extend Animal"] 18 | catAgeInt["int age"] 19 | catMakeSound["`function @C62F3842: 20 | method makeSound() = 21 | { print “_Meow_” }`"] 22 | end 23 | 24 | classCat -- creates object --> catObject 25 | classCat -- extends --> abstractAnimal 26 | catMakeSound -- implements --> abstractMethodMakeSound 27 | %% dogMakeSound -- implements --> abstractMethodMakeSound 28 | %% abstractAnimal -- expects --> classDog 29 | subgraph abstractAnimal["abstract class Animal"] 30 | catAbstractAgeInt["`abstract 31 | int age`"] 32 | abstractMethodMakeSound("`abstract 33 | method makeSound()`") 34 | end 35 | 36 | %% classDog -- creates object --> dogObject 37 | %% subgraph classDog[actual class Dog] 38 | %% dogMakeSound["`[function @28FCA68D] 39 | %% method makeSound(): 40 | %% { return _Woof_ }`"] 41 | %% end 42 | 43 | %% dogMakeSoundFunctionPointer -- calls --> dogMakeSound 44 | %% subgraph dogObject["[Object Dog@78FDB7A9]"] 45 | %% dogMakeSoundFunctionPointer["`method makeSound(): 46 | %% calls Function @28FCA68D`"] 47 | %% 48 | %% end 49 | 50 | style abstractAnimal fill:#03A, stroke:#f66, stroke-width:2px, color:#fff, stroke-dasharray: 5 5 51 | style abstractMethodMakeSound fill:#03A, stroke:#f66, stroke-width:2px, color:#fff, stroke-dasharray: 5 5 52 | style catAbstractAgeInt fill:#03A, stroke:#f66, stroke-width:2px, color:#fff, stroke-dasharray: 5 5 53 | 54 | style classCat fill:#17F, stroke:#f66, stroke-width:2px, color:#fff, stroke-dasharray: 5 5 55 | style catAgeInt fill:#03A, stroke:#f66, stroke-width:2px, color:#fff, stroke-dasharray: 5 5 56 | 57 | style catMakeSoundFunctionPointer fill:#17F, stroke:#f66, stroke-width:2px, color:#fff, stroke-dasharray: 5 5 58 | 59 | %%style classDog fill:#17F, stroke:#f66, stroke-width:2px, color:#fff, stroke-dasharray: 5 5 60 | %% style classDog fill:#17F, stroke:#f66, stroke-width:2px, color:#fff, stroke-dasharray: 5 5 61 | style catObject fill:#69F, stroke:#f66, stroke-width:2px, color:#fff 62 | %% style dogObject fill:#69F, stroke:#f66, stroke-width:2px, color:#fff, stroke-dasharray: 5 5 63 | style catMakeSoundFunctionPointer stroke-dasharray: 5 5, stroke:#f66, stroke-width:2px 64 | style catAbstractAgeInt stroke-dasharray: 5 5, stroke:#f66, stroke-width:2px 65 | style catAgeInt stroke-dasharray: 5 5, stroke:#f66, stroke-width:2px 66 | ``` -------------------------------------------------------------------------------- /assets/motivational_debt.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/realityexpander/How_to_program_from_ground_up/5112d50b95f4a03347faec6495e0c7004bf9fbff/assets/motivational_debt.png -------------------------------------------------------------------------------- /assets/mutability-chart.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/realityexpander/How_to_program_from_ground_up/5112d50b95f4a03347faec6495e0c7004bf9fbff/assets/mutability-chart.png -------------------------------------------------------------------------------- /assets/new_compassionate_dev.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/realityexpander/How_to_program_from_ground_up/5112d50b95f4a03347faec6495e0c7004bf9fbff/assets/new_compassionate_dev.png -------------------------------------------------------------------------------- /assets/pacman_bytes.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/realityexpander/How_to_program_from_ground_up/5112d50b95f4a03347faec6495e0c7004bf9fbff/assets/pacman_bytes.png -------------------------------------------------------------------------------- /assets/paper_ledger.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/realityexpander/How_to_program_from_ground_up/5112d50b95f4a03347faec6495e0c7004bf9fbff/assets/paper_ledger.png -------------------------------------------------------------------------------- /assets/phyiscal_indentations.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/realityexpander/How_to_program_from_ground_up/5112d50b95f4a03347faec6495e0c7004bf9fbff/assets/phyiscal_indentations.png -------------------------------------------------------------------------------- /assets/plugs_and_adapters.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/realityexpander/How_to_program_from_ground_up/5112d50b95f4a03347faec6495e0c7004bf9fbff/assets/plugs_and_adapters.png -------------------------------------------------------------------------------- /assets/pointer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/realityexpander/How_to_program_from_ground_up/5112d50b95f4a03347faec6495e0c7004bf9fbff/assets/pointer.png -------------------------------------------------------------------------------- /assets/proceduralProgrammerMadeLoops.bas: -------------------------------------------------------------------------------- 1 | 1 REM COPY AND PASTE THIS AT: https://www.calormen.com/jsbasic/ 2 | 5 REM PROGRAM TO DEMO PROGRAMMER MADE "LOOP" TO CREATE A CUMULATIVE ADDITION TABLE 3 | 10 LET A = 1 4 | 20 GOSUB 100 5 | 30 PRINT A, B 6 | 40 LET A = A + 1 7 | 50 IF A <= 10 THEN GOTO 20 8 | 60 END 9 | 100 REM ADD A PLUS B, RESULT IN B 10 | 110 LET B = A + B 11 | 120 RETURN 12 | 13 | 1000 REM EXPECTED OUTPUT: 14 | 1010 REM 1 1 15 | 1020 REM 2 3 16 | 1030 REM 3 6 17 | 1040 REM 4 10 18 | 1050 REM 5 15 19 | 1060 REM 6 21 20 | 1070 REM 7 28 21 | 1080 REM 8 36 22 | 1090 REM 9 45 23 | 1100 REM 10 55 -------------------------------------------------------------------------------- /assets/proceduralUnrolledLoops.bas: -------------------------------------------------------------------------------- 1 | 1 REM COPY AND PASTE THIS AT: https://www.calormen.com/jsbasic/ 2 | 5 REM PROGRAM TO DEMO "WITHOUT LOOPS" TO CREATE A CUMULATIVE ADDITION TABLE 3 | 10 LET A = 1 4 | 20 GOSUB 400 5 | 30 PRINT A, B 6 | 40 LET A = A + 1 7 | 50 GOSUB 400 8 | 60 PRINT A, B 9 | 70 LET A = A + 1 10 | 80 GOSUB 400 11 | 90 PRINT A, B 12 | 100 LET A = A + 1 13 | 110 GOSUB 400 14 | 120 PRINT A, B 15 | 130 LET A = A + 1 16 | 140 GOSUB 400 17 | 150 PRINT A, B 18 | 160 LET A = A + 1 19 | 170 GOSUB 400 20 | 180 PRINT A, B 21 | 190 LET A = A + 1 22 | 200 GOSUB 400 23 | 210 PRINT A, B 24 | 220 LET A = A + 1 25 | 230 GOSUB 400 26 | 240 PRINT A, B 27 | 250 LET A = A + 1 28 | 260 GOSUB 400 29 | 270 PRINT A, B 30 | 280 LET A = A + 1 31 | 290 GOSUB 400 32 | 300 PRINT A, B 33 | 310 END 34 | 400 REM ADD A PLUS B, RESULT IN B 35 | 410 LET B = A + B 36 | 420 RETURN 37 | 38 | 1000 REM EXPECTED OUTPUT: 39 | 1010 REM 1 1 40 | 1020 REM 2 3 41 | 1030 REM 3 6 42 | 1040 REM 4 10 43 | 1050 REM 5 15 44 | 1060 REM 6 21 45 | 1070 REM 7 28 46 | 1080 REM 8 36 47 | 1090 REM 9 45 48 | 1100 REM 10 55 -------------------------------------------------------------------------------- /assets/proceduralWithForLoop.bas: -------------------------------------------------------------------------------- 1 | 1 REM COPY AND PASTE THIS AT: https://www.calormen.com/jsbasic/ 2 | 5 REM PROGRAM TO DEMO "FOR LOOP" TO CREATE A CUMULATIVE ADDITION TABLE 3 | 10 FOR A = 1 TO 10 STEP 1 4 | 15 GOSUB 100 5 | 20 PRINT A, B 6 | 30 NEXT A 7 | 40 END 8 | 100 REM ADD A PLUS B, RESULT IN B 9 | 110 LET B = A + B 10 | 120 RETURN 11 | 12 | 1000 REM EXPECTED OUTPUT: 13 | 1010 REM 1 1 14 | 1020 REM 2 3 15 | 1030 REM 3 6 16 | 1040 REM 4 10 17 | 1050 REM 5 15 18 | 1060 REM 6 21 19 | 1070 REM 7 28 20 | 1080 REM 8 36 21 | 1090 REM 9 45 22 | 1100 REM 10 55 -------------------------------------------------------------------------------- /assets/proceduralWithGosub.bas: -------------------------------------------------------------------------------- 1 | 1 REM COPY AND PASTE THIS AT: https://www.calormen.com/jsbasic/ 2 | 5 REM PROGRAM TO ADD 2 NUMBERS, PRINT RESULT USING GOSUB 3 | 10 LET X = 10 4 | 20 LET Y = 32 5 | 30 GOSUB 100 6 | 40 PRINT "Output 1: "; Z 7 | 50 LET X = 110 8 | 70 GOSUB 100 9 | 80 PRINT "Output 2: "; Z 10 | 90 END 11 | 100 REM ADD X PLUS Y, RESULT IN Z 12 | 110 LET Z = X + Y 13 | 120 RETURN 14 | 15 | 1000 REM EXPECTED OUTPUT: 16 | 1010 REM Output 1: 42 17 | 1020 REM Output 2: 142 -------------------------------------------------------------------------------- /assets/proceduralWithGoto.bas: -------------------------------------------------------------------------------- 1 | 1 REM COPY AND PASTE THIS AT: https://www.calormen.com/jsbasic/ 2 | 5 REM PROGRAM TO ADD 2 NUMBERS, PRINT RESULT 3 | 10 LET X = 10 4 | 20 LET Y = 32 5 | 30 GOTO 100 6 | 40 PRINT "Output: "; Z 7 | 50 GOTO 150 8 | 60 IF X = 10 THEN GOTO 190 9 | 70 GOTO 10 10 | 100 REM ADD X PLUS Y, RESULT IN Z 11 | 110 LET Z = X + Y 12 | 120 GOTO 40 13 | 150 PRINT "THIS GOTO STUFF CAN GET CONFUSING" 14 | 160 GOTO 60 15 | 190 PRINT "HOW DID I GET HERE?" 16 | 220 END 17 | 18 | 1000 REM EXPECTED OUTPUT: 19 | 1010 REM Output: 42 20 | 1020 REM THIS GOTO STUFF CAN GET CONFUSING 21 | 1030 REM HOW DID I GET HERE? -------------------------------------------------------------------------------- /assets/programs_for_people.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/realityexpander/How_to_program_from_ground_up/5112d50b95f4a03347faec6495e0c7004bf9fbff/assets/programs_for_people.png -------------------------------------------------------------------------------- /assets/punched_card.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/realityexpander/How_to_program_from_ground_up/5112d50b95f4a03347faec6495e0c7004bf9fbff/assets/punched_card.png -------------------------------------------------------------------------------- /assets/pyramid_of_results.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/realityexpander/How_to_program_from_ground_up/5112d50b95f4a03347faec6495e0c7004bf9fbff/assets/pyramid_of_results.png -------------------------------------------------------------------------------- /assets/queue.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/realityexpander/How_to_program_from_ground_up/5112d50b95f4a03347faec6495e0c7004bf9fbff/assets/queue.png -------------------------------------------------------------------------------- /assets/race-condition-quote.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/realityexpander/How_to_program_from_ground_up/5112d50b95f4a03347faec6495e0c7004bf9fbff/assets/race-condition-quote.png -------------------------------------------------------------------------------- /assets/seven_segment/7-segment-BCD-block-diagram-displaying-5.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/realityexpander/How_to_program_from_ground_up/5112d50b95f4a03347faec6495e0c7004bf9fbff/assets/seven_segment/7-segment-BCD-block-diagram-displaying-5.webp -------------------------------------------------------------------------------- /assets/seven_segment/7-segment-display-truth-table.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/realityexpander/How_to_program_from_ground_up/5112d50b95f4a03347faec6495e0c7004bf9fbff/assets/seven_segment/7-segment-display-truth-table.webp -------------------------------------------------------------------------------- /assets/seven_segment/7-segment-display.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/realityexpander/How_to_program_from_ground_up/5112d50b95f4a03347faec6495e0c7004bf9fbff/assets/seven_segment/7-segment-display.webp -------------------------------------------------------------------------------- /assets/seven_segment/74HC42.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/realityexpander/How_to_program_from_ground_up/5112d50b95f4a03347faec6495e0c7004bf9fbff/assets/seven_segment/74HC42.jpg -------------------------------------------------------------------------------- /assets/seven_segment/BCD-to-7-Segment-Display-Decoder.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/realityexpander/How_to_program_from_ground_up/5112d50b95f4a03347faec6495e0c7004bf9fbff/assets/seven_segment/BCD-to-7-Segment-Display-Decoder.png -------------------------------------------------------------------------------- /assets/seven_segment/BCD-to-7-segment-Decoder-Design-Using-Basic-Gates.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/realityexpander/How_to_program_from_ground_up/5112d50b95f4a03347faec6495e0c7004bf9fbff/assets/seven_segment/BCD-to-7-segment-Decoder-Design-Using-Basic-Gates.jpg -------------------------------------------------------------------------------- /assets/seven_segment/Internal-Schematic-Common-Cathode-7-Segment-LED-Display.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/realityexpander/How_to_program_from_ground_up/5112d50b95f4a03347faec6495e0c7004bf9fbff/assets/seven_segment/Internal-Schematic-Common-Cathode-7-Segment-LED-Display.png -------------------------------------------------------------------------------- /assets/seven_segment/Inverter-Gate-and-NAND-gate-under-50x-microscope.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/realityexpander/How_to_program_from_ground_up/5112d50b95f4a03347faec6495e0c7004bf9fbff/assets/seven_segment/Inverter-Gate-and-NAND-gate-under-50x-microscope.png -------------------------------------------------------------------------------- /assets/seven_segment/Schematic-of-BCD-to-Decimal-Decoder.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/realityexpander/How_to_program_from_ground_up/5112d50b95f4a03347faec6495e0c7004bf9fbff/assets/seven_segment/Schematic-of-BCD-to-Decimal-Decoder.png -------------------------------------------------------------------------------- /assets/seven_segment/Seven_segment_01_Pengo.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/realityexpander/How_to_program_from_ground_up/5112d50b95f4a03347faec6495e0c7004bf9fbff/assets/seven_segment/Seven_segment_01_Pengo.jpg -------------------------------------------------------------------------------- /assets/simpleSwitch.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/realityexpander/How_to_program_from_ground_up/5112d50b95f4a03347faec6495e0c7004bf9fbff/assets/simpleSwitch.png -------------------------------------------------------------------------------- /assets/spiral_model.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/realityexpander/How_to_program_from_ground_up/5112d50b95f4a03347faec6495e0c7004bf9fbff/assets/spiral_model.png -------------------------------------------------------------------------------- /assets/spiral_of_evolution.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/realityexpander/How_to_program_from_ground_up/5112d50b95f4a03347faec6495e0c7004bf9fbff/assets/spiral_of_evolution.png -------------------------------------------------------------------------------- /assets/stack.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/realityexpander/How_to_program_from_ground_up/5112d50b95f4a03347faec6495e0c7004bf9fbff/assets/stack.png -------------------------------------------------------------------------------- /assets/strings.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/realityexpander/How_to_program_from_ground_up/5112d50b95f4a03347faec6495e0c7004bf9fbff/assets/strings.png -------------------------------------------------------------------------------- /assets/test.md: -------------------------------------------------------------------------------- 1 | ```mermaid 2 | flowchart LR 3 | 4 | catObjectMakeSoundMethodFunctionPointer -- calls --> catClassMakeSoundMethod:::Object 5 | catObjectAgeInt -- stores value of --> catClassAgeInt 6 | subgraph catObject["[One “Cat” object instance @19FCA68D]"] 7 | catObjectAgeInt["int age = 3"] 8 | catObjectMakeSoundMethodFunctionPointer{"method makeSound(): 9 | calls 10 | function @C62F3842 11 | in Class Cat"} 12 | end 13 | 14 | abstractAgeInt -- ”expects” --> catClassAgeInt 15 | abstractMakeSoundMethod -- “expects” --> catClassMakeSoundMethod:::Object 16 | catClassAgeInt -- implements --> abstractAgeInt:::Abstract 17 | subgraph classCat["class Cat extends Animal"] 18 | catClassAgeInt["int age"] 19 | catClassMakeSoundMethod{"function @C62F3842: 20 | method makeSound() = 21 | { print “Meow” }"} 22 | end 23 | 24 | classCat -- creates object --> catObject:::Object 25 | classCat -- extends --> abstractAnimal:::Abstract 26 | catClassMakeSoundMethod -- implements --> abstractMakeSoundMethod:::Abstract 27 | subgraph abstractAnimal["abstract class Animal"] 28 | abstractAgeInt["abstract int age"] 29 | abstractMakeSoundMethod{"abstract method 30 | makeSound()"} 31 | end 32 | 33 | classDef Abstract fill:#222, stroke:#0F0, stroke-width:1px, color:#fff, stroke-dasharray: 5 5 34 | 35 | classDef Class fill:#444, stroke:#00F, stroke-width:1px, color:#000, stroke-dasharray: 5 5 36 | style classCat fill:#444, stroke:#DDD, stroke-width:1px, color:#000, stroke-dasharray: 5 5 37 | style catClassAgeInt fill:#444, stroke:#DDD, stroke-width:1px, color:#FFF, stroke-dasharray: 5 5 38 | 39 | classDef Object fill:#55F, stroke:#FFF, stroke-width:3px, color:#fff 40 | style catObjectAgeInt fill:#55F, stroke:#FFF, stroke-width:3px, color:#fff 41 | style catObjectMakeSoundMethodFunctionPointer fill:#222, stroke:#DDD, stroke-width:1px, color:#000, stroke-dasharray: 5 5 42 | ``` -------------------------------------------------------------------------------- /assets/the_ic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/realityexpander/How_to_program_from_ground_up/5112d50b95f4a03347faec6495e0c7004bf9fbff/assets/the_ic.png -------------------------------------------------------------------------------- /assets/things-to-know.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/realityexpander/How_to_program_from_ground_up/5112d50b95f4a03347faec6495e0c7004bf9fbff/assets/things-to-know.png -------------------------------------------------------------------------------- /assets/thread-time-diagram.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/realityexpander/How_to_program_from_ground_up/5112d50b95f4a03347faec6495e0c7004bf9fbff/assets/thread-time-diagram.png -------------------------------------------------------------------------------- /assets/title.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/realityexpander/How_to_program_from_ground_up/5112d50b95f4a03347faec6495e0c7004bf9fbff/assets/title.png -------------------------------------------------------------------------------- /assets/toaster.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/realityexpander/How_to_program_from_ground_up/5112d50b95f4a03347faec6495e0c7004bf9fbff/assets/toaster.png -------------------------------------------------------------------------------- /assets/transistor-electron-microscope.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/realityexpander/How_to_program_from_ground_up/5112d50b95f4a03347faec6495e0c7004bf9fbff/assets/transistor-electron-microscope.png -------------------------------------------------------------------------------- /assets/transistor_vs_tube.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/realityexpander/How_to_program_from_ground_up/5112d50b95f4a03347faec6495e0c7004bf9fbff/assets/transistor_vs_tube.png -------------------------------------------------------------------------------- /assets/trash-driven-dev.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/realityexpander/How_to_program_from_ground_up/5112d50b95f4a03347faec6495e0c7004bf9fbff/assets/trash-driven-dev.png -------------------------------------------------------------------------------- /assets/tree.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/realityexpander/How_to_program_from_ground_up/5112d50b95f4a03347faec6495e0c7004bf9fbff/assets/tree.png -------------------------------------------------------------------------------- /assets/tutorial-tar-pits.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/realityexpander/How_to_program_from_ground_up/5112d50b95f4a03347faec6495e0c7004bf9fbff/assets/tutorial-tar-pits.png -------------------------------------------------------------------------------- /assets/tv_with_plug.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/realityexpander/How_to_program_from_ground_up/5112d50b95f4a03347faec6495e0c7004bf9fbff/assets/tv_with_plug.png -------------------------------------------------------------------------------- /assets/vacuum_tube.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/realityexpander/How_to_program_from_ground_up/5112d50b95f4a03347faec6495e0c7004bf9fbff/assets/vacuum_tube.png -------------------------------------------------------------------------------- /assets/vacuum_tube_diagram.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/realityexpander/How_to_program_from_ground_up/5112d50b95f4a03347faec6495e0c7004bf9fbff/assets/vacuum_tube_diagram.png -------------------------------------------------------------------------------- /assets/williams_tube.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/realityexpander/How_to_program_from_ground_up/5112d50b95f4a03347faec6495e0c7004bf9fbff/assets/williams_tube.png -------------------------------------------------------------------------------- /assets/williams_tube2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/realityexpander/How_to_program_from_ground_up/5112d50b95f4a03347faec6495e0c7004bf9fbff/assets/williams_tube2.png -------------------------------------------------------------------------------- /assets/williams_tube3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/realityexpander/How_to_program_from_ground_up/5112d50b95f4a03347faec6495e0c7004bf9fbff/assets/williams_tube3.png -------------------------------------------------------------------------------- /assets/yegor_bugayenko.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/realityexpander/How_to_program_from_ground_up/5112d50b95f4a03347faec6495e0c7004bf9fbff/assets/yegor_bugayenko.png -------------------------------------------------------------------------------- /build.gradle.kts: -------------------------------------------------------------------------------- 1 | plugins { 2 | kotlin("jvm") version "1.9.22" 3 | } 4 | 5 | group = "org.example" 6 | version = "1.0-SNAPSHOT" 7 | 8 | repositories { 9 | mavenCentral() 10 | } 11 | 12 | dependencies { 13 | testImplementation("org.jetbrains.kotlin:kotlin-test") 14 | 15 | // Coroutines 16 | implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.5.2") 17 | } 18 | 19 | tasks.test { 20 | useJUnitPlatform() 21 | } 22 | kotlin { 23 | jvmToolchain(11) 24 | } -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | kotlin.code.style=official 2 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/realityexpander/How_to_program_from_ground_up/5112d50b95f4a03347faec6495e0c7004bf9fbff/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Tue Feb 06 13:13:06 CST 2024 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.4-bin.zip 5 | zipStoreBase=GRADLE_USER_HOME 6 | zipStorePath=wrapper/dists 7 | -------------------------------------------------------------------------------- /gradlew: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # 4 | # Copyright © 2015-2021 the original authors. 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # https://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | # 18 | 19 | ############################################################################## 20 | # 21 | # Gradle start up script for POSIX generated by Gradle. 22 | # 23 | # Important for running: 24 | # 25 | # (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is 26 | # noncompliant, but you have some other compliant shell such as ksh or 27 | # bash, then to run this script, type that shell name before the whole 28 | # command line, like: 29 | # 30 | # ksh Gradle 31 | # 32 | # Busybox and similar reduced shells will NOT work, because this script 33 | # requires all of these POSIX shell features: 34 | # * functions; 35 | # * expansions «$var», «${var}», «${var:-default}», «${var+SET}», 36 | # «${var#prefix}», «${var%suffix}», and «$( cmd )»; 37 | # * compound commands having a testable exit status, especially «case»; 38 | # * various built-in commands including «command», «set», and «ulimit». 39 | # 40 | # Important for patching: 41 | # 42 | # (2) This script targets any POSIX shell, so it avoids extensions provided 43 | # by Bash, Ksh, etc; in particular arrays are avoided. 44 | # 45 | # The "traditional" practice of packing multiple parameters into a 46 | # space-separated string is a well documented source of bugs and security 47 | # problems, so this is (mostly) avoided, by progressively accumulating 48 | # options in "$@", and eventually passing that to Java. 49 | # 50 | # Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, 51 | # and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; 52 | # see the in-line comments for details. 53 | # 54 | # There are tweaks for specific operating systems such as AIX, CygWin, 55 | # Darwin, MinGW, and NonStop. 56 | # 57 | # (3) This script is generated from the Groovy template 58 | # https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt 59 | # within the Gradle project. 60 | # 61 | # You can find Gradle at https://github.com/gradle/gradle/. 62 | # 63 | ############################################################################## 64 | 65 | # Attempt to set APP_HOME 66 | 67 | # Resolve links: $0 may be a link 68 | app_path=$0 69 | 70 | # Need this for daisy-chained symlinks. 71 | while 72 | APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path 73 | [ -h "$app_path" ] 74 | do 75 | ls=$( ls -ld "$app_path" ) 76 | link=${ls#*' -> '} 77 | case $link in #( 78 | /*) app_path=$link ;; #( 79 | *) app_path=$APP_HOME$link ;; 80 | esac 81 | done 82 | 83 | APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit 84 | 85 | APP_NAME="Gradle" 86 | APP_BASE_NAME=${0##*/} 87 | 88 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 89 | DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' 90 | 91 | # Use the maximum available, or set MAX_FD != -1 to use that value. 92 | MAX_FD=maximum 93 | 94 | warn () { 95 | echo "$*" 96 | } >&2 97 | 98 | die () { 99 | echo 100 | echo "$*" 101 | echo 102 | exit 1 103 | } >&2 104 | 105 | # OS specific support (must be 'true' or 'false'). 106 | cygwin=false 107 | msys=false 108 | darwin=false 109 | nonstop=false 110 | case "$( uname )" in #( 111 | CYGWIN* ) cygwin=true ;; #( 112 | Darwin* ) darwin=true ;; #( 113 | MSYS* | MINGW* ) msys=true ;; #( 114 | NONSTOP* ) nonstop=true ;; 115 | esac 116 | 117 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 118 | 119 | 120 | # Determine the Java command to use to start the JVM. 121 | if [ -n "$JAVA_HOME" ] ; then 122 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 123 | # IBM's JDK on AIX uses strange locations for the executables 124 | JAVACMD=$JAVA_HOME/jre/sh/java 125 | else 126 | JAVACMD=$JAVA_HOME/bin/java 127 | fi 128 | if [ ! -x "$JAVACMD" ] ; then 129 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 130 | 131 | Please set the JAVA_HOME variable in your environment to match the 132 | location of your Java installation." 133 | fi 134 | else 135 | JAVACMD=java 136 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 137 | 138 | Please set the JAVA_HOME variable in your environment to match the 139 | location of your Java installation." 140 | fi 141 | 142 | # Increase the maximum file descriptors if we can. 143 | if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then 144 | case $MAX_FD in #( 145 | max*) 146 | MAX_FD=$( ulimit -H -n ) || 147 | warn "Could not query maximum file descriptor limit" 148 | esac 149 | case $MAX_FD in #( 150 | '' | soft) :;; #( 151 | *) 152 | ulimit -n "$MAX_FD" || 153 | warn "Could not set maximum file descriptor limit to $MAX_FD" 154 | esac 155 | fi 156 | 157 | # Collect all arguments for the java command, stacking in reverse order: 158 | # * args from the command line 159 | # * the main class name 160 | # * -classpath 161 | # * -D...appname settings 162 | # * --module-path (only if needed) 163 | # * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. 164 | 165 | # For Cygwin or MSYS, switch paths to Windows format before running java 166 | if "$cygwin" || "$msys" ; then 167 | APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) 168 | CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) 169 | 170 | JAVACMD=$( cygpath --unix "$JAVACMD" ) 171 | 172 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 173 | for arg do 174 | if 175 | case $arg in #( 176 | -*) false ;; # don't mess with options #( 177 | /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath 178 | [ -e "$t" ] ;; #( 179 | *) false ;; 180 | esac 181 | then 182 | arg=$( cygpath --path --ignore --mixed "$arg" ) 183 | fi 184 | # Roll the args list around exactly as many times as the number of 185 | # args, so each arg winds up back in the position where it started, but 186 | # possibly modified. 187 | # 188 | # NB: a `for` loop captures its iteration list before it begins, so 189 | # changing the positional parameters here affects neither the number of 190 | # iterations, nor the values presented in `arg`. 191 | shift # remove old arg 192 | set -- "$@" "$arg" # push replacement arg 193 | done 194 | fi 195 | 196 | # Collect all arguments for the java command; 197 | # * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of 198 | # shell script including quotes and variable substitutions, so put them in 199 | # double quotes to make sure that they get re-expanded; and 200 | # * put everything else in single quotes, so that it's not re-expanded. 201 | 202 | set -- \ 203 | "-Dorg.gradle.appname=$APP_BASE_NAME" \ 204 | -classpath "$CLASSPATH" \ 205 | org.gradle.wrapper.GradleWrapperMain \ 206 | "$@" 207 | 208 | # Use "xargs" to parse quoted args. 209 | # 210 | # With -n1 it outputs one arg per line, with the quotes and backslashes removed. 211 | # 212 | # In Bash we could simply go: 213 | # 214 | # readarray ARGS < <( xargs -n1 <<<"$var" ) && 215 | # set -- "${ARGS[@]}" "$@" 216 | # 217 | # but POSIX shell has neither arrays nor command substitution, so instead we 218 | # post-process each arg (as a line of input to sed) to backslash-escape any 219 | # character that might be a shell metacharacter, then use eval to reverse 220 | # that process (while maintaining the separation between arguments), and wrap 221 | # the whole thing up as a single "set" statement. 222 | # 223 | # This will of course break if any of these variables contains a newline or 224 | # an unmatched quote. 225 | # 226 | 227 | eval "set -- $( 228 | printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | 229 | xargs -n1 | 230 | sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | 231 | tr '\n' ' ' 232 | )" '"$@"' 233 | 234 | exec "$JAVACMD" "$@" 235 | -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @rem 2 | @rem Copyright 2015 the original author or authors. 3 | @rem 4 | @rem Licensed under the Apache License, Version 2.0 (the "License"); 5 | @rem you may not use this file except in compliance with the License. 6 | @rem You may obtain a copy of the License at 7 | @rem 8 | @rem https://www.apache.org/licenses/LICENSE-2.0 9 | @rem 10 | @rem Unless required by applicable law or agreed to in writing, software 11 | @rem distributed under the License is distributed on an "AS IS" BASIS, 12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | @rem See the License for the specific language governing permissions and 14 | @rem limitations under the License. 15 | @rem 16 | 17 | @if "%DEBUG%" == "" @echo off 18 | @rem ########################################################################## 19 | @rem 20 | @rem Gradle startup script for Windows 21 | @rem 22 | @rem ########################################################################## 23 | 24 | @rem Set local scope for the variables with windows NT shell 25 | if "%OS%"=="Windows_NT" setlocal 26 | 27 | set DIRNAME=%~dp0 28 | if "%DIRNAME%" == "" set DIRNAME=. 29 | set APP_BASE_NAME=%~n0 30 | set APP_HOME=%DIRNAME% 31 | 32 | @rem Resolve any "." and ".." in APP_HOME to make it shorter. 33 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi 34 | 35 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 36 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" 37 | 38 | @rem Find java.exe 39 | if defined JAVA_HOME goto findJavaFromJavaHome 40 | 41 | set JAVA_EXE=java.exe 42 | %JAVA_EXE% -version >NUL 2>&1 43 | if "%ERRORLEVEL%" == "0" goto execute 44 | 45 | echo. 46 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 47 | echo. 48 | echo Please set the JAVA_HOME variable in your environment to match the 49 | echo location of your Java installation. 50 | 51 | goto fail 52 | 53 | :findJavaFromJavaHome 54 | set JAVA_HOME=%JAVA_HOME:"=% 55 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 56 | 57 | if exist "%JAVA_EXE%" goto execute 58 | 59 | echo. 60 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 61 | echo. 62 | echo Please set the JAVA_HOME variable in your environment to match the 63 | echo location of your Java installation. 64 | 65 | goto fail 66 | 67 | :execute 68 | @rem Setup the command line 69 | 70 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 71 | 72 | 73 | @rem Execute Gradle 74 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* 75 | 76 | :end 77 | @rem End local scope for the variables with windows NT shell 78 | if "%ERRORLEVEL%"=="0" goto mainEnd 79 | 80 | :fail 81 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 82 | rem the _cmd.exe /c_ return code! 83 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 84 | exit /b 1 85 | 86 | :mainEnd 87 | if "%OS%"=="Windows_NT" endlocal 88 | 89 | :omega 90 | -------------------------------------------------------------------------------- /settings.gradle.kts: -------------------------------------------------------------------------------- 1 | plugins { 2 | id("org.gradle.toolchains.foojay-resolver-convention") version "0.5.0" 3 | } 4 | rootProject.name = "How_to_program_from_ground_up" 5 | 6 | -------------------------------------------------------------------------------- /src/main/kotlin/Main.kt: -------------------------------------------------------------------------------- 1 | //TIP To Run code, press or 2 | // click the icon in the gutter. 3 | fun main() { 4 | val name = "Kotlin" 5 | //TIP Press with your caret at the highlighted text 6 | // to see how IntelliJ IDEA suggests fixing it. 7 | println("Hello, " + name + "!") 8 | 9 | for (i in 1..5) { 10 | //TIP Press to start debugging your code. We have set one breakpoint 11 | // for you, but you can always add more by pressing . 12 | println("i = $i") 13 | } 14 | } 15 | 16 | 17 | -------------------------------------------------------------------------------- /src/main/kotlin/abstractClassExample.kt: -------------------------------------------------------------------------------- 1 | // Kotlin example of an abstract class and inheritance, secondary constructors, and default parameter values. 2 | // Also shows the beginning of a design flaw in the `Memo` class inherited from the `File` class. 3 | 4 | abstract class File( 5 | val fileName: String // <-- The primary constructor of the abstract class, initializes property `fileName`. 6 | ) { 7 | abstract fun view() // Expects a fun called "view" and has no default implementation. 8 | open fun showName() { // Expects a fun called "showName" and has a default implementation. 9 | println("File Name: " + this.fileName) // <-- The "default implementation" for any subclass that doesn't override the fun. 10 | } 11 | } 12 | 13 | class ExcelDoc( 14 | fileName: String 15 | ): File(fileName) { // <-- ExcelDoc is a subclass of File, also called a "type" of File. 16 | override fun view() { // <-- the implementation of the abstract class "view". 17 | println("Viewing ExcelDoc: " + this.fileName) 18 | } 19 | } 20 | 21 | class Photo( 22 | fileName: String 23 | ): File(fileName) { // <-- Photo is a subclass of File, also called a "type" of File. 24 | override fun view() { // <-- the implementation of the abstract class "view". 25 | println("Viewing Photo: " + this.fileName) 26 | } 27 | } 28 | 29 | class Memo( 30 | fileName: String, 31 | private val to: String, 32 | private val from: String, 33 | private val subject: String 34 | ): File(fileName) { // <-- Memo is a subclass of File. 35 | 36 | constructor(to: String, from: String, subject: String): this( // <-- Secondary constructor. 37 | "Memo-$to|$from|$subject.memo", 38 | to, 39 | from, 40 | subject 41 | ) 42 | 43 | override fun view() { // <-- The implementation of the abstract class "view". 44 | super.showName() // <-- Calls the "default implementation" of the abstract superclass. 45 | // Calls to the superclass are not required, but often used to call any 46 | // implementations of the superclass. This is a way to reuse code functionality. 47 | 48 | println("Viewing Memo: from= " + this.from + ", to= " + this.to + ", subject= " + this.subject) 49 | } 50 | 51 | override fun showName() { // <-- overrides the "default implementation" of the abstract superclass. 52 | // Displays name of who the memo is "to" & "from" 53 | println("Memo: ${this.to} to ${this.from}") // <-- Shows addressees of the memo, *NOT* just the file name... 54 | // Design problems already creeping in.... 55 | } 56 | 57 | fun send() { // <-- A new function that is not part of the abstract class. 58 | println("Sending Memo: from= " + this.from + ", to= " + this.to + ", subject= " + this.subject) 59 | } 60 | } 61 | 62 | // Start of program 63 | fun main() { 64 | // val file0: File = File("MyFile") // <-- Since the `File` class is `abstract`, an object 65 | // cannot be created from it. this will cause a compiler error. 66 | val file1: File = ExcelDoc("MyExcelDoc.xls") 67 | val file2: Photo = Photo("MyPhoto.jpg") 68 | val file3: Memo = Memo(to="Chris", from="Bob", subject="Meeting") // <-- `file3` is of type `Memo` and not 69 | // `File` because we want to access the 70 | // `send` method. 71 | 72 | fun viewFile(file: File) { // <-- Parameter `file` is type `File` and not `ExcelDoc` or `Photo` or `Memo`. 73 | file.view() 74 | } 75 | 76 | viewFile(file1) // <-- Calls the "view" fun of the ExcelDoc class 77 | viewFile(file2) // <-- Calls the "view" fun of the Memo class 78 | viewFile(file3) // <-- Calls the "view" fun of the Photo class 79 | 80 | println() // <-- Just to separate the output of the `viewFile` calls from the `showName` and `send` calls. 81 | file1.showName() // <-- Calls the "showName" fun of the ExcelDoc class. 82 | file3.showName() // <-- Calls the "showName" fun of the Memo class, notice the design flaw here? 83 | file3.send() // <-- Calls the "send" function of the Memo class, not part of the abstract class. 84 | } 85 | 86 | // Output: 87 | // Viewing ExcelDoc: MyExcelDoc.xls 88 | // Viewing Photo: MyPhoto.jpg 89 | // File Name: Memo-Chris|Bob|Meeting.memo 90 | // Viewing Memo: from= Bob, to= Chris, subject= Meeting 91 | // 92 | // File Name: MyExcelDoc.xls 93 | // Memo: Chris to Bob -------------------------------------------------------------------------------- /src/main/kotlin/boopExample.kt: -------------------------------------------------------------------------------- 1 | // BOOP Programming Example (Back-to Object Oriented Programming, Alan Kay's original vision of OOP) 2 | 3 | interface CanView { // <-- This means that any class that implements this interface must have a `view` method. 4 | fun view() 5 | } 6 | 7 | final class Page( // <-- the "Page" class constructor, the "val" keyword means the variable is immutable. 8 | private val content: String // <-- content is only accessible by calling the `inspectContent` method. 9 | ): CanView { 10 | override fun view() { 11 | println("Page: ${inspectContent()}") 12 | } 13 | 14 | fun updateContent(newContent: String): Page { 15 | return Page(newContent) // <-- The "updateContent" method returns a new object with the new state. 16 | } 17 | 18 | fun inspectContent(): String { 19 | return content 20 | } 21 | } 22 | 23 | final class Book( 24 | val title: String, // <-- Its OK to access the title directly, as it's primitive, immutable and cannot be modified. 25 | private val pages: List 26 | ): CanView { 27 | override fun view() { 28 | println("Book: $title, # of Pages: ${pages.size}") 29 | pages.forEach { it.view() } // <-- The "forEach" method is a higher order function that takes a lambda function 30 | // `it` refers to the current element in the list, the `page` object. 31 | } 32 | 33 | fun updateTitle(newTitle: String): Book { 34 | return Book(newTitle, pages) // <-- The "updateName" method returns a new object with the new state. 35 | } 36 | 37 | fun updatePages(newPages: List): Book { 38 | return Book(title, newPages) // <-- The "updatePages" method returns a new object with the new state. 39 | } 40 | } 41 | 42 | final class Application( 43 | val book: Book // <-- The "Application" class, the "val" keyword means the variable is immutable. 44 | ): CanView { 45 | override fun view() { 46 | println("Application Viewing: ${book.title}") 47 | book.view() 48 | } 49 | 50 | fun updateBook(newBook: Book): Application { 51 | return Application(newBook) // <-- The "updateBook" method returns a new object with the new state. 52 | } 53 | } 54 | 55 | 56 | // Start of program 57 | fun main() { 58 | // Setup the App in the familiar Imperative Style: 59 | // Create the list of Page objects 60 | val pages = listOf( // <-- the "val" keyword means the variable is immutable and can only be assigned once. 61 | Page("Page 1 Content"), 62 | Page("Page 2 Content"), 63 | Page("Page 3 Content") 64 | ) 65 | // Create the book object using the list page objects 66 | val book = Book( 67 | "MyBook.txt", 68 | pages 69 | ) 70 | // Create the application object using the book object 71 | var app = Application(book) // <-- The "var" keyword means the variable is mutable, 72 | // `app` is a "var" because it's expected to change state. 73 | // Every other variable is a "val" and is immutable. 74 | 75 | // The above code could be arranged in the functional style, where the state of the program is created in 76 | // a single line! 77 | // 78 | // - This style is also known as "declarative" style, as opposed to the familiar "imperative" style. 79 | // - Using declaritive style, the code is about "what" needs to be done, rather than step-by-step "how" to do it. 80 | // - As a programmer, you only see the high-level view, as the implementation details are hidden deeper 81 | // in the code, "abstracted" away in the functions. 82 | // - Functions are called and executed from the innermost brackets first to the outermost assignment last. 83 | // - The state of the program is created in a single call to the `Application` constructor. 84 | 85 | // Setup the App in Functional Style: 86 | app = Application( 87 | Book( 88 | title = "MyBookTitle.txt", 89 | pages = listOf( 90 | Page("Page 1 Content"), 91 | Page("Page 2 Content"), 92 | Page("Page 3 Content") 93 | ) 94 | ) 95 | ) 96 | app.view() // <-- will print the same as the imperative style: 97 | // Application Viewing: MyBookTitle.txt 98 | // Book: MyBookTitle.txt, # of Pages: 3 99 | // Page: Page 1 Content 100 | // Page: Page 2 Content 101 | // Page: Page 3 Content 102 | 103 | // app.book = Book("UpdatedBook.txt", emptyList()) // <-- will not compile, as the variable `book` is immutable 104 | // and cannot be modified. It can only be replaced. 105 | 106 | // To change the state of the application, a whole new object must be created with the new state, 107 | // usually based on a copy the old state, with modifications to reflect the new state. 108 | val newPages = pages 109 | .filter { page -> // Instead of using imperative "for" loops, "filter" internally uses a loop to create 110 | // a new list of pages. 111 | page.inspectContent() != "Page 2 Content" // <-- removes the 2nd page from the list. 112 | } 113 | .toMutableList() // <-- converts the immutable list to a mutable list to allow for adding a new page. 114 | .apply { // <-- creates a new list of pages with the same content as the original list. 115 | add( // <-- adds a new page to the list. 116 | Page("New Page 4 Content") 117 | ) 118 | } 119 | .toList() // <-- converts the mutable list back to an immutable list. 120 | 121 | app = app.updateBook( 122 | app.book // <-- Using the `book` from the current state of the application. 123 | .updateTitle("UpdatedBookTitle.txt") // <-- Creates a new book with the updated name and the same pages. 124 | .updatePages(newPages) // <-- Creates a new book with the updated pages and the same title. 125 | ) 126 | 127 | println() // <-- prints an empty line to separate the two views. 128 | app.view() // <-- will print: 129 | // Application Viewing: UpdatedBookTitle.txt 130 | // Book: UpdatedBookTitle.txt, # of Pages: 3 131 | // Page: Page 1 Content 132 | // Page: Page 3 Content 133 | // Page: New Page 4 Content 134 | } 135 | 136 | // Output: 137 | // Application Viewing: MyBookTitle.txt 138 | // Book: MyBookTitle.txt, # of Pages: 3 139 | // Page: Page 1 Content 140 | // Page: Page 2 Content 141 | // Page: Page 3 Content 142 | // 143 | // Application Viewing: UpdatedBookTitle.txt 144 | // Book: UpdatedBookTitle.txt, # of Pages: 3 145 | // Page: Page 1 Content 146 | // Page: Page 3 Content 147 | // Page: New Page 4 Content -------------------------------------------------------------------------------- /src/main/kotlin/controlledVisibilityExample.kt: -------------------------------------------------------------------------------- 1 | // Kotlin example of controlled visibility and inheritance using COP style. 2 | // This example shows how to control the visibility of properties and methods in a class hierarchy. 3 | 4 | open class Publication( 5 | public val fileName: String, 6 | private var content: String 7 | ) { 8 | protected var numTimesViewed = 0 // This property can be accessed by any subclass of "Publication". 9 | private var numTimesUpdated = 0 // Only this "Publication" class can access this property. 10 | 11 | // ⬇︎-- This method is public, so it can be called from anywhere. 12 | fun viewContent() { 13 | incrementTimesViewed() 14 | println("Viewing file ${this.fileName}: ${this.content}, times viewed=${this.numTimesViewed}") 15 | } 16 | 17 | // ⬇︎-- This method is protected, so it can only be called from within the class or any subclass. 18 | protected fun updateContent(content: String) { 19 | this.content = content 20 | incrementTimesUpdated() 21 | println("Updated: ${this.fileName}, times updated=${this.numTimesUpdated}") 22 | } 23 | 24 | // ⬇︎-- This methods is private to the class, so it can only be called from within the class. 25 | private fun incrementTimesViewed() { 26 | numTimesViewed++ 27 | } 28 | 29 | // ⬇︎-- This method is private to the class, so it can only be called from within the class. 30 | private fun incrementTimesUpdated() { 31 | numTimesUpdated++ 32 | } 33 | } 34 | 35 | class Magazine( 36 | fileName: String, 37 | content: String 38 | ): Publication(fileName, content) { // note: The constructor values are passed to the primary constructor of the superclass. 39 | 40 | private var lastUpdatedByName: String = "" 41 | 42 | // ⬇︎-- This method is public, so it can be called from anywhere. 43 | fun update(content: String, updatedByName: String) { 44 | super.updateContent(content) 45 | 46 | // ⬇︎-- The `fileName` property is public, so it can be accessed from anywhere. 47 | println("Updating: ${this.fileName}") 48 | 49 | // ⬇︎-- The `lastUpdatedBy` property is private, so it can only be accessed from within the `Magazine` class. 50 | this.lastUpdatedByName = updatedByName 51 | 52 | // ⬇︎-- This line will not compile, as `numTimesUpdated` is private to class Publication. 53 | // super.numTimesUpdated = 0 54 | 55 | // ⬇︎-- This line will not compile, as `incrementTimesUpdated` is private to class Publication. 56 | // super.incrementTimesUpdated() 57 | 58 | // ⬇︎-- This line will not compile, as `numTimesUpdated` is private to class Publication. 59 | // println("times updated=${this.numTimesUpdated} times") 60 | 61 | // ⬇︎-- The `numTimesViewed` property is protected, so it can be accessed from any subclass. 62 | println("File: ${this.fileName} has been viewed ${this.numTimesViewed} times, last updated by: ${this.lastUpdatedByName}") 63 | } 64 | } 65 | 66 | 67 | class SomeOtherClass { // <-- IMPORTANT NOTE: This class is **NOT** a subclass of `Publication` or `Magazine`. 68 | 69 | // ⬇︎-- This method is public, so it can be called from anywhere. 70 | fun tryToDoStuffToPublication(publication: Publication) { 71 | publication.viewContent() 72 | 73 | // ⬇︎-- This line will not compile, as `content` is private to class Publication. 74 | // publication.content = "New Content" 75 | 76 | // ⬇︎-- This line will not compile, as `updateContent` is protected inside class Publication. 77 | // publication.updateContent("New Content") 78 | 79 | // ⬇︎-- This line will not compile, as `incrementTimesViewed()` is private to class Publication. 80 | // publication.incrementTimesViewed() 81 | 82 | // ⬇︎-- This line will not compile, as `numTimesUpdated` is private to class Publication. 83 | // println(publication.numTimesUpdated) 84 | 85 | // ⬇︎-- This line will not compile, as `numTimesViewed` is private to class Publication. 86 | // println(publication.numTimesViewed) 87 | 88 | // ⬇︎-- This line will compile, as `fileName` is public, and the type of `publication` is `Publication`. 89 | println("File name: ${publication.fileName}") 90 | } 91 | 92 | // ⬇︎-- This method is public, so it can be called from anywhere. 93 | fun tryToDoStuffToMagazine(magazine: Magazine) { 94 | magazine.viewContent() 95 | 96 | // ⬇︎-- This line will not compile, as `content` is private to class Publication 97 | // magazine.content = "New Content" 98 | 99 | // ⬇︎-- This line will not compile, as `updateContent` is protected inside class Publication. 100 | // magazine.updateContent("More Updated Content") 101 | 102 | // ⬇︎-- This line will not compile, as `incrementTimesViewed()` is private to class Publication 103 | // magazine.incrementTimesViewed() 104 | 105 | // ⬇︎-- Now `update` works, as the `update` method is public, and the type of `magazine` is `Magazine`. 106 | magazine.update("More Updated Content", "Jim") 107 | magazine.viewContent() 108 | } 109 | } 110 | 111 | // Start of program 112 | fun main() { 113 | 114 | val magazine = Magazine("Magazine.txt", "Initial Content") 115 | magazine.viewContent() 116 | magazine.update("New Content", "Chris") 117 | magazine.viewContent() 118 | 119 | println() // <-- Just a blank line to separate the output. 120 | val someOtherClass = SomeOtherClass() 121 | someOtherClass.tryToDoStuffToPublication(magazine) 122 | someOtherClass.tryToDoStuffToMagazine(magazine) 123 | } 124 | 125 | // Output: 126 | // Viewing file Magazine.txt: Initial Content, times viewed=1 127 | // Updated: Magazine.txt, times updated=1 128 | // Updating: Magazine.txt 129 | // File: Magazine.txt has been viewed 1 times, last updated by: Chris 130 | // Viewing file Magazine.txt: New Content, times viewed=2 131 | // 132 | // Viewing file Magazine.txt: New Content, times viewed=3 133 | // Viewing file Magazine.txt: New Content, times viewed=4 134 | // Updated: Magazine.txt, times updated=2 135 | // Updating: Magazine.txt 136 | // File: Magazine.txt has been viewed 4 times, last updated by: Jim 137 | // Viewing file Magazine.txt: More Updated Content, times viewed=5 -------------------------------------------------------------------------------- /src/main/kotlin/coroutineExample.kt: -------------------------------------------------------------------------------- 1 | import kotlinx.coroutines.* 2 | import kotlinx.coroutines.flow.MutableStateFlow 3 | import kotlinx.coroutines.flow.update 4 | import kotlin.time.Duration.Companion.milliseconds 5 | import kotlin.time.ExperimentalTime 6 | 7 | private const val NUMBER_OF_CYCLES = 100 // may need 200 to guarantee the problem will occur. 8 | 9 | fun main() { 10 | //coroutineWithUpdateProblem() 11 | 12 | fixedCoroutineUpdateProblemWithAtomicUpdates() 13 | } 14 | 15 | @OptIn(DelicateCoroutinesApi::class, ExperimentalTime::class) 16 | fun coroutineWithUpdateProblem() { 17 | var x = 0 18 | 19 | val job1 = GlobalScope.launch { 20 | for (i in 1..NUMBER_OF_CYCLES) { 21 | x=x+1 22 | println("Coroutine 1: $i, x=$x") 23 | delay(10.milliseconds) 24 | } 25 | } 26 | val job2 = GlobalScope.launch { 27 | for (i in 1..NUMBER_OF_CYCLES) { 28 | x=x+1 29 | println("Coroutine 2: $i, x=$x") 30 | delay(10.milliseconds) 31 | } 32 | } 33 | 34 | runBlocking { 35 | job1.join() 36 | job2.join() 37 | } 38 | 39 | println("Final value of x: $x, should be ${NUMBER_OF_CYCLES * 2}") 40 | } 41 | 42 | // Output: 43 | // Coroutine 2: 1, x=1 44 | // Coroutine 1: 1, x=2 45 | // Coroutine 2: 2, x=3 46 | // Coroutine 1: 2, x=4 47 | // Coroutine 2: 3, x=5 48 | // Coroutine 1: 3, x=6 49 | // Coroutine 2: 4, x=7 50 | // Coroutine 1: 4, x=8 51 | // Coroutine 2: 5, x=9 52 | // Coroutine 1: 5, x=10 53 | // Coroutine 2: 6, x=11 54 | // Coroutine 1: 6, x=12 55 | // Coroutine 1: 7, x=14 // <-- Notice the order of the output is inconsistent, as the coroutines run concurrently. 56 | // ... 57 | // Coroutine 1: 8, x=14 // <-- Notice the value of `x` is inconsistently incrementing, as the updates are NOT "atomic." 58 | // Coroutine 2: 8, x=14 59 | // Coroutine 1: 9, x=16 60 | // Coroutine 2: 9, x=17 61 | // ... 62 | // Coroutine 2: 99, x=192 63 | // Coroutine 1: 99, x=193 64 | // Coroutine 1: 100, x=194 65 | // Coroutine 2: 100, x=195 66 | // Final value of x: 195, should be 200 // <-- Notice final value of `x` is 195, not the expected 200. This is a race condition. 67 | 68 | // Fix the issue with the atomic updates by using the `StateFlow` class. 69 | @OptIn(ExperimentalTime::class, DelicateCoroutinesApi::class) 70 | fun fixedCoroutineUpdateProblemWithAtomicUpdates() { 71 | val x = MutableStateFlow(0) 72 | 73 | println("\nFixed Coroutine Update Problem using Atomic updates (StateFlow)") 74 | 75 | val job1 = GlobalScope.launch { 76 | for (i in 1..NUMBER_OF_CYCLES) { 77 | x.update { x -> 78 | x + 1 79 | } 80 | println("Coroutine 1: i=$i, x=${x.value}") 81 | delay(10.milliseconds) 82 | } 83 | } 84 | 85 | val job2 = GlobalScope.launch { 86 | for (i in 1..NUMBER_OF_CYCLES) { 87 | x.update { x -> 88 | x + 1 89 | } 90 | println("Coroutine 2: i=$i, x=${x.value}") 91 | delay(10.milliseconds) 92 | } 93 | } 94 | 95 | runBlocking { 96 | job1.join() 97 | job2.join() 98 | } 99 | 100 | println("Final value of x: ${x.value}, should be ${NUMBER_OF_CYCLES * 2}") 101 | } 102 | 103 | // Output: 104 | // Fixed Coroutine Update Problem 105 | // Coroutine 2: 1, x=2 106 | // Coroutine 1: 1, x=1 107 | // Coroutine 2: 2, x=4 108 | // Coroutine 1: 2, x=3 109 | // Coroutine 2: 3, x=5 110 | // Coroutine 1: 3, x=6 // <-- Notice that the order of the output is inconsistent, as the coroutines run concurrently. 111 | // Coroutine 1: 4, x=8 112 | // Coroutine 2: 4, x=7 // <-- Notice the value of `x` IS consistently incrementing, as the updates are `atomic`. 113 | // Coroutine 1: 5, x=9 114 | // Coroutine 2: 5, x=10 115 | // Coroutine 2: 6, x=12 116 | // ... 117 | // Final value of x: 200, should be 200 // <-- Notice the final value of `x` is correct. 118 | -------------------------------------------------------------------------------- /src/main/kotlin/coroutineVsThreadExample.kt: -------------------------------------------------------------------------------- 1 | import kotlinx.coroutines.* 2 | import java.util.concurrent.atomic.AtomicInteger 3 | import kotlin.time.Duration.Companion.milliseconds 4 | import kotlin.time.ExperimentalTime 5 | 6 | const val numParallelTasks = 100_000 7 | 8 | fun main() { 9 | runBlocking { // <-- `runBlocking` creates a coroutine context and runs the code inside it. 10 | threadVsCoroutinesPerformanceDifference() 11 | } 12 | } 13 | 14 | // Example of using coroutines and threads to compare performance for 100_000 tasks. (the _ is just for human readability, and ignored by the compiler.) 15 | @OptIn(DelicateCoroutinesApi::class, ExperimentalTime::class) 16 | suspend fun threadVsCoroutinesPerformanceDifference() { // <-- `suspend` keyword means this function can be called from a coroutine. 17 | val counter = AtomicInteger(0) 18 | 19 | println("\nThread vs Coroutines Performance Difference:") 20 | println("----------------------------------------------") 21 | 22 | // Using coroutines 23 | println("Coroutines running...") 24 | val job = GlobalScope.launch { 25 | repeat(numParallelTasks) {// <-- `repeat` runs the given task 100_000 times. 26 | launch {// <-- `launch` creates a new coroutine with the given task. 27 | // The task: 28 | counter.incrementAndGet() // <-- this is the task. 29 | delay(3.milliseconds) 30 | } 31 | } 32 | } 33 | var startTime = System.currentTimeMillis() 34 | job.join() // <-- `join` waits for the coroutine to finish. 35 | println("Coroutines result: ${counter.get()}") 36 | println("Time taken: ${System.currentTimeMillis() - startTime}ms") 37 | 38 | // Using threads 39 | println("\nThreads running...") 40 | val threadList = List(numParallelTasks) {// <-- `List` creates a list of 100_000 elements. 41 | Thread { // <-- `Thread` creates a new thread with the given task. 42 | // The task: 43 | counter.incrementAndGet() 44 | Thread.sleep(3) // 3ms 45 | } 46 | } 47 | counter.set(0) 48 | startTime = System.currentTimeMillis() 49 | threadList.forEach(Thread::start) // <-- `start` starts running the task in a new thread. 50 | threadList.forEach(Thread::join) // <-- `join` waits for the thread to finish. 51 | println("Threads result: ${counter.get()}") 52 | println("Time taken: ${System.currentTimeMillis() - startTime}ms") 53 | } 54 | 55 | // Output: 56 | // Coroutines result: 100000 57 | // Time taken: 33ms 58 | // 59 | // Threads result: 100000 60 | // Time taken: 5956ms -------------------------------------------------------------------------------- /src/main/kotlin/functionalExample.kt: -------------------------------------------------------------------------------- 1 | // Kotlin program to show how to use higher-order functions and lambdas to avoid side effects. 2 | 3 | fun main() { 4 | val addFun = { x: Int, y: Int -> x + y } // <-- a lambda that takes 2 integers and returns the sum of the integers. 5 | val multiplyFun = { x: Int, y: Int -> x * y } // <-- a lambda that takes 2 integers and returns the product of the integers. 6 | val firstThenSecond = { // <-- a lambda that takes 4 arguments, 2 functions and 2 integers, and returns the result of the 2 functions. 7 | first: (Int, Int) -> Int, // <-- a lambda that takes 2 integers and returns an integer, it's executed first. 8 | second: (Int, Int) -> Int, // <-- a lambda that takes 2 integers and returns an integer, it's executed second. 9 | a: Int, b: Int -> 10 | second(first(a, b), b) // <-- calls the `first` lambda with the 2 integers (a & b), 11 | // then calls the `second` lambda with the result of `first()` and the 2nd integer (b). 12 | } 13 | 14 | val result = firstThenSecond(addFun, multiplyFun, 10, 2) // <-- calls the lambda with the 2 functions and 2 integers. 15 | println(result) // the result will be 24. 16 | } 17 | 18 | // Output: 19 | // 24 -------------------------------------------------------------------------------- /src/main/kotlin/inheritanceExample.kt: -------------------------------------------------------------------------------- 1 | // Kotlin example of inheritance, subtyping and polymorphism (all essentially the same thing) 2 | 3 | open class Media() { // <-- the "base class" or "superclass", `open` means it can be subclasses (extended/inherited) 4 | protected var name: String = "Untitled" // <-- the `name` property is protected, so it can be accessed by subclasses, and not from outside the class. 5 | 6 | constructor(name: String) : this() { // <-- the primary constructor of the class, it takes a single parameter `name` of type `String` 7 | this.name = name 8 | } 9 | 10 | open fun play() { 11 | println("Playing Unknown Media: " + this.name) 12 | } 13 | } 14 | 15 | open class MP3( 16 | name: String 17 | ): Media(name) { // <-- the "subclass" or "derived class"; it `extends` (inherits) from the superclass (Media), 18 | // NOTICE: No constructor is defined, so the `default constructor` in the superclass will be used `Media(name)` 19 | 20 | override fun play() { 21 | println("Playing MP3: " + this.name) 22 | } 23 | } 24 | 25 | class Video( 26 | name: String 27 | ): Media(name) { // NOTICE: No constructor is defined, so the `default constructor` in the superclass will be used `Media(name)` 28 | 29 | override fun play() { 30 | println("Playing Video: " + this.name) 31 | } 32 | } 33 | 34 | class ProtectedMP3( 35 | name: String, 36 | private val password: String 37 | ): MP3(name) { // NOTICE: No constructor is defined, so the `default constructor` in the superclass will be used `Media(name)` 38 | private var isAuthenticated: Boolean = false 39 | 40 | fun authenticate(password: String) { 41 | if (this.password == password) { 42 | this.isAuthenticated = true 43 | println("Authenticated.") 44 | } 45 | } 46 | 47 | override fun play() { 48 | if (this.isAuthenticated == true) { 49 | println("Playing Protected MP3: " + this.name) 50 | } else { 51 | println("Not Authenticated! Submit password to authenticate.") 52 | } 53 | } 54 | } 55 | 56 | // Start of program 57 | fun main() { 58 | val doc0: Media = Media("MyMedia") // Since the `Media` class is `open` and not `abstract`, an object can be created from it. 59 | val doc1: Media = MP3("MyMP3") 60 | val doc2: Media = Video("MyVideo") 61 | 62 | fun playMedia(media: Media) { // Note that the parameter is of type `Media` and not `MP3` or `Video` or `ProtectedMP3` 63 | media.play() 64 | } 65 | 66 | playMedia(doc0) // <-- will print "Playing: MyMedia" 67 | playMedia(doc1) // <-- will print "Playing MP3: MyMP3.mp3" 68 | playMedia(doc2) // <-- will print "Playing Video: MyVideo.mp4" 69 | 70 | // println(doc0.name) // <-- will not compile because `name` is `protected` and cannot be accessed from outside the class. 71 | 72 | // Note: `doc3` is of type `ProtectedMP3` and not `MP3` or `Media` because we want to access the `authenticate` method, 73 | // which is not available in the `Media` class or the `MP3` class. 74 | val doc3: ProtectedMP3 = ProtectedMP3("MyProtectedMP3", "MySecretPassword123") 75 | 76 | playMedia(doc3) // <-- will print "Not Authenticated! Submit password to authenticate." 77 | doc3.authenticate("MySecretPassword123") // <-- will print "Authenticated!" 78 | playMedia(doc3) // <-- will print "Playing Protected MP3: MyProtectedMP3.mp3" 79 | 80 | 81 | // Bonus type-casting 82 | val doc4: Media = ProtectedMP3("MyOtherProtectedMP3", "password2") 83 | // doc4.authenticate("password2") // <-- will not compile, because `doc4` is of type `Media` and not `ProtectedMP3`. 84 | (doc4 as ProtectedMP3).authenticate("password2") // <-- will print "Authenticated." 85 | } 86 | 87 | // Output: 88 | // Playing Unknown Media: MyMedia 89 | // Playing MP3: MyMP3 90 | // Playing Video: MyVideo 91 | // Not Authenticated! Submit password to authenticate. 92 | // Authenticated. 93 | // Playing Protected MP3: MyProtectedMP3 94 | // Authenticated. -------------------------------------------------------------------------------- /src/main/kotlin/interfaceExample.kt: -------------------------------------------------------------------------------- 1 | interface Document { // <-- interfaces only define the "signature" of the functions it expects to be in the subclass 2 | fun view() // this interface expects a function called "view" 3 | } 4 | 5 | // PDF is one "concrete implementing" class of the "Document" interface 6 | class PDF: Document { // PDF is a subclass of Document, and required to implement the "view" function 7 | override fun view() { // <-- the implementation of the interface (uses the "override" keyword) 8 | println("Launch PDF Viewer") 9 | } 10 | } 11 | 12 | // Email is one "concrete implementing" class of the "Document" interface 13 | class Email: Document { // Email is a subclass of Document, and must implement the "view" function 14 | override fun view() { // <-- the implementation of the interface (uses the "override" keyword) 15 | println("Launch Email App") 16 | } 17 | } 18 | 19 | // Song is one "concrete implementing" class of the "Document" interface 20 | class Song: Document { // <-- the implementation of the interface (uses the "override" keyword) 21 | override fun view() { 22 | println("Launch Music Player") 23 | } 24 | } 25 | 26 | // Start of program 27 | fun main() { 28 | val doc1: Document = PDF(); 29 | val doc2: Email= Email() 30 | val doc3: Song = Song() 31 | 32 | fun viewDocument(doc: Document) { // Note that the parameter is of type `Document` and not `PDF` or `Email` or `Song` 33 | doc.view() // Will call the appropriate "view" function of the subclass 34 | } 35 | 36 | viewDocument(doc1) // <-- will print "Launch PDF Viewer" 37 | viewDocument(doc2) // <-- will print "Launch Email App" 38 | viewDocument(doc3) // <-- will print "Launch Music Player" 39 | } 40 | 41 | // Output: 42 | // Launch PDF Viewer 43 | // Launch Email App 44 | // Launch Music Player -------------------------------------------------------------------------------- /src/main/kotlin/liskovSubstitutionPrincipleExample.kt: -------------------------------------------------------------------------------- 1 | // Liskov Substitution Principle Example 2 | 3 | interface Shape { 4 | val name: String 5 | fun area(): Float 6 | } 7 | 8 | open class Rectangle( 9 | val width: Float, 10 | val height: Float 11 | ): Shape { 12 | override val name = "Rectangle" 13 | override fun area() = width * height 14 | } 15 | 16 | class Circle(val radius: Float): Shape { 17 | override val name = "Circle" 18 | override fun area(): Float = (3.14 * radius * radius).toFloat() 19 | } 20 | 21 | class Square(val side: Float): Rectangle(side, side) { // <-- Square is a subclass of `Rectangle`, still a `Shape`. 22 | override val name = "Square" 23 | } 24 | 25 | // Start of the program 26 | fun main() { 27 | val rectangle = Rectangle(10f, 20f) 28 | val square = Square(10.0f) 29 | val circle = Circle(10.0f) 30 | // val someShape = Shape() // <-- This will not compile because Shape is an interface and cannot be instantiated. 31 | 32 | // Can call `area()` method on any subclass of `Shape`: 33 | println("Rectangle area: ${rectangle.area()}") 34 | println("Square area: ${square.area()}") 35 | println("Circle area: ${circle.area()}") 36 | 37 | // Can create a `Shape`-s list that accepts any subclass of Shape: 38 | val shapes: List = listOf(rectangle, square, circle) // <-- Allocates a list of Shapes and adds the shapes to it. 39 | shapes.forEach { shape -> 40 | println("Area for shape ${shape.name}: ${shape.area()}") 41 | } 42 | 43 | // Can't have a Circle in a list that only accepts Rectangles: 44 | // val rectangles: List = listOf(rectangle, circle) // <-- This will NOT compile. 45 | 46 | // Can't add a Rectangle to a list of Circles: 47 | val circle2 = Circle(20.0f) 48 | val circles: MutableList = mutableListOf(circle, circle2) // <-- This will compile. 49 | // circles.add(Rectangle(10f, 20f)) // <-- This will NOT compile. 50 | } 51 | 52 | 53 | // Output: 54 | // Rectangle area: 200.0 55 | // Square area: 100.0 56 | // Circle area: 314.0 57 | // Area for shape Rectangle: 200.0 58 | // Area for shape Square: 100.0 59 | // Area for shape Circle: 314.0 60 | -------------------------------------------------------------------------------- /src/main/kotlin/multipleInheritanceExample.kt: -------------------------------------------------------------------------------- 1 | package org.example 2 | 3 | // Multiple inheritance Example 4 | // Kotlin allows interfaces to have default implementations for functions. 5 | 6 | interface Add1 { 7 | abstract val a: Int 8 | abstract val b: Int 9 | 10 | fun add(): Int { 11 | return a + b // <-- different default implementations 12 | } 13 | 14 | fun subtract(): Int { 15 | return a - b 16 | } 17 | } 18 | 19 | interface Add2 { 20 | abstract val a: Int 21 | abstract val b: Int 22 | 23 | fun add(): Int { 24 | return a + a + b + b // <-- different default implementations 25 | } 26 | 27 | fun subtract(): Int { 28 | return a - b - b 29 | } 30 | } 31 | 32 | interface Add3 { 33 | abstract val a: Int 34 | abstract val b: Int 35 | 36 | fun add(): Int { 37 | return a + a + a + b + b + b // <-- different default implementations 38 | } 39 | 40 | fun subtract(): Int { 41 | return a - b - b - b 42 | } 43 | } 44 | 45 | class Calculator1( 46 | override val a: Int = 0, // <-- must override the properties for the interface to define the default values 47 | override val b: Int = 0 // <-- must override the properties for the interface to define the default values 48 | ) : Add1, Add2, Add3 { // <-- Inherit("Subclass"/"Subtype"/"Derive") from three interfaces (multiple inheritance) 49 | 50 | // Must override `add` when there are 2 conflicting definitions in the interfaces 51 | override fun add(): Int { 52 | return super.add() // <-- call the desired implementation in Add1 53 | } 54 | 55 | // Must override `subtract` when there are 2 conflicting definitions in the interfaces 56 | override fun subtract(): Int { 57 | return super.subtract() // <-- call the desired implementation in Add3 58 | } 59 | } 60 | 61 | class Calculator2( 62 | override val a: Int = 0, 63 | override val b: Int = 0 64 | ) : Add1, Add2, Add3 { 65 | 66 | override fun add(): Int { 67 | return super.add() // <-- calls different implementation than the Calculator1 class 68 | } 69 | 70 | override fun subtract(): Int { 71 | return super.subtract() // <-- calls different implementation than the Calculator1 class 72 | } 73 | } 74 | 75 | fun main() { 76 | val calc1 = Calculator1(1, 2) 77 | println("sum=${calc1.add()}") // <-- Output: sum=3 78 | 79 | val calc2 = Calculator2(1, 2) 80 | println("sum=${calc2.add()}") // <-- Output: sum=6 81 | } 82 | -------------------------------------------------------------------------------- /src/main/kotlin/sideEffectsExample.kt: -------------------------------------------------------------------------------- 1 | // Kotlin program to pedantically demonstrate the concept of "side effects." 2 | 3 | fun main() { 4 | var x = 0 // <-- Defines a variable that will be "affected" or "mutated" by the lambda. 5 | val add = { a: Int, b: Int -> // <-- Defines a lambda that takes two Ints and returns an Int. 6 | val result = a + b + x 7 | x += a // <-- Create a "side effect" by changing the value of `x` outside the lambda. 8 | 9 | result // <-- Return the result of the addition. 10 | } 11 | 12 | print(add(1, 2)) // <-- Print expected value the first time called (3). 13 | 14 | println(add(1, 2)) // <-- Print the unexpected value the second time called (4) due to the side effect. 15 | } 16 | 17 | // Output: 18 | // 3 // <-- This value of is what we expected, only the first time though... 19 | // 4 // <-- This value of is **NOT** what we expected due to the "side effect." 20 | -------------------------------------------------------------------------------- /src/main/kotlin/structuredExample.kt: -------------------------------------------------------------------------------- 1 | 2 | 3 | fun main() { // <-- start of the program, int means the function returns an integer 4 | var y: Int = 100 5 | var x: Int = 10 6 | 7 | run { // <-- start of a scope or "code block" or just "block" 8 | var y: Int = 32 // Inside the brackets "Inner" or "Local" to the scope. 9 | var z: Int = 54 // <-- Only visible to the scope it's defined in, ie: this one. 10 | 11 | x = x + y 12 | } // <-- end of the "scope" 13 | 14 | println(x) // <-- print the value of x as a decimal number 15 | println(x.toChar()) // <-- print the value of x as a character (the ASCII value of x) 16 | // println(z) // <-- this will cause a compile error, because `z` is not defined in this scope 17 | } 18 | 19 | // Output: 20 | // 42 21 | // * -------------------------------------------------------------------------------- /src/main/kotlin/threadExample.kt: -------------------------------------------------------------------------------- 1 | private const val NUMBER_OF_CYCLES = 100 2 | 3 | fun main() { 4 | threadsWithUpdateProblem() 5 | 6 | fixedThreadUpdateProblemWithAtomicUpdates() 7 | } 8 | 9 | fun threadsWithUpdateProblem() { 10 | var x = 0 11 | 12 | val thread1 = Thread { 13 | for (i in 1..NUMBER_OF_CYCLES) { 14 | x++ 15 | println("Thread 1: i=$i, x=$x") 16 | Thread.sleep(10) // milliseconds 17 | } 18 | } 19 | val thread2 = Thread { 20 | for (i in 1..NUMBER_OF_CYCLES) { 21 | x++ 22 | println("Thread 2: i=$i, x=$x") 23 | Thread.sleep(10) // milliseconds 24 | } 25 | } 26 | 27 | thread1.start() 28 | thread2.start() 29 | thread1.join() 30 | thread2.join() 31 | 32 | println("Final value of x: $x, should be ${NUMBER_OF_CYCLES * 2}") 33 | } 34 | 35 | // Output: 36 | // Thread 2: 1, x=0 37 | // Thread 1: 1, x=0 38 | // Thread 2: 2, x=2 39 | // Thread 1: 2, x=2 40 | // Thread 2: 3, x=4 41 | // Thread 1: 3, x=5 42 | // Thread 2: 4, x=6 43 | // Thread 1: 4, x=7 // <-- Notice that the order of the output is not consistent, as the threads are running concurrently. 44 | // Thread 1: 5, x=8 45 | // Thread 2: 5, x=8 46 | // Thread 1: 6, x=10 47 | // Thread 2: 6, x=10 // <-- Notice the value of `x` is not consistently incrementing, as the updates are not `atomic`. 48 | // Thread 1: 7, x=12 49 | // Thread 2: 7, x=13 50 | // ... 51 | // Thread 1: i=98, x=186 52 | // Thread 2: i=99, x=187 53 | // Thread 2: i=100, x=188 54 | // Thread 1: i=99, x=189 55 | // Thread 1: i=100, x=190 56 | // Final value of x: 190, should be 200 // <-- Notice the final value of `x` is not 200, as expected. 57 | 58 | fun fixedThreadUpdateProblemWithAtomicUpdates() { 59 | var x = 0 60 | val lock = Any() // Doesn't matter what the type is. It's just used as a lock or "flag" to synchronize the threads. 61 | 62 | println("\nFixed Thread Update Problem (race condition) using Atomic updates (synchronized)") 63 | 64 | val thread1 = Thread { 65 | for (i in 1..NUMBER_OF_CYCLES) { 66 | synchronized(lock) { // <-- `synchronized` tells the execution to wait here until the lock is released. 67 | // the update is locked here, so the other thread can't update `x` until the current thread is done. 68 | x=x+1 69 | println("Thread 1: i=$i, x=$x") 70 | } // <-- The lock is released here at the end of the synchronized block. 71 | Thread.sleep(10) // milliseconds 72 | } 73 | } 74 | val thread2 = Thread { 75 | for (i in 1..NUMBER_OF_CYCLES) { 76 | synchronized(lock) { 77 | x=x+1 78 | println("Thread 2: i=$i, x=$x") 79 | } 80 | Thread.sleep(10) // milliseconds 81 | } 82 | } 83 | 84 | thread1.start() 85 | thread2.start() 86 | thread1.join() 87 | thread2.join() 88 | 89 | println("Final value of x: $x, should be ${NUMBER_OF_CYCLES * 2}") 90 | } 91 | 92 | // Output: 93 | // Fixed Thread Update Problem (Atomic updates) 94 | // Thread 1: i=1, x=1 95 | // Thread 2: i=1, x=2 96 | // Thread 1: i=2, x=3 97 | // Thread 2: i=2, x=4 98 | // Thread 2: i=3, x=5 // <-- Notice that the order of the output is inconsistent, as the threads are running concurrently. 99 | // Thread 1: i=3, x=6 100 | // Thread 1: i=4, x=7 101 | // Thread 2: i=4, x=8 102 | // Thread 2: i=5, x=9 103 | // ... 104 | // Thread 2: i=98, x=195 105 | // Thread 1: i=98, x=196 106 | // Thread 2: i=99, x=197 107 | // Thread 1: i=99, x=198 108 | // Thread 2: i=100, x=199 // <-- Notice the value of `x` IS consistently incrementing, as the updates are `atomic`. 109 | // Thread 1: i=100, x=200 110 | // Final value of x: 200, should be 200 -------------------------------------------------------------------------------- /src/main/kotlin/timeComplexityExample.kt: -------------------------------------------------------------------------------- 1 | // Program to demonstrate the time complexity of various algorithms. 2 | 3 | // Algorithm: Binary Search 4 | // Performs a binary search on a sorted array - O(log n) 5 | // Returns the index of the value in the array, or -1 if the value is not found. 6 | fun Array.binarySearch(searchValue: Int): Int { 7 | var low = 0 8 | var high = size - 1 9 | while (low <= high) { 10 | val mid = (low + high) / 2 11 | val midVal = this[mid] 12 | when { 13 | midVal < searchValue -> low = mid + 1 14 | midVal > searchValue -> high = mid - 1 15 | else -> return mid 16 | } 17 | } 18 | 19 | return -1 // -1 = value not found 20 | } 21 | 22 | // Algorithm: Quick Sort 23 | // Perform recursive quicksort - O(n log n) 24 | // Returns a new sorted array. 25 | fun Array.quickSort(): Array { 26 | if (size < 2) return this 27 | val pivot = this[randomInt(size - 1)] 28 | 29 | val less = filter { it < pivot }.toTypedArray().quickSort() // recursive call 30 | val equal = filter { it == pivot }.toTypedArray() 31 | val greater = filter { it > pivot }.toTypedArray().quickSort() // recursive call 32 | 33 | return less + equal + greater 34 | } 35 | 36 | fun randomInt(max: Int) = (0..max).random() 37 | 38 | // Start of Program 39 | fun main() { 40 | val x = Array(2_000) { randomInt(100) } // <-- O(n) - Fill Array `x` with 2000 random integers 41 | var result: Long = 0 42 | 43 | var start = System.currentTimeMillis() 44 | result = x[500].toLong() // <-- O(1) 45 | println("Constant Time Lookup O(1) = Result: $result, Time: ${System.currentTimeMillis() - start}ms") 46 | 47 | 48 | start = System.currentTimeMillis() 49 | result = 0 50 | for (i in 0 until x.size) { // <-- O(n) 51 | result = x[i] + result 52 | } 53 | println("Linear Time Lookup O(n) = Result: $result, Time: ${System.currentTimeMillis() - start}ms") 54 | 55 | 56 | start = System.currentTimeMillis() 57 | result = 0 58 | for (i in 0 until x.size) { // <-- O(n^2) 59 | for (j in 0 until x.size) { // <-- O(n) 60 | result = x[i] + x[j] + result 61 | } 62 | } 63 | println("Quadratic Time Lookup O(n^2) = Result: $result, Time: ${System.currentTimeMillis() - start}ms") 64 | 65 | 66 | // Notice how this one takes MUCH, MUCH longer than the previous ones. 67 | start = System.currentTimeMillis() 68 | result = 0 69 | for (i in 0 until x.size) { // <-- O(n^3) 70 | for (j in 0 until x.size) { // <-- O(n^2) 71 | for (k in 0 until x.size) { // <-- O(n) 72 | result = x[i] + x[j] + x[k] + result 73 | } 74 | } 75 | } 76 | println("Cubic Time Lookup O(n^3) = Result: $result, Time: ${System.currentTimeMillis() - start}ms") 77 | 78 | 79 | start = System.currentTimeMillis() 80 | val sorted = x.quickSort() // <-- O(n log n) 81 | println("Logarithmic Time Lookup O(n log n) = Result (size): ${sorted.size}, Time: ${System.currentTimeMillis() - start}ms") 82 | 83 | 84 | start = System.currentTimeMillis() 85 | val y = sorted.binarySearch(50) // <-- O(log n) 86 | println("Linearithmic Time Lookup O(log n) = Result: $y, Time: ${System.currentTimeMillis() - start}ms") 87 | } 88 | -------------------------------------------------------------------------------- /src/main/kotlin/typesExample.kt: -------------------------------------------------------------------------------- 1 | data class Point( // <-- `Point` is a programmer-defined type that is made up of other types 2 | val x: Int, // <-- `Int` is a type that represents a whole number (32 bits) 3 | val y: Int, // <-- `Int` is a type that represents a whole number (32 bits) 4 | val colorIdChar: Char // <-- `char` is a type that represents a single ASCII character (1 byte) 5 | ) 6 | 7 | fun main() { 8 | val x: Int = 5 9 | val y: Float = 6.128f 10 | val z: Char = 'A' 11 | val p: Point = Point(10, 42, 'G') 12 | 13 | println("Output: $x $y $z ${p.x} ${p.y} ${p.colorIdChar}") 14 | } 15 | 16 | // Output: 5 6.128 A 10 42 G -------------------------------------------------------------------------------- /src/main/kotlin/usingClassesAsNameSpaces.kt: -------------------------------------------------------------------------------- 1 | // Kotlin Example of Using a Class as a "Name-Space" to Group Together Methods 2 | // - Using COP style mashed together with Procedural style. 3 | 4 | // The `Person` class is used as a "structure" to group together data that is related to a person. 5 | // It's COP because it has a method that operates on its own object's data. 6 | data class Person( 7 | var name: String = "John Doe", 8 | var age: Int = 0, // never store age like this, always calculate it from the birthdate. 9 | var height: Double = 0.0, 10 | var weight: Double = 0.0 11 | ) { 12 | // This is a method that is part of the `Person` class. This makes it a COP `class` and not a `struct`. 13 | fun printPerson() { 14 | println("Name: ${this.name}, Age: ${this.age}, Height: ${this.height}, Weight: ${this.weight}") 15 | } 16 | } 17 | 18 | // Here's just a bunch of functions that operate on the `Person` class / "structure", like in procedural and structured programming. 19 | fun printPerson(person: Person) { 20 | println("Name: ${person.name}, Age: ${person.age}, Height: ${person.height}, Weight: ${person.weight}") 21 | } 22 | fun changeName(person: Person, newName: String) { 23 | person.name = newName 24 | } 25 | fun changeAge(person: Person, newAge: Int) { 26 | person.age = newAge 27 | } 28 | fun changeHeight(person: Person, newHeight: Double) { 29 | person.height = newHeight 30 | } 31 | fun changeWeight(person: Person, newWeight: Double) { 32 | person.weight = newWeight 33 | } 34 | 35 | // This class is used as a "name-space" to group together methods that operate on the `Person` class. 36 | class PersonManager { 37 | companion object { // <-- creates a `static` set of functions that can be accessed without an instance of the `PersonManager` class. 38 | fun changeName(person: Person, newName: String) { 39 | person.name = newName 40 | } 41 | fun changeAge(person: Person, newAge: Int) { 42 | person.age = newAge 43 | } 44 | fun changeHeight(person: Person, newHeight: Double) { 45 | person.height = newHeight 46 | } 47 | fun changeWeight(person: Person, newWeight: Double) { 48 | person.weight = newWeight 49 | } 50 | } 51 | } 52 | 53 | // This class is used as a "name-space" to group together methods that operate on the `Person` class. 54 | class PersonManager2 { 55 | fun changeName(person: Person, newName: String) { 56 | person.name = newName 57 | } 58 | fun changeAge(person: Person, newAge: Int) { 59 | person.age = newAge 60 | } 61 | fun changeHeight(person: Person, newHeight: Double) { 62 | person.height = newHeight 63 | } 64 | fun changeWeight(person: Person, newWeight: Double) { 65 | person.weight = newWeight 66 | } 67 | fun printPerson(person: Person) { 68 | println("Name: ${person.name}, Age: ${person.age}, Height: ${person.height}, Weight: ${person.weight}") 69 | } 70 | } 71 | 72 | // Start of Program 73 | fun main() { 74 | val person = Person("John Doe", 30, 6.0, 200.0) 75 | 76 | // Directly accessing the data, like in procedural & structured programming. 77 | person.name = "Jane Doe" 78 | person.age = 25 79 | person.height = 5.5 80 | person.weight = 150.0 81 | person.printPerson() // <-- "touch" of COP because a method is being called on the `person` object, not "just" a function. 82 | 83 | // Using functions like in the procedural and structured programming. 84 | changeName(person, "Jane Doe") 85 | changeAge(person, 25) 86 | changeHeight(person, 5.5) 87 | changeWeight(person, 150.0) 88 | printPerson(person) 89 | 90 | // Using the `static` methods of the `PersonManager` class to manipulate the data of the `Person` object. 91 | PersonManager.changeName(person, "Jane Doe") 92 | PersonManager.changeAge(person, 25) 93 | PersonManager.changeHeight(person, 5.5) 94 | PersonManager.changeWeight(person, 150.0) 95 | person.printPerson() 96 | 97 | // Another common mistake, that is equivalent to above. 98 | val pm = PersonManager2() // <-- Creating an object just to call a method is a waste of memory. Why not just call a function? 99 | pm.changeName(person, "Jane Doe") 100 | pm.changeAge(person, 25) 101 | pm.changeHeight(person, 5.5) 102 | pm.changeWeight(person, 150.0) 103 | pm.printPerson(person) 104 | } 105 | 106 | // Output: 107 | // Name: Jane Doe, Age: 25, Height: 5.5, Weight: 150.0 108 | // Name: Jane Doe, Age: 25, Height: 5.5, Weight: 150.0 109 | // Name: Jane Doe, Age: 25, Height: 5.5, Weight: 150.0 110 | // Name: Jane Doe, Age: 25, Height: 5.5, Weight: 150.0 --------------------------------------------------------------------------------