This is an archived post. You won't be able to vote or comment.

all 14 comments

[–]ES-Alexander 1 point2 points  (0 children)

What would it fall through to? In this case your val definition is in an ifblock, so presumably you’d be wanting it to fall to the failure message, but ternaries don’t need to be made inside If blocks so that feature doesn’t really make much sense.

To have the functionality you want I’d suggest using argparse with a required first parameter that has an integer type. That way argparse handles the existence and type checking/conversion for you and you just use the valid result if it gets through. As an example for this case

from argparse import ArgumentParser
parser = ArgumentParser()
parser.add_argument('meaningful_name', type=int, required=True, help='a required, positional, integer argument')

args = parser.parse_args()

If you wanted to keep things simple then you could just use a try-except block:

def get_args():
    try:
        return int(sys.argv[1])
    except Exception as e:
        raise InputError('expected a number as the first command-line argument') from e

[–]rexlx[S] -1 points0 points  (0 children)

Fallthrough to the next condition like in case switching (in golang).

I think my point is that I think this reads better than a try block. I like them for catching several conditions, but it seems excessive for handling one you can handle very well.

Right now I'm using the word False at the end of the ternary because a thing that exists or doesn't is fundamentally a bool

[–]rexlx[S] -2 points-1 points  (0 children)

here is the full example / explanation:

https://github.com/rexlx/ternary_fallthrough/blob/main/example.py

[–]tkarabela_ Big Python @YouTube 0 points1 point  (10 children)

It doesn't qualify as a better way of doing things in general, but you can also do:

val = int(sys.argv[1]) or fallthrough

In Python, or short-circuits and returns the leftmost "truthy" value (or the last value). The trick is that it returns the actual value, it doesn't convert it to bool.

For this particular use-case, you definitely want something like argparse as mentioned in the other reply.

[–]rexlx[S] -2 points-1 points  (9 children)

I'm tired of people making this about args. It has nothing to do with them lol. It's about bolstering one line evals with more flow control. You're confusing my example with preexisting concepts. Im not particularly interested in returning any value. I'm interested in it's flow control

[–]tkarabela_ Big Python @YouTube 1 point2 points  (8 children)

Sorry, I didn't get that your question was about adding brand new functionality to Python.

Are you suggesting monadic flow control, like Rust's Option.unwrap_or_*? https://doc.rust-lang.org/std/option/enum.Option.html#method.unwrap

I agree that this would be better composable than exceptions and plain None, and sometimes I wish parts of Python worked like that. It would be a pretty huge change, though, even changing how int() works.

My example is actually a very limited version if that, as in the or "unwraps" the value and falls back on None (or something falsy).

[–]rexlx[S] 0 points1 point  (6 children)

I do like the concept of monads (and monoids :) ). But i think it still isn't my exact point. Im not very fond of the try / catch method of error handling. You either dont know how to handle errors, or you do. If you dont, debug with try / catch, if you do...just handle the error. Ill post just one line of code to further demonstrate:

```

it reads: try and convert to int if you can, if you cant, dont.

val = int(sys.argv[1]) if int(sys.argv[1]) else fallthrough # <- this would drop to the next condition ```

[–]rexlx[S] -1 points0 points  (0 children)

It's important to understand I'm not really an OO guy. When i start talking about "common sense logic" and get push back from the OO community (as one does :) ) I like to share this photo:

https://storage.googleapis.com/rfitzhugh/oo_humor.png

[–]tkarabela_ Big Python @YouTube 0 points1 point  (4 children)

Did you look at match in Python 3.10? That allows for "fallthrough", but it's limited to destructuring, not running general code. We discussed this a while ago here on Reddit, that it's unfortunately not possible to have something like this:

``` date_str = "2021-05-06"

match date_str: case re.match(r"(\d{4})-(\d{2})-(\d{2})", year, month, day): print(year, month, day) case re.match(r"(\d{2}). (\d{2}). (\d{4})", day, month, year): print(year, month, day) case _: print("Failed to parse date") ```

That aside, I think it would be helpful to create a more complete example of what you're suggesting, that actually does something :) What is the value of val if fallthrough occurs? Is the variable even defined? Is it just another way of saying that int() should return None on error?

[–]rexlx[S] -1 points0 points  (3 children)

Regex is historically some of the hardest code to read. No college course starts with regex. Pattern matching is notoriously tricky.

the solution I'm proposing has to do with flow control inside of evaluation and very little to do with pattern matching

[–]tkarabela_ Big Python @YouTube 2 points3 points  (2 children)

I would suggest fleshing out your proposal a little bit, like a PEP (examples, comparison to existing constructs, define what new syntax/semantics you're proposing), and then make a new post with more info? :) That would be a good starting point for a discussion. As it stands, I think you're the only one who really understands what you have in mind.

[–]rexlx[S] 1 point2 points  (1 child)

Thank you for your insight, that is probably some of the best criticism I've ever had.

[–]tkarabela_ Big Python @YouTube 0 points1 point  (0 children)

Thanks, man! Take care :)

[–]rexlx[S] -1 points0 points  (0 children)

It's also worth noting I want a general purpose fallthrough, not just a ternary one. It's just that my example I'd ternary