I have never particularly liked Python. I mean, as a programmer, I consider any coercion into a particular way of doing thing an insult. Thus, the whole there-is-only-one-way-to-do it and benevolent-dictator affairs have never rhyme with my personal philosophy. But I always restrained from criticizing Python. After all, I have never used Python extensively, and my contact with it has never resulted in enough pain for me to hate it.
Well, life changed. I was forced into Python by a class. An algorithm class no less. I love algorithm and theories. Everything there is shiny and flawless, with no wiggle rooms for bugs and the likes. Plus, programming in these situation excites: the problem is well-defined, the graders favor style over pesky optimization, and the solution is polished. This is the exact reverse of profession work, where the result (not the code, but its effect) is everything, and pretty code costs night and weekend (plus lots and lots of fighting).
When I first realized that my class requires Python, excitement actually prevailed briefly. After all, if you ever search for something like "python teaching language," you would see people say all of those glorious things about how python is absolutely beautiful for teaching. I have never liked Python's tyrannical philosophy. However, well, this is a golden chance to learn Python right on its own turf. Maybe I would like it. Maybe my opinion would match that of my friend (apparently Python grew on him after a while). Maybe.
Well, Python crushed my hope with its stupidity (seriously, I have no other names for this), bad design, and generally annoyance to use.
Firstly, let me be very frank: I miss type declaration. I miss it. I mean, production code can sustain lack of type declaration much better than academic code. Why? Because you have tests and documentations and an expectation of proficiency in the language to fill in the blank. Academic code delivers on idea, not execution. So, it should be readable without compiler, without running, without tests, and with minimal documentation. For goodness' sake, the code itself is the documentation of the text (have you read computer science paper? The code explains the English). However, without type declaration, it's impossible to figure out how to use a value without context. Each solution skeleton in my class has 10 lines of comments to to explain the expected type and usage of the input and output. Like 100+ characters which can be easily written in 10 characters in Java or C#. Seriously.
Another thing on type declaration: people keep whining about how much characters they waste. Well, let's ignore my comment on the necessary comments for dynamically typed inputs and outputs, and assume for a moment that you can read the mind of the coder to know how those things should be used. Will dynamic typing save a lot of waste in that case? The answer is no. Remember, we are talking about academic, teaching situation here. The most important virtue here is readability, not efficiency. This generally leads to quite small functions with very few extra variables declaration aside from input of functions, and most of these extra variables are counters (you know, i, j, k, etc.). In most cases, the variables are values passed between functions. You will have to declare them as arguments anyway. Furthermore, because those variables are interfaces between functions, one often wants to document how they should behave, aka write out the types. Thus, the saving here is minimal, if at all. And the readability of dynamic types goes down the drain thanks to the comments.
Talking about variable declaration, since when is declared-when-first-used easy to read? Again, this may be so in production code, where everyone deals with the same set of code days over days. In academic settings, this is bullshit. To determine what the variable should be, one has to look for its first use, usually in the thick of processing. I remember how Pascal was adamant about all variables declared right at the beginning. The requirement stands for a reason: you know, loud and clear, what each variables should behave. No need to read through the code, no need to guess and assume. This helps readability of massive amount of code at once without warming up time. This helps academic code.
Well, let's get over the stupidity of variables and their types. Let's talk about Python inability as a programming language. See, my instructors seem to like something call Numpy a lot. I get it, it's for numerical computation. However, numpy imposes a different set of containers, with vaguely similar syntax but mutually incompatible with Python built-in containers. What does this mean? Either one of two things must be true: Python does not provide a set of interfaces (think List in Java and C#) that is general enough to do things with, or Numpy people are fundamentally stupid and lazy. I pick the first reason. I trust the people. I distrust dictators. This is kinda like Go and APL (never used, only passing insult here; maybe incorrect). Basically, in those languages, all users are bastards who can't do things well. Thus, the only way to actually do anything beside the wills of the language creators is to write fundamentally separated interfaces that resemble the base language. Python is worse: because the variable are dynamically typed, you can't know for sure what the hell is in there. So, if you receive an array, be sure to check where it is from (no type, remember) before doing division and put some numbers in it. Put float in an int array, which is usually OK, may destroy your program.
Oh, this refers me to a third problem: the necessary to run the program to see obvious flaws. I frankly don't understand the whole cheering over runtime error rather than compilation error. It's beyond stupid. In fact, it is an insult to the learners, consider them incapable of reading code. Why? Compilation errors are obvious. Remember, if a computer can pick it up, a reasonably-trained human can. Runtime errors, on the other hands, are subtle and hard to pick out. For example, division of a number over a string can be either a compilation error (since variable must be typed) or run time error. The former case can be picked out easily by human (let's face it, human can read a string variable declaration); the latter cannot (um, what is that variable types again?). When everything is forced to be spelled out, everything is clear. Humans can read them, with or without computers. When everything is, "trust me, it's fine," well, sorry, I don't trust myself to not mistype things.
Btw, I should also point out that this is another difference between production and teaching code. In production, most of the time, you frankly don't know what is supposed to be the solution. At least I don't. So, the usual process involves trying things out, see what happens, then finally code up a final solution based on the evidence (this is especially true for more complicated bugs or novel situations). In class, the reverse is true. The learners start with a class of knowledge to try out, and the code's purpose is to express that knowledge in a more concrete terms. This is true for both theory and more practical classes. Again, each class would have a set of concepts, and the learners should solve the problems by these before coding. Thus, most issues with the code can be picked up by compilation, either by eyes or by machine. Lastly, since teaching code demonstrates a concepts, often it does not need to be run at all. The graders would just compile it in their head, goes through the logics, and give feedback. In such case, runtime errors are terrible. They hide hideous bugs while provide incentives to hack things together. Hacking is not the point of knowledge transfer. Hacking is for production.
Finally, let's talk about indentation. Another big selling points of Python: hear ya hear ya, your code's readability is enforced by your intepreter. Yeah. Let alone the fact that the interpreter fails to detect hosts of issues until runtime, let alone the fact that input values' behaviors are undefined by default, let alone the fact that basic types may be unusable. Python will help your cosmetic to look good! Bow down to pretty code! This sickens me every time. I used to be TA for a Scheme-based class. Every time (and I meant every time), the love of the students to Scheme would jump about 5-fold after I taught them correct indentation, and they would do this without the compiler acting like Hitler. Every programmers with a few months of experience would indent reasonably well for most C-like programming language. Furthermore, given that teaching code is usually short and sweet, this whole concept of coercion of style is generally useless. On the other hand, I have yet to notice any standardization in naming (you know, internalCapitalization vs. underscores_for_spaces). Maybe I am too green, but it seems like people just do what the hell they like here. Again, teaching code is short and sweet, so this kind of styles matter a great deal. But of course, it's impossible to enforce (maybe Python should outlaw underscore in names, or outlaw mid-name capitalization).
Frankly, here is my impression of Python and its cheerleaders: Python is great for very very beginners whose only interest is to show off. It is very fast to punch in something resembling good code. It is very fast if you don't do anything major. It is very fast to get buggy code "running." However, as soon as you put any serious logics in, Python crumbles like worms under someone's shoes. Its code needs serious context (either comments or the usage site) to make sense; its abstraction layer is lacking; its compilation system cares more about cosmetic than sustain. Basically, everything is wrong. On top of that, it lacks any kind of mind-twisting advancements (I am thinking about Lisp and Rust) or pliability for hacking and playing (I am think about Perl, of course, but C is a good example). It's like a dumb dictator: insists on minor styles but lets bigger problems go unchecked. I sincerely hope I won't cross path with it again. Ever.
Showing posts with label programming. Show all posts
Showing posts with label programming. Show all posts
Saturday, April 18, 2015
Sunday, November 13, 2011
To Type or Not to Type
Again, the superiority of dynamically typed language is taken up by a hacker over hacker news. This time, with a different tack. Types, according to our lovely author, is not a sign of sadism and/or masochism where one derives great pleasure out of torturing oneself and everyone else with all of those stupid declaration; rather, it is a sign of n00bs, who can't comment enough in there code.
Oh, how I hate the word n00b. In thy name, how many bugs/stupid features have been created? In the olden days, the number 1 cause of bugs were efficiency, which modern programmers seem to abandon amass (for a good reason, of course). These days, n00b-proof is their war banner for creating bugs.
Back to the discussion. Are new programmers more drawn to comments and statically typed system? I doubt it. Actually, it acts the reverse: new programmers (aka n00bs) detest those things. After all, they do not learn how to program to do those dumb and boring task. Heck, in programming classes, even calculating Fibonacci numbers are too dumb, too useless for those newbies. Nay, they want "cool" new tech, like GUI, like 3D, like games, like Web, etc. Things that they can show off to their n00b-er friends; things that can earn them millions in days. Oh, and they want those things yesterday.
Generally speaking, I see the urge to organize, model, and document code as a sign of maturity, and the actual action of doing so a sign of discipline. It is easy to see why: writing those documentations require effort, great effort even since they are not particularly creative or fun. Creativity and fun sustain a programmer; activities without these hurts, sometimes physically. Extending extra effort to do those activities, thus, is hard, and great discipline is required to do so. Thus, calling those with the discipline to do things that you hate n00bs is not just insulting: it's stupid and n00bs.
However, is type necessary, even? (since sadist and masochist people like pain, too).
Types are unnecessary, if your program is hacked together within about 2 - 3 sessions, and its useful lifespan is within about a month, or less. Anything more than that, and you are begging for troubles, not even in the long run.
First and foremost, let's make this clear: you need to know meta anyway. You need to know what a function does, what it expects, and what it returns. You do. Otherwise, you will start to add "2" to 1. That's mild. How about asking a missile system to shoot at pi number? Thus, you need to know what a function expects, and what it will return.
Now, the question becomes: how do you remember this meta? First note: you will need this 2 weeks from now. Second note: your buddy writes the function for you. Third note: oh, that function is too slow, so you need to rewrite it.
There are 2 schools of thought on this matter, as far as I see: there are the n00bs, stupid, incapable people who do not believe in their miserable brains; and there are super uber programmers/hackers who can remember everything. The former ones would prefer to write down the meta information, preferably in such a manner that it will be forced to keep up with the code base (aka the type system); the latter just keep it in their minds, and re-read the code, follow the logic when they (verily occasionally) forget.
You pick: which one is more usable?
I am seriously amazed at how people talk about a program or a code base as if it is a living, breathing creature: it needs freedom. Dynamically typed system frees the code from this, from that. As if the code cares about those grand freedom. In the end of the day, no matter what language you use, no matter what feat you attempt, a computer program calculates some pieces of data, and put them in some appropriate places. End. In addition, the most important aspect of a program is to calculate the the right thing, and put the right info into the right places. All programs, thus, are inherently deterministic and static.
Now, I will admit this: static type system can be painful from time to time. Sometimes, the pain is good. For example, it requires that you know what you are trying to do. I greatly admire and am entertained by the notion of "exploration programming," in which you do a task that you have no clue what it is. It invokes the image of Columbus striving into the unknown, doing the unthinkable. And we still call Native Americans Indians. But seriously, this is programming, not exploring. We want our programs to be right, to solve our issues, not to embark in a great saga. Thus, we want to know what we are doing, so we can do the right things.
Sometimes, the pain of static type system is in deployment: for the most cases, statically typed code requires separate compilation, and modification cannot be done on-the-fly. However, this can be solved, more or less, in a good setup. These days, you can create a system such that upon commit, it can compile all of the new code, switch over to backup server, deploy new binaries to the main server, switch back to main server, deploy new binaries to the backup server. It's not exactly on-the-fly, but hourly is totally feasible. And let's be frank, if your customer service is good, how bad it is to ask the customers to wait a day? For most cases (provided it is really a day), not that big of a deal. How about this case: upon a specific input, your system will throw an exception, and will print the stack trace, which reveals your database structures, along with password and username to the table to contain all personal information, to the user?
Lastly, it can be a pain to type in the declaration. However, very frankly, except the case where you actually use Notepad (without the plus plus) to write code, this is largely a solved issues. Heck, IDEs these days will put in those code for you with rather high accuracy!
All in all, the question of typing is more of a personal matter than anything else. If you would like, I believe that it is provable how static type helps a code base reduce bugs (hell, it removes a class of bugs), improve long term (or even short term, when the dude who wrote the code takes off for a month and his code needs to be modified) productivity, and generally make life easier. It can also be proven that all of the talking about types is just waste of everyone time, and all things can be done in all languages (except explicit toy ones), and that we should get back to work instead of arguing over silly things. Your call.
Oh, how I hate the word n00b. In thy name, how many bugs/stupid features have been created? In the olden days, the number 1 cause of bugs were efficiency, which modern programmers seem to abandon amass (for a good reason, of course). These days, n00b-proof is their war banner for creating bugs.
Back to the discussion. Are new programmers more drawn to comments and statically typed system? I doubt it. Actually, it acts the reverse: new programmers (aka n00bs) detest those things. After all, they do not learn how to program to do those dumb and boring task. Heck, in programming classes, even calculating Fibonacci numbers are too dumb, too useless for those newbies. Nay, they want "cool" new tech, like GUI, like 3D, like games, like Web, etc. Things that they can show off to their n00b-er friends; things that can earn them millions in days. Oh, and they want those things yesterday.
Generally speaking, I see the urge to organize, model, and document code as a sign of maturity, and the actual action of doing so a sign of discipline. It is easy to see why: writing those documentations require effort, great effort even since they are not particularly creative or fun. Creativity and fun sustain a programmer; activities without these hurts, sometimes physically. Extending extra effort to do those activities, thus, is hard, and great discipline is required to do so. Thus, calling those with the discipline to do things that you hate n00bs is not just insulting: it's stupid and n00bs.
However, is type necessary, even? (since sadist and masochist people like pain, too).
Types are unnecessary, if your program is hacked together within about 2 - 3 sessions, and its useful lifespan is within about a month, or less. Anything more than that, and you are begging for troubles, not even in the long run.
First and foremost, let's make this clear: you need to know meta anyway. You need to know what a function does, what it expects, and what it returns. You do. Otherwise, you will start to add "2" to 1. That's mild. How about asking a missile system to shoot at pi number? Thus, you need to know what a function expects, and what it will return.
Now, the question becomes: how do you remember this meta? First note: you will need this 2 weeks from now. Second note: your buddy writes the function for you. Third note: oh, that function is too slow, so you need to rewrite it.
There are 2 schools of thought on this matter, as far as I see: there are the n00bs, stupid, incapable people who do not believe in their miserable brains; and there are super uber programmers/hackers who can remember everything. The former ones would prefer to write down the meta information, preferably in such a manner that it will be forced to keep up with the code base (aka the type system); the latter just keep it in their minds, and re-read the code, follow the logic when they (verily occasionally) forget.
You pick: which one is more usable?
I am seriously amazed at how people talk about a program or a code base as if it is a living, breathing creature: it needs freedom. Dynamically typed system frees the code from this, from that. As if the code cares about those grand freedom. In the end of the day, no matter what language you use, no matter what feat you attempt, a computer program calculates some pieces of data, and put them in some appropriate places. End. In addition, the most important aspect of a program is to calculate the the right thing, and put the right info into the right places. All programs, thus, are inherently deterministic and static.
Now, I will admit this: static type system can be painful from time to time. Sometimes, the pain is good. For example, it requires that you know what you are trying to do. I greatly admire and am entertained by the notion of "exploration programming," in which you do a task that you have no clue what it is. It invokes the image of Columbus striving into the unknown, doing the unthinkable. And we still call Native Americans Indians. But seriously, this is programming, not exploring. We want our programs to be right, to solve our issues, not to embark in a great saga. Thus, we want to know what we are doing, so we can do the right things.
Sometimes, the pain of static type system is in deployment: for the most cases, statically typed code requires separate compilation, and modification cannot be done on-the-fly. However, this can be solved, more or less, in a good setup. These days, you can create a system such that upon commit, it can compile all of the new code, switch over to backup server, deploy new binaries to the main server, switch back to main server, deploy new binaries to the backup server. It's not exactly on-the-fly, but hourly is totally feasible. And let's be frank, if your customer service is good, how bad it is to ask the customers to wait a day? For most cases (provided it is really a day), not that big of a deal. How about this case: upon a specific input, your system will throw an exception, and will print the stack trace, which reveals your database structures, along with password and username to the table to contain all personal information, to the user?
Lastly, it can be a pain to type in the declaration. However, very frankly, except the case where you actually use Notepad (without the plus plus) to write code, this is largely a solved issues. Heck, IDEs these days will put in those code for you with rather high accuracy!
All in all, the question of typing is more of a personal matter than anything else. If you would like, I believe that it is provable how static type helps a code base reduce bugs (hell, it removes a class of bugs), improve long term (or even short term, when the dude who wrote the code takes off for a month and his code needs to be modified) productivity, and generally make life easier. It can also be proven that all of the talking about types is just waste of everyone time, and all things can be done in all languages (except explicit toy ones), and that we should get back to work instead of arguing over silly things. Your call.
Subscribe to:
Posts (Atom)