akubera
Joined 10 years ago
Joined 10 years ago
The discussion: https://discuss.python.org/t/pep-736-keyword-argument-shorth...
The rejection: https://discuss.python.org/t/pep-736-shorthand-syntax-for-ke...
Grammar changes, in particular things used everywhere like function invocations, have to be worth paying the price for changing/adding new rules. The benefits of fewer characters and more explicit intention weren't enough to outweigh the costs.
There were other considerations: Do linters prefer one syntax to another? Does the name refer to the parameter or the argument in tooling? Should users feel pressure to name local variables the same as the function's parameters? What about more shorthand for common cases like func(x=self.x, y=self.y)?
I personally did not like the func(x=, y=) syntax. I think their example of Ruby's func(x:, y:) would actually make more sense, since it's syntax that would read less like "x equals nothing", and more "this is special syntax for passing arguments".
It's been almost 14 years since that was published, so maybe some self-reflection is due.
It's easy to write code that deadlocks; make two shared pointers to the same mutex, then lock them both. This compiles without warnings:
let mutex_a = Arc::new(Mutex::new(0_u32));
let mutex_b = mutex_a.clone();
let a = mutex_a.lock().unwrap();
let b = mutex_b.lock().unwrap();
println!("{}", *a + *b);Visualizes a proof and talks about special cases and a little of the history.
As for @Cerium's real-life usage, you have possibility of uneven legs and uneven floor (and discontinuities, like a raised floorboard) so it's obviously not guaranteed, but if the floor is warped and smooth enough, you can try.
[EDIT]: Changed wording
There's very sophisticated compression systems throughout each experiment's data acquisition pipelines. For example this paper[1] describes the ALICE experiment's system for Run3, involving FPGAs and GPUs to be able to handle 3.5TB/s from all the detectors. This one [2] outlines how HL-LHC & CMS use neural networks to fine tune compression algorithms on a per-detector basis.
Not to mention your standard data files are ROOT TFiles with TTrees which store arrays of compressed objects.
It's all pretty neat.
But for addition, the idea is to give the complete number if you do `a + b`, otherwise you could use the context to keep the numbers within your `ctx.add(a, b)`. But after the discussions here, maybe this is too unsafe... and it should use the default precision (or a slightly larger one) in the name of safety? With a compile time flag to disable it? hmm...
Having user-set generic limits would be cool, and something I considered when const generics came out, but there's a lot more work to do on the basics, and I'm worried about making the interface too complicated. (And I don't want to reimplement everything.) D
I also would like a customizable parser struct, with things like localization, allowing grouping-delimiters and such (1_000_000 or 1'000'000 or 10,00,000). That could also return some kind of OutOfRange parsing error to disallow "suspicious" values, out of range. I'm not sure how that to make that generic with the serde parser, but I may some safe limits to the auto serialization code.
Especially with JSON, I'd expect there's only two kinds of numbers: normal "human" numbers, and exploit attempts.
1e10 + 1e-10 = 10000000000.0000000001
1e10000000000000000000 + 1e-10000000000000000000 = ...
It's tough to know where to draw the lines between "safety", "speed", and "functionality" for the user.[EDIT]: Oh I see, fix the parser to disallow such large numbers from entering the system in the first place, then you don't have to worry about adding them together. Yeah that could be a good first step towards safety. Though, I don't know how to parametrize the serde call.
Sounds like Haskell made the right call: put warnings in the docs and steer the user in the right direction. Keeps implementation simple and users in control.
To the point of the article, serde_json support is improving in the next version of BigDecimal, so you'll be able to decorate your BigDecimal fields and it'll parse numeric fields from the JSON source, rather than json -> f64 -> BigDecimal.
#[derive(Serialize, Deserialize)]
pub struct MyStruct {
#[serde(with = "bigdecimal::serde::json_num")]
value: BigDecimal,
}
Whether or not this is a good idea is debatable[^], but it's certainly something people have been asking for.[^] Is every part of your system, or your users' systems, going to parse with full precision?
Also the name and the generator is nicer (for some definition of nice):
>>> def square_vals(x : list):
... return (v * v for v in x)
...
>>> square_vals([1,2,3])
<generator object square_vals.<locals>.<genexpr> at 0x786b8511f5e0>
>>> def square_vals_yields(x: list):
... for v in x:
... yield v * v
...
>>> square_vals_yields([1,2,3])
<generator object square_vals_yields at 0x786b851f5ff0>
I think it's more idiomatic to pass generator-comprehensions into functions rather than return them from functions >>> sum((v*v for v in x))One thing the author might want to try is writing their own "build-backend". You can specify your own script (even use setup.py) and that will be the target of python -m build or pip wheel or presumably whatever build-frontend you use.
# pyproject.toml
[build-system]
requires = ["setuptools"]
build-backend = "setup" # import setup.py as the build-module
backend-path = ["."]
Then in setup.py you should write two functions: def build_sdist(sdist_directory, config_settings):
...
def build_wheel(wheel_directory, config_settings, metadata_directory):
...
Where config_settings is a dictionary of the command line "--config-settings" options passed to the builder. (sys.argv does not have access to the actual invocation, I suppose to ensure frontend standardization)example:
$ python -m build --config-setting=foo=bar --config-setting=can-spam
# will call
>>> build_sdist("the/dist/dir", {"foo": "bar", "can": "spam"})
Of course, you can extend the default setuptools build meta so you only have to
do the pre-compilation or whatever your custom build step requires: from setuptools.build_meta import build_sdist as setuptools_build_sdist
def build_sdist(sdist_directory, config_settings):
# ... code-gen and copy files to source ...
# this will call setup.py::setup, to make things extra confusing
return setuptools_build_sdist(sdist_directory, config_settings)
I had to create a temporary MANIFEST.in file to make sure that the setuptools
build_sdist saw the generated files. Maybe there's a better way?
I think the wheel "just" packages whatever the sdist produces, though that might be more difficult if you're compiling .so files or whatnot.Still overall pretty fiddly/under-documented and a shame there seems to be a push for more dependencies rather than encouraging users to build their own solutions.
More info in PEP 517: https://peps.python.org/pep-0517/
[ my other public key: https://keyoxide.org/DF564BCA14402C4D550E10FF9D3BC88718FB4D14 $2a$11$hK.oSfvqEJGRylzOeN6Pmu7kQzaCSE4rrLHKK3WBU.Iv50T4oqCF2 ]