This was 22 years ago... it's honestly so tiring to see people use this as a "got 'em!" argument. Times change, businesses change. This is not a case of ideology.
You also helped me realize that part of all this mess is that I HAVE been feeling old. Well, maybe not old... older. I feel like I got hyper-focused on being a programmer (and I feel I never explicitly committed to it, just sort of went along with it) and now I just realized it's been 16 years.
Something I realized when reading your response is that I winced a tiny bit when you mentioned "finding meaning in your work" - as if that was something I did not believe could be achieved.
I think in my mind it's more about going to work and doing things are not... so made-up. I find this extremely hard to communicate. This may be due to me being too far removed from the actual impact whatever we deliver may have. Or as other posters have pointed out, lack of confidence in the general mission.
Or maybe I haven't yet figured out the real reason and this is just something my brain has made up.
Hey, thanks for your input! These are good questions.
Funny thing. A few months ago I've also decided to improve my communication skills - both in reading and writing. (Long way to go...) It did hit me that whatever I end up doing in the long run, communication is the only 100%-reusable skill that can pay off anywhere. And so much time is wasted due to sub-optimal communication.
> It did hit me that whatever I end up doing in the long run, communication is the only 100%-reusable skill that can pay off anywhere. And so much time is wasted due to sub-optimal communication.
Interesting point! I think there's something to it.
Forgive me if my central European bias is showing, but I've always discounted how important it is to align yourself with the mission of the company you decide to work for. Seemed to me like it's a complete bonus and luxury if the two overlap, and the default is just... work.
Of course as long as the company isn't actively working against something you would consider your values.
But it's definitely a question that can't be ignored if one wants to do some digging.
Using the sorted() built-in returns a new sorted array. Getting keys from a dictionary is literally just calling dict.keys(). Sorry, but I don't think you've used Python enough to offer lists like these.
I stand corrected on the mylist.sort() vs sorted(mylist). But really, such a mistake is more likely with two very different ways of doing the same kind of operation.
In ruby you would just mylist.sort() for a new sorted list (although parens are optional if no arguments, but I show them), or mylist.sort!() to sort mylist in place. You don't have to know two very different things. Plus it's obvious with the !
> Getting keys from a dictionary is literally just calling dict.keys()
Nope. Unless your definition of "keys" is a 'dict_keys' class. Chances are really good that what you wanted was a list of keys, not some object which does not behave exactly like a list. If you want to access the keys by index, you can't do it like mydict.keys()[0] because dict_keys does not have an index method.
Oddly, if you want a list of keys of a dict in Python, you just do list(mydict).
But you can also do [*mydict], which gives you a list of keys but is something special you have to learn.
Here's a fun one. Give me the first key of a dict.
Ruby: mydict.keys.first
Python: (several ways)
next(iter(mydict)) # which makes no sense at all... asking for the next value of something when you're actually asking for the first.
list(mydict)[0]
[*mydict][0]
What if you want the values of the dict? Well, no surprise, Python gives you a dict_values object when you do mydict.values(). Likewise, you can't do listy things with that because it's not a list. You have to convert it to a list with list(mydict.values()). Or you can do the [*mydict.values()] thing.
Python is full of so many inconsistencies, the cognitive overhead is much higher than it needs to be. I would argue that it makes people dumber, because they have to waste mental energy learning weird things for special cases.
But what about the rest of my previous post list?
Here's one I left out. The return-early pattern is common in imperative programming. We like to exit a function as soon as we know things aren't going a certain way.
In Ruby: x = fetch_object("bob") or return "bob not found"
In Python you need 2 or 3 lines (2 if you're using the walrus := operator).
if (x := fetch_object("bob") is None):
return "bob not found"
How about setting a value for a variable if it is unset? This is a common thing done when you have variable arguments
Ruby: x ||= "default"
Python: x = x or "default" # not only does it look stupid setting a thing to itself, but it will fail if x is zero.
Dict_values is a readonly set, not a list. Sets are generally unique, non indexable and unordered.
Since dict keys are generally intended to be unique, this is a much better data structure, because very often you just want to check if x in d.keys(), being a o(1) rather than linear search into a list -twice, because you first have to construct the list also!
It’s also more of a set-like view into the original key-set. This is why it shows up as dict_keys rather than set. You wouldn’t want every piece of code that simply does for k in d.keys() to first make a copy of the entire dataset before starting the iteration. Beginners will use these functions all over just like that, even though you can simply do for k in d. Or if k in d. Preventing such footguns is worth the inconvenience of having to convert to list(d.keys()) for the rare case of when it’s absolutely needed.
I’ve also never seen any code that need to get the first item out of a dict, what does that even mean? Dicts are mappings. Better optimize both syntax and performance for the more common use cases. Only use case I can see is an LRU cache but for that there are better ways, like @lru_cache or OrderedDict.pop. Where that’s needed, copying the whole dict into a new array would also be extremely inefficient.
> I’ve also never seen any code that need to get the first item out of a dict, what does that even mean?
You have a dict which contains a collection of similar values indexed by one value (which is the key). These may be records of people, and the key could be their phone number. Or it's documents indexed by some id, and the id is the key. Or orders keyed on order_id.
If you need to make a decision about processing based on some characteristic of the first item, you're not going to loop over the collection; you just need to know the key or possibly some element within the value of the first item in that dict.
Lists, dicts, tuples, sets, etc. are all collections. Why should collections not have as consistent features (and behaviors) as possible? Every collection has a first item. Maybe for unordered collections it doesn't make sense, but only set is unordered here.
It's nice to be able to go from general to specific, and to stay as high up that ladder as possible. And when designing systems that push complexity to the edges, the fewer ways of doing the same conceptual things, the better.
Python provides pop() for lists and dicts, and those both operate on positional data within their respective structures. Python could add first(), nth(), take(), and other nice conveniences to their collections. The low level implementation could be optimized, but the developer would have the benefit of common concepts.
Consistency matters a lot, because it means once we learn a concept or pattern we can apply that pattern generally without having to make a lot of changes for special cases.
For example:
h = {a: 1, b: 2}
h.map { |k,v| v * 10 } => [10, 20]
You could probably have guessed what that did even if you didn't know Ruby.
a = [1, 2]
a.map { |x| x * 10 } => [10, 20]
The only difference here was that we knew that each element was a single value rather than a key value pair (which we destructured into k and v in the previous example).
Half of the list is equally premature conclusions. Without entertaining this too much: You have properties, slots, __setitem__, dict merging with inplace h1.update(h2) or returning {**h1, **h2, “key”:”toadd”}. Defaultdict being clunky, really? Mypy does catch assignment typos outside __init__. Chain failing on non-iterables sounds expected, what else should happen? Implicitly treating as list of 1…? Explicit returns is a good thing, it avoids ambiguity and allows static analysis on missing return paths or returning wrong type.
Still got some gems in there that python could benefit from. Like safe navigation and nested dig, you can sort of emulate it with .get(“top”, {}).get(..) but it’s messy.
Modeling vehicle dynamics as a whole is a great subject, because there are so many parts where you have to explicitly decide on how much you wish to simulate. Brakes, tires, suspension, vibration transfer... On one hand you can have a simulated vehicle in 2 hours of coding, and on the other you can spend two months on tires alone.
One related story I like is how Assetto Corsa Competizione devs bumped into "weird" behavior emerging from their simulations which seemed like a bug - but then confronted with the actual manufacturers and found out that it happens in real life as well:
Highly recommended, video is titled "A traction control bug that was a realistic feature".
EDIT: And this is before you get to aerodynamics, which is a whole different can of worms. With todays GT3 cars, how you simulate the front splitter and rear diffuser can make or break the accuracy of the simulation. It's fantastic stuff. Wish I worked on this day-to-day. On the other hand I have trouble putting it down and going to bed when doing it as a hobby, so...
I know multiple engineering folks in the industry and they constantly tell me about how much the culture sucks. Very cool problems, but it's very cutthroat as you would expect.
Source: live near many teams just outside of Charlotte
This sounds like an opportunity to work with a lower tier race team to build reputation. Cool thing about racing, to the limit of the rules, the sport as a whole is receptive to the advance of technology if it confers a competitive advantage.
Life seems balanced now, I get to scratch my itches, not unhappy at my current job, and I don't feel like I'm saying "no" and making excuses. A tiny step here, a tiny step there, worst case it turns out to be a pleasant stroll.
Why is there such a strong tendency towards treating things as a this-is-it(-this-time-for-real) thing? This only confuses people and muddles up expectations.