Justified Programming — Reason Parameters That Answer “Why”



Programmers usually bark commands at computers. Never does the computer ask “why”, and never does the programmer explain themselves. What if we did? Annotate the purpose of your function calls. It may save your day!

This is one of my few lessons that is not tied to any particular programming language. I do use C and C++ in these examples, but it would work just as well in nearly any other programming language.

Twitter:
Liberapay: (alternatives at
Twitch:
Homepage:

You can contribute subtitles/captions at: Or to any video on my channel at:

Music:
– Tales of Phantasia :: Retaliation :: Motoi Sakuraba (converted into MIDI and played through OPL3 emulation through homebrew software)
– Famicom Tantei Club Part II: Ushiro ni Tatsu Shōjo :: Dean’s Room :: Kenji Yamamoto (SPC-OPL3 conversion)¹
– Onita Atsushi FMW :: Staff Roll (SPC-OPL3 conversion)

¹) This is probably an adaptation from a concert/fugue/toccata/something by Bach. If you are someone who knows classical music and you recognize this song, please clarify this in the comments! You can listen to the full song at:
The first song can be listened here:

ERRATA
There is a typo in the strchr code shown at 1:20, my bad! The (~0ul – 1) should be just ~0ul. Coincidentally it does not cause the function to return incorrect values, it just tanks the performance. Without the bug, the dummied out code is 50% faster than the short code, but with the bug, it is 50% slower instead. Note that the SIMD-optimized assembler-coded strchr in glibc for x86_64 is still almost four times faster than the corrected code.
But there is also an actual bug in the strchr code on screen, that causes it to return incorrect values. Can you spot it?

#Bisqwit #Programming #ProgrammingPhilosophy #SelfDocumentingCode

Nguồn: https://hopdongtuonglai.com

Xem thêm bài viết khác: https://hopdongtuonglai.com/tong-hop

  • This should be taught at Programming 101.

    Prot Eus June 19, 2020 2:01 pm Reply
  • pair<bool, std::string>? What?! Also, you're aware std::string is an owned type and you just copy it over the whole prot array, right?
    Just use a std::string* pointer type (or std::shared_ptr<std::string>), and set those values to its address. (If scope becomes an issue, push it to a reference-counted reason set, and point at the item there instead!)
    And, instead of the redundant bool value, just initialize it to NULL  🙂

    Either way, I do like the concept! I do not like that it mostly depends on runtime execution aspects, like the stack and function arguments. I would prefer if it were more transparent, so that while it does not affect execution, things like debuggers could easily fetch attached justifications to function calls or expression fragments (akin to how Python attaches docstrings to callables!).

    Gustavo6046 June 19, 2020 2:01 pm Reply
  • Reason parameters are amazing, instead of having the why in design only, we have the why inside the code itself!!!

    Guilherme Alves Lopes June 19, 2020 2:01 pm Reply
  • I really thought this was a joke at first.

    Dudu PT June 19, 2020 2:01 pm Reply
  • that strchr function looks like one that would benefit from micro optimization, since its the type of function that would be called a lot from many different places

    1wsx10 June 19, 2020 2:01 pm Reply
  • Would it be possible to isolate these reason parameters to debug builds with some template/preprocessor/build system magic? More importantly, could it be done practically?

    frog June 19, 2020 2:01 pm Reply
  • Your videos make me happy.

    Akami Channel June 19, 2020 2:01 pm Reply
  • Anyone else expecting to see an esoteric programming language?

    Connor Keenum June 19, 2020 2:01 pm Reply
  • "We spend effort in naming functions, variables, methods and function parameters meaningfully […] just so we can understand later."

    You don't know how much you are way too much optimist.

    Rand0081 June 19, 2020 2:01 pm Reply
  • i realize that autogen english subtile with NO mistake!

    Tan HD June 19, 2020 2:01 pm Reply
  • How to convert source code ?

    Nitesh Malani June 19, 2020 2:01 pm Reply
  • I have .Ex4 file can you teach me how to remove protection on it. Is it possible ?

    Nitesh Malani June 19, 2020 2:01 pm Reply
  • We think along similar lines, but you address a part of an equation I thought would never be possible… The "Why"  In robotics, we'll never have anything less than a chat bot, unless we teach the machine to respond based on it's purpose and proximity to others around itself, and attempt to solve the who, what, when, and where of the person it has come into contact with.   Using this algorithm, I hypothetically take it a step further.   A virus… The mind is to the human what a virus is to a machine; Who says a virus has to be bad, it's only the purpose for which you use a virus that determines moral intent.   I propose the following, if it is at all possible…

    Game Concept to solve the problem of semi-spontaneous Artificial Intelligence within NPC's in a video game, to relieve the pressure of the master program having to do all the work itself.   Artificial Intelligence, in my opinion should be external to the master program, rather than the program controlling dozens of AI's at any given time.

    Introduction to a limited virus that is quarantined within the confines of the gaming environment, it's only purpose is towards self-awareness, survival, and being aware of it's surroundings.

    Example
    Player Harold leases some space aboard a Space Station, and decides to turn that space into a Fast Food burger joint.   He furnishes the restaurant, buys a cash register, and a computer for Human Resources related tasks, the only thing missing is the employees.

    He accesses his computer and goes to the Job Board, clicks on the food industry, and looks at all the possible NPC candidates and the skills they will bring to the job.   These NPC's are not yet in the game, but once Harold clicks "hire", the game creates these NPC's and a virus is attached, giving it "life".   Each spawned NPC has a "checklist" assigned to it, sort of like a pre-flight checklist in the aviation field.   But this "checklist" is for AI's.

    It starts asking questions…
    How is my health…  Am I hungry, thirsty…  What do I want to do… My checklist says I have a job lined up, so I better be on my way, as I do not want to be late on my first day on the job.   Per our agreed upon contract, I will be working such and such hours, but after that I am free to do as I please…  but while I'm working, my mind must stay focused on the job.

    With every AI in the game, asking and answering the questions on their personalized check list, we create a game in which the AI's feel spontaneously real.   Some jobs AI's take, after the required positions have been filled, may act as stepping stones to bigger and better paying job opportunities, after they've met the prerequisites having worked a lower end job, meaning, some of them have aspirations to rise above their current jobs, to pursue other opportunities, but recognize in order to meet a long term objective, shorter term goals must first be met.

    My question to you, Mr. Bisqwit, is such a virus possible, and how small can a virus be, if it's only task is to access data from some form of checklist, whatever efficient manner we can come up with to achieve this, as well to figure out path finding in order to reach those locations.

    There's also the concept of "virtual variables", which are variables in game, that are only visible in scope to AI's based on their training.   For instance if an AI is trained in engineering, will not have access or even be aware of medical related events on screen, thus, AI's only have access locally to those events they are qualified for, and that goes for the player as well.

    Harold McBroom June 19, 2020 2:01 pm Reply
  • Sad, because i could give only one like :(. Thank you so much for this tip

    Bruno Ferreira de Sousa June 19, 2020 2:01 pm Reply
  • Why not use lock guards? Or a variable wrapper with a lock and lock guards? I just recently wrote one myself, tested it against many threads as win10 will let me generate.

    // Thread safe primitive/object wrapper
    template <typename t>
    class tsafe {
    public:
    template <typename z>
    tsafe(z val){
    var = val;
    }

    t get() {
    std::lock_guard<std::mutex> destrMutex(mut);
    return var;
    }

    bool set(t& val) {
    std::lock_guard<std::mutex> destrMutex(mut);
    return var = val;
    }

    void directAccess(std::function<void (t&)> func) {
    std::lock_guard<std::mutex> destrMutex(mut);
    func(var);
    }

    // BASIC OPERATOR OVERLOADS
    // Asingment
    bool operator =(tsafe<t> val) {
    std::lock_guard<std::mutex> destrMutex(mut);
    var = val.get();
    return true;
    }

    template <typename z>
    bool operator =(z val) {
    std::lock_guard<std::mutex> destrMutex(mut);
    return var = val;
    }

    // Addition
    t operator +(tsafe<t> val) {
    std::lock_guard<std::mutex> destrMutex(mut);
    var += val.get();
    return var;
    }

    template <typename z>
    t operator +(z val) {
    std::lock_guard<std::mutex> destrMutex(mut);
    var += val;
    return var;
    }

    void operator +=(tsafe<t> val) {
    std::lock_guard<std::mutex> destrMutex(mut);
    var += val.get();
    }

    template <typename z>
    void operator +=(z val) {
    std::lock_guard<std::mutex> destrMutex(mut);
    var += val;
    }

    // Subtraction
    t operator -(tsafe<t>& val) {
    std::lock_guard<std::mutex> destrMutex(mut);
    var -= val.get();
    return var;
    }

    template <typename z>
    t operator -(z& val) {
    std::lock_guard<std::mutex> destrMutex(mut);
    var -= val;
    return var;
    }

    void operator -=(tsafe<t> val) {
    std::lock_guard<std::mutex> destrMutex(mut);
    var -= val.get();
    }

    template <typename z>
    void operator -=(z val) {
    std::lock_guard<std::mutex> destrMutex(mut);
    var -= val;
    }

    // Division
    t operator /(tsafe<t>& val) {
    std::lock_guard<std::mutex> destrMutex(mut);
    var /= val.get();
    return var;
    }

    template <typename z>
    t operator /(z& val) {
    std::lock_guard<std::mutex> destrMutex(mut);
    var /= val;
    return var;
    }

    void operator /=(tsafe<t> val) {
    std::lock_guard<std::mutex> destrMutex(mut);
    var /= val.get();
    }

    template <typename z>
    void operator /=(z val) {
    std::lock_guard<std::mutex> destrMutex(mut);
    var /= val;
    }

    // Multiplication
    t operator *(tsafe<t>& val) {
    std::lock_guard<std::mutex> destrMutex(mut);
    var *= val.get();
    return var;
    }

    template <typename z>
    t operator *(z& val) {
    std::lock_guard<std::mutex> destrMutex(mut);
    var *= val;
    return var;
    }

    void operator *=(tsafe<t> val) {
    std::lock_guard<std::mutex> destrMutex(mut);
    var *= val.get();
    }

    template <typename z>
    void operator *=(z val) {
    std::lock_guard<std::mutex> destrMutex(mut);
    var *= val;
    }

    // COMPARISON OPPERATORS
    bool operator <(tsafe<t>& val) {
    std::lock_guard<std::mutex> destrMutex(mut);
    return var < val.get();
    }

    template <typename z>
    bool operator <(z& val) {
    std::lock_guard<std::mutex> destrMutex(mut);
    return var < val;
    }

    bool operator <=(tsafe<t>& val) {
    std::lock_guard<std::mutex> destrMutex(mut);
    return var <= val.get();
    }

    template <typename z>
    bool operator <=(z& val) {
    std::lock_guard<std::mutex> destrMutex(mut);
    return var <= val;
    }

    bool operator >(tsafe<t>& val) {
    std::lock_guard<std::mutex> destrMutex(mut);
    return var > val.get();
    }

    template <typename z>
    bool operator >(z& val) {
    std::lock_guard<std::mutex> destrMutex(mut);
    return var > val;
    }

    bool operator >=(tsafe<t>& val) {
    std::lock_guard<std::mutex> destrMutex(mut);
    return var >= val.get();
    }

    template <typename z>
    bool operator >=(z& val) {
    std::lock_guard<std::mutex> destrMutex(mut);
    return var >= val;
    }

    bool operator ==(tsafe<t>& val) {
    std::lock_guard<std::mutex> destrMutex(mut);
    return var == val.get();
    }

    template <typename z>
    bool operator ==(z& val) {
    std::lock_guard<std::mutex> destrMutex(mut);
    return var == val;
    }

    bool operator !=(tsafe<t>& val) {
    std::lock_guard<std::mutex> destrMutex(mut);
    return var != val.get();
    }

    template <typename z>
    bool operator !=(z& val) {
    std::lock_guard<std::mutex> destrMutex(mut);
    return var != val;
    }
    private:
    t var;
    std::mutex mut;
    };

    Alex Desilets June 19, 2020 2:01 pm Reply
  • Awesome video, excellent explanation.

    R3ap3rPy June 19, 2020 2:01 pm Reply
  • First of all, thanks for all the effort you put into your videos — they're great and enjoyable to watch :-).

    Have you considered poking a bit into type theory and constructive mathematics? It turns out that there is an isomorphism between writing programs and proving propositions in logic (called the Curry-Howard isomorphism). In essence, it tells us that we can write our propositions as types in a programming language, and any program that inhabits that type is a proof of that proposition. Programming languages such as OCaml make use of this idea to implement something akin to propositional logic, but it is taken to a more of an extreme in proof assistants like Agda and Coq. A middle ground would probably be Haskell, which has a couple of more practical features of such type theories, but doesn't push it to an extreme and aims to be a programming language first. In essence, what this lets us do is express some of the invariants that we want our code to obey and we can check that it's the case statically (modulo implementation bugs, of course!).

    I'd be quite interested in seeing video from you trying to convey these terms in a simpler way and demonstrating some of the more fun aspects of it 🙂 (I am more than happy to answer any queries you might have, by the way). Thanks again for all your effort!

    Green? June 19, 2020 2:01 pm Reply
  • This was very educational. I enjoyed the fun examples and exercises you used. I hope you make more of these videos.

    LucasJG1994 June 19, 2020 2:01 pm Reply
  • Took me far too long to realize why lock was being called twice.

    Daniel Astbury June 19, 2020 2:01 pm Reply
  • Clap Clap Clap. This is really impressive. I do want to know why you work as a bus driver while you seem to have more programming knowledge than most programmer i know and maybe the story about your family.

    Jules A June 19, 2020 2:01 pm Reply
  • yes do this so i can easily debug your work without symbols :0~

    Kopuz June 19, 2020 2:01 pm Reply
  • I could not agree with this video more.

    Harley Speedthrust June 19, 2020 2:01 pm Reply
  • Bisqwit did you ever try object pascal, if yes what do you think about Modern Object Pascal compared to C++?

    IceLand June 19, 2020 2:01 pm Reply

Leave a Reply

Your email address will not be published. Required fields are marked *