Moonside

Moonside OP wrote

Go lacks facilities for generic programming so you can't write in a sensible manner a function that operates on many different datatypes. This means you either need to write almost identical routines over and over or lose useful safety guarantees.

For example, consider a list containing strings ["lol", "lmao", "nada"] (a value of type List String) and a list containing integers [1, 2, 3] (a value of type List Integer). You wish to write two functions:

  1. length which returns the number of elements list contains.
  2. head which returns the first element of a list.

If your language supports generic programming, you can just write functions length and head that work on lists containing any type of values. But since Go doesn't, if you want to have certain safety guarantees, you need to write a version of these functions for each type. In this case, you need to implement lengthString, lengthInteger, headString and headInteger. The comment author does this kind of a process by hand from a single "master" source code file to keep himself sane, but the way he uses those Canadian Aborigine Syllabics makes it look as if Go supported generic programming.

The loss of safety guarantees (if you don't wish to implement essentially same routines n times) comes from that you can mix elements of different types together in code which fails at run time and comes crashing down. In generic programming, you can guarantee that routine outputs a value of type t if the input value was a list of values of type t, or concisely, the routine's type is List t -> t. (Your compiler can verify that your implementation abides by this rule, which is known as type safety in general.) As an another example, I can tell at a glance that a routine of type List t -> List t may

  1. drop elements from the input list,
  2. repeat some elements of the input list and
  3. rearrange elements of the input list

but can't do anything else. But if the type was List Integer -> List Integer I couldn't guarantee any of these properties. In fact a function I wrote, no matter what the parameter list is, could return the value [69] and the compiler would still say nice. Go is even worse, since the other option is interpreting all values of being the most general one, Object (or something like that). You can't even know that it's a list of Integers anymore, it could be a weird mix and you'll only know for sure when you program crashes.

Actually you can take the above reasoning even further. Suppose you have a routine of type String -> String. What can you say about it just based on its type? Hardly anything since all computation is essentially just transforming sequences of symbols into other sequences of symbols. There are as many implementations that pass the type checking as there are possible programs. But if you generalize the type into a -> a I can deduce what the routine does since there is only one possible implementation: take a parameter, do nothing with it and return it as the output. So using generics reduces code duplication, increases software safety and correctness and further helps reason about programs.

Soz that this was so long, but following Mark Twain, I just didn't have time to write anything shorter.

3

Moonside wrote

Now I can finally put my Undertale knowledge into use: she was a lot like Alphys good ending run (except Alphys was actually supercompetent in-story unlike the present person I'm talking about). Some problems:

  1. Stops communicating when she had problems
  2. the general lack of guts to just try out things
  3. All or nothing thinking when it came to implementation. I think that coders mostly implement one thing at a time, see if it works/compiles/passes the test and move on to the next thing and learn from the experience and apply it to further cases. This was totally absent. I think she tried to figure it out all in her head and if she felt any uncertainty, she just didn't try to code.
  4. Didn't habitually compile/test/see whether software worked and fix problems or annotate them if unfixed.
  5. Couldn't read official documentation Java had.

Honestly I'd say it was mostly a series of emotional issues more than anything else. You can't learn coding if you fear compiler/test feedback and trying out things and fall apart when things don't work.

2

Moonside wrote

Could you convince them that writing documentation is a nice way to procrastinate and makes the implementation part easier? I swear I solved an implementation problem (which caused no small amount of headscratching) recently just by carefully specifying the function to be implemented. By doing that I ended up describing the cases correctly which then made the implementation trivial. It was a recursive function so a botched case analysis easily leads to incomprehensible behavior.

source control, etc. as fluff, nice to have, non-productive, etc.

¡Dios mío! I'm glad that I've used source control for very low importance projects so that I can use it without any real effort when it's needed.

The crappy part of programming really is that there are so many useful tools that you have to bring together and tinker with to make them good. Like to write good unit tests you presumably ought to be specifying your functionality in good enough detail, your testing framework presumably has a few knobs to be set, then you have to make testing and documentation work with your build system, for Git you need a .gitignore file and so on, all this upfront work and busy work that makes it all easy to skirt.

3

Moonside wrote

Honestly it's in the top tier of book titles, unironically. Instantly memorable, tells you exactly what to expect. A+ Edward T. Wright!

3