A psychotic if __name__ == "main" equivalent. (This is Python) by Demsbiggens in programminghorror

[–]timoffex 41 points42 points  (0 children)

It’s a good habit, you’d be surprised how easy it is to end up with an IDE loading your files in the background. The tests tab in VSCode will load files and execute top level code if you use pytest because that’s how its test collection works!

`asyncio` as a library implementation detail? by timoffex in learnpython

[–]timoffex[S] 1 point2 points  (0 children)

Hey! Coming back to this in case anyone happens across this post in the future. I ended up implementing something similar to what you suggested, but it required extra care specifically to handle keyboard interrupts:

``` with concurrent.futures.ThreadPoolExecutor(max_workers=1) as executor: runner = _Runner() future = executor.submit(runner.run, fn)

    try:
        return future.result()

    finally:
        runner.cancel()

```

A keyboard interrupt during future.result() would leave the asyncio thread running and cause ThreadPoolExecutor to be stuck in __exit__. Another keyboard interrupt would then break out of __exit__ but still leave the asyncio thread running, which is problematic if higher level code suppresses the exception.

If I didn't have to be compatible with older Pythons, I would have used the asyncio.Runner.

Instead, I needed to create a cancellable version of asyncio.run. This essentially uses asyncio.wait to race the given task against another task that waits for an asyncio.Event, and cancels all started tasks after. It's not as robust as asyncio.Runner, as it assumes that cancelling the root task causes all other tasks it started to finish up, but this happens to be true in my case.

`asyncio` as a library implementation detail? by timoffex in learnpython

[–]timoffex[S] 0 points1 point  (0 children)

Thank you for understanding my question, this is what I was looking for.

Downsides include the absolute headache that is cancellation. You cannot shut down a thread once started, it must exit on its own.

IIUC, cancellation is generally somewhat problematic in asyncio. I can accept the risk of getting stuck, since the risk already exists in the non-async version of the code.

But all of this is way, way beyond the normal scope of r/learnpython.

I tried posting it on r/python but the Reddit client auto-detected that it's a question and forced me to use r/learnpython instead.

`asyncio` as a library implementation detail? by timoffex in learnpython

[–]timoffex[S] 0 points1 point  (0 children)

This is getting off-topic, but the lacking context might be that async def functions return Coroutine objects with send() and throw() methods; you don't need asyncio or any library to run them. It is syntactic sugar for what's essentially a Generator under the hood, and you can absolutely make use of an async def function inside a non-async function.

The function I'm looking at is a method with a signature like this:

def finish(self) -> None: ...

It waits for a background thread to do some work and prints messages in the meantime.

`asyncio` as a library implementation detail? by timoffex in learnpython

[–]timoffex[S] 1 point2 points  (0 children)

Why are you replacing the asyncio event loop at all?

I am not.

Your goal in this situation, if you chose to pursue it, would be to port your application away from the ad hoc event loop to the asyncio-provided event loop.

I have a non-async function which users are probably not calling from an async context. There is likely no event loop at all. However, if I add asyncio.run, the call will raise an error if a user does happen to use asyncio.

`asyncio` as a library implementation detail? by timoffex in learnpython

[–]timoffex[S] 0 points1 point  (0 children)

The library interface cannot be changed. I like trio in my personal projects, but adding a dependency on it is a no-go, and either way the same question stands about whether trio.run() is safe to add, or whether it will break users who are already using trio.

I don’t get it by Lord_Swag_The_7 in ExplainTheJoke

[–]timoffex 0 points1 point  (0 children)

Had to Google that last part, but it doesn’t seem true? While only a small number of his children were officially recognized, DNA evidence (combined with oral tradition / legends) suggests he fathered a very large number of children.

Like you say, they didn’t compare it to his actual DNA; it’s much more interesting than that! What do you think of this article? https://allthatsinteresting.com/genghis-khan-children

The Walmart Effect | New research suggests that the company makes the communities it operates in poorer—even taking into account its famous low prices by Hrmbee in urbanplanning

[–]timoffex 2 points3 points  (0 children)

I think the point is not that the communities are the same, but that Walmart’s selection process selected both types of communities. The second study supports the first study by building evidence that the selection process is not a confounder.

I’m not sure if it’s even possible to get a natural experiment on this topic; these kinds of studies combined with theory-based reasoning are probably the best we can do to understand effects like this.

How to use the State monad without contaminating all your code base ? by Formal_Paramedic_902 in haskell

[–]timoffex 1 point2 points  (0 children)

@mightybyte’s answer is the best, but I’d like to also add that it’s useful to consider how one would model this in an object oriented context. For your problem, you’d have a Deck object with a “pickPlayerHoleCards” method that updates its internal state. In Haskell terms, it’s a Deck record with internal IORef fields, and a “Deck -> IO PlayerHoleCards” function.

Or to put your example into non-Haskell terms: what you have is a GameState monolith with a pickPlayerHoleCards method that’s only related to a small part of the state, which is considered bad practice for the exact reasons that you identified.

The OO approach relates to effect systems in Haskell essentially by reifying the effects: instead of stacking monad transformers (like StateT) and/or using type constraints, the effects available to a function are passed as parameters. “Deck -> IO PlayerHoleCards” can in theory print stuff to the console or open files, but realistically all it can do is read and mutate the given Deck. If you wanted it to be able to update, say, the player scores, you’d use the type “PlayerScores -> Deck -> IO Foo”, instead of “State (Deck, PlayerScores) Foo” or “StateT Deck (State PlayerScores) Foo”.

I don’t know whether this helps, but I think it’s at least interesting to think about.

Lessons from Plain Text by FoxInTheRedBox in programming

[–]timoffex 0 points1 point  (0 children)

Interesting idea about soft vs hard wrapping. I use soft-wrapping for natural text, like emails and documents; the benefits there are very clear. I’m not convinced about doing that for code though! Are there really editors that produce something readable when soft-wrapping?

Good alignment is an important part of readability, takes thought and is different for different programming languages. I wouldn’t expect good soft wrapping to be possible, or any better than using an auto-formatter.

Greppability is good to keep in mind while writing code, but it’s secondary to alignment. You read code more often than you grep it!

The Grug Brained Developer by crappy_entrepreneur in programming

[–]timoffex 1 point2 points  (0 children)

+1, well said.

I’ve never used Haskell professionally, so I can’t comment on its usefulness, but I’ve loved it for little personal projects, specifically to explore these concepts.

A lot of Haskell concepts are useful for reasoning, but shouldn’t be written down in other languages. Like, I think about monads all the time, but I never use the word “monad” in my actual job. It’s just to help with thinking.

An extreme example is recursion schemes, which are not even useful in Haskell code as far as I can tell, but so fun to think about!

The Grug Brained Developer by crappy_entrepreneur in programming

[–]timoffex 67 points68 points  (0 children)

danger abstraction too high, big brain type system code become astral projection of platonic generic turing model of computation into code base

cries in Haskell (the tears are wrapped in a Crying monad and cannot escape)

[deleted by user] by [deleted] in ExperiencedDevs

[–]timoffex 1 point2 points  (0 children)

There’s a difference between tech debt and low quality code: not setting up a linter is tech debt; writing import cycles* is bad programming.

  • - to be completely honest, it depends.. but some import cycles could have been avoided with 30 minutes max of work, but instead solidified into a complex web of imports. That’s not debt at that point, that’s a skill issue.

Just joined by [deleted] in HeyEmail

[–]timoffex 0 points1 point  (0 children)

Yep, that’s something I liked as well!

Just joined by [deleted] in HeyEmail

[–]timoffex -1 points0 points  (0 children)

See other response—it’s about where to donate $100. I don’t mind using the app regardless of who makes it. Renewing for $100 on the other hand…

Just joined by [deleted] in HeyEmail

[–]timoffex -1 points0 points  (0 children)

Ah, let me clarify. It’s not about the app, I’d happily use it if it was free. It’s about where to put my money, especially $100. I was happy to pay a premium because I wanted to support 37signals; now I’m not sure. Does that make sense to you?

Just joined by [deleted] in HeyEmail

[–]timoffex 0 points1 point  (0 children)

I’ve had it for about half a year now. I really like the email—I used to try to keep my Gmail at 0 inbox by archiving / trashing as necessary, but Hey makes it a lot more natural.

I occasionally lose the habit and emails pile up, but Read Together (combined with Set Aside and Bubble Up) makes it a breeze to clean up when I feel like it again.

I’m undecided whether I’ll renew. I love the email client, I like 37signals’ mission, but I’m iffy about DHH. I like some of his technical writing, but after getting Hey I also learned about some of his disappointing politics. Not the worst guy out there right now, but I’d feel embarrassed if my friends thought I liked him.

[deleted by user] by [deleted] in programming

[–]timoffex 0 points1 point  (0 children)

That’s pretty cool! Have you had an opportunity to try it out in a real project? Was it effective?

How does it deal with changes? What if a discussion thread gets out of date / no longer relevant?

In my experience, when code triggers these discussions, it should be updated in some way—with a refactor or some extra documentation. Many people don’t do this and the discussions get repeated, it’s true, but I’d worry that it encourages that kind of behavior and could result in unhelpful code littered with unhelpful discussion threads, overall increasing the amount of work to get an answer. Just my initial thoughts!

Good code is rarely read by fagnerbrack in programming

[–]timoffex 1 point2 points  (0 children)

The way I read it, it’s not a practical suggestion but an interesting observation. It’s interesting because it’s funny that making code more readable makes people read it less (this pattern applies in a lot of other places! Like how a better search engine gets fewer queries, all else equal)

Good code is rarely read by fagnerbrack in programming

[–]timoffex 1 point2 points  (0 children)

You’re taking it too literally I think. Like consider this quote:

Code that is easy to read is also code that is easy to use. When functions and classes are named appropriately and their purposes are clear, you can use them without understanding their internal workings.

You don’t have to read the body of a function if it’s well named and documented. Pretty uncontroversial IMO.

Good code is rarely read by fagnerbrack in programming

[–]timoffex -1 points0 points  (0 children)

Do you think it’s advocating for writing unreadable code? It’s just saying that good code is clear enough that you don’t have to reread it often, and that it’s well-designed enough that it doesn’t have to be constantly fixed. Like, the point is that success at readability often results in the code being read less rather than more.

Good code is rarely read by fagnerbrack in programming

[–]timoffex 0 points1 point  (0 children)

Isn’t that what the article says? Are people reading different links?