400 karma · joined May 5, 2018
A. aren't testing enough / at all or haven't given any consideration to what is the smallest change needed to deliver value
B. have serious organizational problems around coordination
C. are running a company completely unsustainably
This definition includes nearly every language with modules, polymorphism, and depending what counts as message passing might either dis-include statically typed languages, languages without a defined model of concurrency that disallows shared mutable state, or languages without message passing library support.
If that's what canonically counts as OOP, there's no straw-manning going on here, the discussion is just a comparison against a pretty well-defined category of programming languages with different features that are often described as and understood to be object-oriented.
Whenever people bring this up I often hear that Erlang is supposed to be the canonical object-oriented language, and if that's the case, I'm not sure how we could call this discussion straw-manning, because it's just talking about totally different languages.
lol I know its not arcana or hard math, but framing a decision people regularly make in life without any means of holistic assessment or accounting for the options like its a micro-econ problem if you just informally mean "make a judgement call", is the type of terminology abuse that's the hallmark of a pseud.
> but not everybody uses it well. Many waste efforts on multiple things ("jack of all trades"), others chose the thing that makes them worse off professionally or personally over better options open to them, etc.
And this is at the root of my objection to this, what could you possibly mean here by "not everybody uses it well"? To what or whose criteria can you possibly make such an assessment?
> So, that's the point I was making: choosing math over Chinese (as the author suggests) can work out well from a O/C perspective. Understanding math better is more approachable than learning a language like Chinese adequately to make anything of it, and can have a wide impact (especially to a programmer, but also in personal life, business decisions, etc).
You might fall in love with a Chinese national and want to learn your partner's native tongue. You might have your life wholly changed by a work of Chinese literature. This is why this whole framing is utterly insane, there's no way to account for all the ways your life might be bettered by both these pursuits. Why even make some facile pseudo-analytic attempt. It's just dumb STEM dick measuring to pretend like there's a way to assess this.
There's lots of enjoyment to be had in learning things that aren't immediately (or even remotely) useful, and there's often a lot of unanticipated utility in learning things that are pursued for pure enjoyment. There are entire fields in mathematics that were/are pursued for personal enjoyment and later proved to be incredibly useful (or might never be!).
> Not every subject has equal importance. It would also be naive to think every subject or skill has equal relevance to a particular person's life and therefore one can just choose randomly.
I'm not saying you need to choose your pursuits randomly or without account of the time they take, but I think making these choices only for monetary gain or purely on some basis of what utility you think they'll provide is a pretty joyless existence in either case, and w/ the latter consideration is a pretty naive accounting of your ability to meaningful assess an "opportunity cost". Leisure activity, learning for learning's sake, broadening your cultural horizons, etc. are all worthwhile things in my book.
If you're talking about opportunity cost in a fuzzy "there are other things I'd rather learn, or some particular thing seems more useful to me now" kind of way, that's a goofy metaphor and an unhelpful insight in the context of offering advice about what things to learn.
> (I learned that lesson very late in life. In my 20s, I was very careless and carefree about what I learned and I squandered away a lot of valuable years. I wasn't discriminating enough about the topics I spent time on.)
Without any context into what you think was squandered by learning other things, it's impossible for me to appreciate your POV on this, but it seems unlikely to me that you lost all that much.
Almost nobody uses lazy IO anymore though. Most IO is done w/ strict IO functions from the bytestring library and often with stream processing libraries like conduit or pipes.
Your example of how to handle max for array arguments is exactly the kind of thing I would discourage in js code, because it overloads the meaning of "maximum" to data that don't have a natural way of assigning an ordering if heterogeneous arguments are permitted (actually it sounds like you're saying something like max([1], [9]) should return "9", which doesn't correspond to an intuitive understanding of "maximum" at all given it returns something that isn't either of the passed arguments). Whereas the rust code can use the "PartialOrd" trait to ensure we only try to produce a maximum of like elements with a defined ordering relation. That's fine for a limited number of cases where its easy to show type equivalence in js, but I think it's problematic as a general design principle, and because you don't have ways to express the limits of polymorphism I've seen this kind of thing proliferate to unsafe uses of a function very quickly.
I think this attempt to come up w/ reasonable interpretations for unanticipated usages of a function is kind of a rabbit hole. Beyond that I think it's also problematic to assume that all usages of a function in a language without a type system are intended usages, i.e. that programmers _mean_ to pass arrays whenever an array appears as one of the arguments.
There's a tradeoff here between generality and how important it is to encode all invariants about a piece of data. Many haskell list processing functions are expressed in terms of right folds, which makes infinite lists fairly unproblematic to work with so long as only part of the list is demanded in the end, however for some cases you may want the type system to ensure you can't receive an infinite list.
Absolutely. I think it's been getting better at that on the tutorial front. For a long time there were very few books I'd actually recommend for haskell, but Haskell Programming from First Principles [1] changed that for me (personally). And I think Stephen Diehl's excellent What I Wish I Knew When Learning Haskell [2] is a fantastic general resource for newbies. But I think the community could stand to have more of this, absolutely.
And I definitely agree about libraries. I'd like to see more haskell libraries with extended tutorials, and written w/ a non-expert audience in mind. I think the community has for so long been dominated by long-time haskell developers and people ensconced in functional programming, much of the documentation is written for those kinds of people.
I started using haskell at my last job after having done a couple years of functional programming in scala, but I honestly never found it required that much knowledge of category theory. The FAM trio of classes (functor, applicative, monad) are the most common ideas used from category theory in an explicit way, and they're frankly so prevalent at this point in the industry at large that they're in basically every language in extremely common libraries. Most programmers are pretty familiar w/ map and bind (which is also sometimes called flatMap, then, and_then, or chain). Applicative functors might be a little more exotic, but they're easy to pick up if you understand the other two. And I don't think you really need to understand what a morphism is or how to read arrow diagrams to really use any of these things. If you can use arrays in javascript, you can use the IO monad.
Most of the challenge in haskell for me was figuring out stuff like how I should structure my code to enable mocking out effects for testing (there's multiple answers to this w/ different tradeoffs), or how to get good editor support without ghc-mod breaking. I haven't used haskell in industry in about the past two years, but I imagine these are still some of the biggest challenges w/ using it.
Your tests are probing your code on a narrow range of inputs (or if you're using something like property testing, potentially a larger but still finite range) drawn from the valid state space that is almost always too large to actually verify. They're also themselves pieces of code that itself can have bugs. Formal methods can prove properties about code, but usually w/ a much larger investment of time.
> The need for a debugger is a symptom of a sick system. I have never required a debugger on a healthy system.
I think people who say stuff like this are probably a little in denial about how many bugs they've actually written and how difficult it is to get any kind of certainty about the correctness of their code. Programmers write bugs, why are we policing the tools they use to fix them?
Even if your team executes perfectly and never runs into this, the biggest problem IMO is that you can't really enforce most of your guarantees w/ any degree of confidence w/o a typed schema. Even if you work within a typed language that perfectly validates all the invariants of your application before storing anything, the second you need to perform work that does not strictly funnel data through your application (i.e. an update query), you are effectively gambling on whether or not those invariants will hold. This kind of "read-modify-write" flow of data doesn't really perform well (or even hold validity) for a lot of common use cases, so in reality you need your database to ensure these things for you.
Also the two deployed apps problem is just a special case of two people interacting w/ a database who aren't working under the same assumptions as to what invariants should hold. That can happen in single code bases, even with a lot of care taken.
There certainly are invariants that are non-trivial or cumbersome to enforce strictly with a schema, but you can really only enforce them w/ a database that provides serializable transactions.
In many cases, schematization of data in the database is good for other reasons though (for instance, guaranteeing type-normalized data in the presence of multiple deployed versions of an app via accident or otherwise, ensuring your queries and updates are typesafe, etc.)
> that anyone should be able to publish their code on any server, in contrast to central registries such as Perl’s CPAN, Java’s Maven, or Node’s NPM. Placing domain names at the start of the go get import space reused an existing decentralized system and avoided needing to solve anew the problems of deciding who can use which names. It also allowed companies to import code on private servers alongside code from public servers.
lol statements like this are infuriating. Go is no more decentralized than those languages, unless you consider git hosting something people in standard practice do on their own (survey some of the top Go dependencies and see if that holds true). They simply lack a package index, but the cited language package managers both have those and allow you to host your own.