One could hope, but any library abusing kwargs in all their methods is showing they’re willing to go through the absolute minimum to make their code usable, let alone readable and self-documenting.
It's a tiny hope. But a hope nonetheless. Fortran is fun.
Also, do you prefer a specific version of Fortran, or is the latest one fine?
You can read more about the language and its high-level features here: https://fortran-lang.org
That website/community was created in part by the original author of the Python Sympy library, Ondřej Čertík. He is also working on his own Fortran compiler that you can use via webassembly to play around with Fortran; find links if you want to play here: https://lfortran.org
I've only dabbled a little, but I like the general idea, and I appreciate a F/OSS Fortran compiler being developed like this alongside actively seeking to grow the Fortran community & push the language & its libraries forward.
I expect more widespread adoption of Fortran to be quite a ways out, but what Ondřej is doing for Fortran is necessary (not sufficient) for such adoption to be the case.
[1] Is Fortran easier to optimize than C for heavy calculations?
Fortran has also added support for e.g. object-oriented programming, pure functions (no side effects for better optimization), and pointers. So idiomatic modern Fortran code looks very different from the “Fortran 77” code that many people might think of when they hear the name :).
The next step is Idris, where you define starting and desired type and start interactive shell to figure out right way to get there.
However....
Nim is unlikely to go mainstream. It's not the next Rust and not for technical reasons.
Julia won't budge Python out of the top slot anytime soon, although it should in many scenarios past simple scripting.
The Azure SDK is full of them, making liberal use of kwargs.pop. What a nightmare.
At first I was kinda giggling. But actually there are such things, if the Mapping is also ordered.
LRU cache, trees, tries… and—oh wait—all CPython dicts are ordered these days!
(Honestly I have only used the modern ordered-nature of `dict` for serialization to versioned or human-editable files. But why not an algorithm with a “`stackdict`” I guess?)
Naked kwargs is so difficult to work with that I hesitate to think of a use case where it wouldn’t be an anti pattern.
Preferable for whom? I do not prefer it. I much prefer to avoid the extra work it creates for me vs. the simplicity of kwargs. I use explicit args for the function I made and then add *kwargs on the end and then I don't have to write bespoke config objects or copy and paste a bunch of stuff that might be obsolete by a future update to some library and also pollute my function's signature. I would very much welcome a way to tell callers where kwargs is going without having to do extra work.
For code with many users, creating a few extra minutes of work for one dev is preferable when the alternative would be every dev who uses that code has to spend that same extra work and then some to grok what exactly is going on with the method signatures. Being explicit also creates traceable code, in that you can search a keyword to find everywhere it’s used or passed rather than tracing methods where it might be used.
I can promise very few users would be thankful for the elegance and minimalism of args/kwargs when they’re source-diving trying to figure out how to get some basic functionality to work.
Looking at it another way, the hunk of code in charge of serializing your message does not care one whit about the innards of each message, and making it become aware would add tremendous complexity with no real value.
One significant issue with static typing in Python is how much boilerplate is required to use types when also doing the sorts of things that dynamic Python is really good at - for instance proxying functions. If you want to do that now and preserve the types, you need to re-declare the types of everything in the wrapper.
Now, if the underlying function already made use of Unpack, you could "reuse" that type in your own wrapper with low boilerplate and less chance of things diverging in hard-to-refactor ways.
E.g setup something and then pass the kwargs through to the other function.
from collections.abc import Callable
from typing import TypeVar, ParamSpec
import logging
T = TypeVar('T')
P = ParamSpec('P')
def add_logging(f: Callable[P, T]) -> Callable[P, T]:
'''A type-safe decorator to add logging to a function.'''
def inner(*args: P.args, **kwargs: P.kwargs) -> T:
logging.info(f'{f.__name__} was called')
return f(*args, **kwargs)
return inner
@add_logging
def add_two(x: float, y: float) -> float:
'''Add two numbers together.'''
return x + yJust reading this sent a chill down my spine. I have horrible memories of having to read the code to figure out what something was doing (in JavaScript, Python, Ruby, etc), due to the disaster of an anti-feature called dynamic typing having been used.
> so not really any point in trying to convince you
You’re right about that, but I take a stronger position on this than for example something very subjective like curly braces versus white space indentation. I am indeed very dogmatic and take a hard-line on this. To the point that I’ll say this: dynamic typing is simply a wrong and bad engineering decision.
Another example of a bad thing is allowing null to be a part of every type instead of requiring an explicit ? in the type, or the use of an Optional wrapper — and this is something any modern languages — to name a few Rust, Kotlin, etc fixes. But that isn’t meant to level a personal attack against the languages designers of the past (or to say that they were stupid). Allowing every type to be Union[T, null] was a simply a language design mistake (that potentially cost us billions) that we need to rectify and move forward from.
However, imo, dynamic typing is a 100 times worse than not having null safety (or not having memory safety like C or C++). I can work with a C or C++ without much trouble, but not with dynamic typing. Dynamic typing is simply just inexcusably horrid.
Untyped languages tend to be at the forefront of paradigms, and typed languages come in toward the end when reliability and need for tooling are more important than innovation/discovery.
In the 90s a bunch of kids were building websites with LAMP stacks while serious engineers were building aging/about-to-be-irrelevant desktop software in serious, typed languages.
I kickstarted a project in Python a decade ago that was wild on dynamic typing. As it passed a critical threshold of ~10k LoC, it became nearly ummaintainable.
What's that `response` passed here? A verbatim response object from `requests`? A proxy mapping? Bytes? A JSON string? If so, a list or a dict? And what fields are inside?
Multiply it by tens or hundreds of methods and classes, and it's easy to see why projects based on purely dynamic patterns fail to scale.
By now I have almost completely rewritten that project to use type hints everywhere I could. And guess what? In 95% of the cases I knew exactly what was being passed - or the choice was about 2-3 types at most, so a Union sufficed.
Yes, there's a 5% of cases where Python's dynamic typing features are a blessing. The power of meta programming in Python is often underestimated. Reflection is amazingly intuitive compared to the patchwork mess of Java, Kotlin and friends. Everything can be mocked without hassle and boilerplate. And duck typing can really be useful sometimes.
But, again, in an average project I wouldn't expect code that benefits from these features to make up more than 5-10% of the codebase.
For everything else, just do yourself, your future self and anyone who will work on your code a favour, and use type hints.
The P in the LAMP stack is still a bit of a mystery to me. It could (one could wish) have been Haskell instead, but oh well.
Now I just have to wait 5 more years until 3.12 is sufficiently old that work lets me use it.
Bets on user-upgradable Python on Linux by 2030?
(Of course, then you take on the responsibility of keeping up with patch releases yourself, which is why we use distros. But if it's just a small number of packages on top of a distro-managed base system, it's perhaps not so bad.)
Have you ever worked in a place that uses Python? When someone says to you "hey it's not working" are you really going to say with a straight face "oh yes, you just need to compile Python from source". Come on, this is one of those obviously stupid situations that for some reason people feel the need to defend. It's not defensible.
You don't need to compile Node or Rust or Go or Deno from source to install the latest version.
https://realpython.com/python-versions-docker/#running-pytho...
Use asdf. You don’t want to manage your project’s dependencies at the system level any more than you have to.
1. https://docs.python.org/3.12/whatsnew/3.12.html#pep-692-usin...