570 karma · joined August 28, 2013
About your two situations, I am guessing you mean that the functions rely on state not being passed in, but rather on state referenced from the outer scope? I agree that that complicates both reasoning and testing, and so it should be avoided. In C/C++ this type of design (i.e. relying on static scope state) is practically always avoided as there's rarely any need for it.
If instead you mean that mutable references are being passed in as parameters then logic wise isn't this similar to assignment/binding in a functional language as long as you avoid propagating the side effect to other functions?
I am personally a great fan of immutability, just not functional languages. I can see the justification for limiting the tools at your disposable to guarantee certain things, it's just that in this case I think they are not sufficient.
---
For those downvoting, gee thanks. I see how trying to have a discussion is hurting your feelings.
Please explain?
Mutations can cause side-effects but don't have to. You seem to think that limiting program behavior _necessarily_ alleviates informal reasoning, but that's not the case. Your argument is also highly hyperbolic in terms of testing. A properly designed system with immutability needs to be tested no less than properly designed system with mutability.
Also a lot of the things he lists are not at all as clearly harmful as he makes them out to be.
GOTO: Used in some of the cleanest code bases. For example the lua programming language, redis db, and linux kernel OS. Yes the use is limited, but it's there not because of mistakes but rather because it is sometimes the most clean way.
Numbers: I don't understand this one. In the very least having different types of numbers seems to be a necessity for anything performance oriented such as graphics. JS not having them (they seem to have been added for WebGL as an extension, no?) is not a good reason for all new languages to do the same.
Mutations: I am personally of the view that mutation often simplifies the informal reasoning complexity of a program. There's a reason functional programming hasn't caught on and it likely never will. A hybrid approach of having both immutability and mutability like Rust seems most sensible.
Reference equality (Referential transparency?): If you have immutability do you not get this for free? How can you be sure about getting rid of mutations but not be sure you want objects to be equal based on data?
Each language has it's own quirks that make it special and that's part of the reason programming is fun. There's never a single right way.
- The compiler error messages are awful, especially for newer programmers. By awful I really do mean awful. "Syntax error" is not a very meaningful message, but at least it tells you the location right? Except due to the poor grammar of the language (I did say these objections are subjective) a small mistake like a missing in or semi-colon results in a wild chase trying to figure why you are getting a "syntax error" in a perfectly valid piece of code.
- Unpolished language grammar. There are just a lot of small things that bug me about the language like the existence of "in" for let statements (Rust's approach feels much cleaner), having multiple ways to create blocks (begin..end, and parenthesis), having to type rec for recursive functions, difference between declaration of functions in mli and ml, argument sigs and function sigs use the same delimeter, let is used for binding functions, imperative mode using refs is just plain ugly. These are minor and almost entirely subjective objections, but the real issue isn't just a lack of polish, it's that the language is too unrestricted.
- Language is too unrestricted. 1) It's often very difficult to read other people's code because there are many ways to accomplish the same thing. 2) The language almost invites you to have high levels of nested logic (something considered a cardinal sin in imperative programming) to the extent that it's not uncommon to see (or be tempted to write) 6 or even more levels of depth. 3) Easy abuse of lambda functions (fun and function) can make it difficult to even know how many parameters a function really expects. I mean this in the sense that you need to carefully read the code to get an idea of even whether a let binding is a data binding or a function binding. Of course these are all things you learn to handle and manage with some experience, but they really don't make the language an easy pick-up.
- Language is difficult to reason about internally. Let me give an example. OCaml can be very clever sometimes, like when you prepend to a list, that's an O(1) prepend with no copy of the initial list even though it's immutable. To write better OCaml code you need to become familiar with such things (though I suppose that's true of any language) and sometimes it's not easy (for me at least) to guess internal behavior. For example, does "let t = {t with x} in" modify t in place even though t is immutable (assuming we are the same level where t is first declared, i.e. initial t is no longer reachable) or does it create a new copy of t and then modify the x in that new copy? I guess a fair counter is, who cares?, and I get that, but at the same time I have some underlying drive that makes me want to know (the answer is the second one, the data is copied) at least things such as when I am allocating new memory.
The last big one and the most controversial of all - (purely) functional programming is not worth the trouble. It is inherently more complicated than imperative regardless of all the functional people claiming otherwise. It's not as simple as "you learned one first and that's why it's easier", an argument I've heard repeated many times, one that probably has merit, but also one that cannot account for the difference in difficulty. I can write an entire paper on why functional is more difficult (essentially it will use most of the reasoning as Out of the Tar Pit - which argues that functional is great - but with some changes in the argument to result in an opposing conclusion). In terms of informal reasoning, the benefits of lack of internal (to a function) mutable state are essentially zero, or better worded, lack of local mutable state increases the complexity of a function. It's not like your state doesn't change if you use recursion and immutability... it certainly does, it just mutates transiently while you are building up your result. That's often more difficult to reason about than a typical imperative solution with mutability. Okay, fine, perhaps I am a shit developer who simple isn't smart enough or lacks the experience, but the reality is when you are working on a team, the chances are that you will have a very difficult time gathering 20, 30, or more solid functional developers let alone that many OCaml developers. Ideally, you want your team to all be at least competent in the language you are using and that's harder to achieve with OCaml.
I think OCaml is a lovely language that brings a lot to the table, but I simply can't see it becoming mainstream (or really any other functional language either). The thing that makes sense to me is to merge imperative and functional into some sort of hybrid language, which is one of the main reasons Rust is so exciting. Reduce global mutable state to as low as reasonable while making allowances for local mutable state. Also Rust fixes the three sections of complaints above - great errors and warnings, feels more polished when writing, and forces a much higher rigidity - though it introduces some other issues.
At this point I am not even sure what I'm talking about so I'll end it here hoping the above made any sense at all.
An example of that is the article itself which leverages the gained information from SO to solve the real problem.
Also arcane knowledge is not the same thing as problem solving.
Also your example doesn't make any sense. Creating a law for abortion is not even in the same category as breaking current laws. This is not purely an issue of morality, it's about the rule of law as well.
for i in range(1,100):print("Fizz"(i%3==0) + "Buzz"(i%5==0) or i)
"Our simple projections indicate that muscle contractile speeds that would allow for maximal or near-maximal forces would permit running speeds of 35 to 40 miles per hour and conceivably faster"
So essentially if human physiology worked differently than it did, we could theoretically run much faster. Not a useless result, but not really anything as exciting as they make it sound.
You can always go one level down, but I would hardly say you need assembly for c or c++.
This is only half of it. The second half is to choose a mid size project, write yourself something that resembles a spec, and code it up from scratch. It could be some sys util or perhaps a video game (this will require you to learn library linking).
The third half is to read online articles and tutorials while you do the two things above.
The fourth and final half is to get yourself a book once you have a grasp on the language(s) and learn some of their more complicated idioms and pitfalls.
Also as a side note, at this point in time I don't think the "C/C++" conglomerate make much sense any more as modern C++ looks very different from C. Unless you explicitly need C, I would suggest learning C++ first as it's higher level (and also much larger). Though, idk, maybe learning C first is better as it's the foundation for C++... I guess either is fine, just not both simultaneously.
In regards to long trips, I still maintain that having a distraction like music, audio books, or company to talk to is actually safer than not having them. Your brain getting tired of monotonous activity and scenery is a real thing as anyone who's done a 10 hour drive can tell you. But again my comment wasn't really in the same context as the parent I guess, so there's that.
So you are claiming that having to look away from the road for possibly whole seconds to deal with a phone is not really dangerous, but what is dangerous is your mind wandering? I'm sorry but experience and common sense says otherwise.
I would also argue that your second point is not as not clear cut either. Having some sort of distraction is definitely helpful most of the time when driving long distances. I personally find audio books very greatly help to fight off monotony, which in turn keeps my attention higher than if I was not being distracted.
Some reasons as to why I severely dislike it: 1) When it scrolls the background changes color. There's multiple transitions going on. It's sort of like going to a different website. I lose my entire concentration and interest. 2) No scroll bar. I can't get to the final slide without painfully going slide by slide. 3) When scrolling with the mouse, I lose control of the webpage for about a second. I can keep spinning the mouse wheel but nothing is happening. It's infuriating.