#internals-and-peps

1 messages ยท Page 62 of 1

raven ridge
#

I think most core devs felt that making the insertion order preservation part of the language spec was the less bad of several bad options. It does add an extra constraint to future dict implementations in terms of backwards compatibility, but the alternative was that developers would be very likely to write code that depends on an implementation detail of CPython rather than a language guarantee, and result in tons of code that wouldn't be portable to other Python implementations.

#

they chose the one that's better for users and harder for the Python implementers.

teal yacht
#

@teal yacht the core devs decided it on the python-dev mailing list, just like they decide every other issue. There was a year between CPython dict becoming order preserving and it being added to the language spec.
@raven ridge Yes, but the thread itself where they finally added it was extremely short and derailed the conversation to pprint for whatever reason (it was an issue, but off-topic to that specific thread), a few people said they didn't agree but the convo moved on directly

flat gazelle
teal yacht
#

admittedly, all of this is a non-issue if the implementation doesn't change in the future or changes for another implementation that preserves order but idk, the benefits of adding it to the spec are so small imo

flat gazelle
#

it gets you a lot of neat code for dicts that did not work before. list(dict.fromkeys(some_list)) removes duplicates preserving order

raven ridge
#

a few people said they didn't agree but the convo moved on directly
@teal yacht I don't remember much disagreement, and I didn't notice any while skimming that thread. There was a lot of talk about what the implications of making this language change will be, but there weren't voices saying not to make that language change at all - maybe I missed the messages you're thinking of?

chilly zephyr
#

hello How do I make 2 diffrent classes 'talk' to each other? Im making a basic clicker game and I have 2 classes autoclicker and main,

#

and I want main to use autoclickers methods and autoclicker to use some methods from main

swift gust
#

question about cogs with that unload and load thing does that mean anyone in the server can unload one so the commands don't work?

radiant fulcrum
swift gust
#

oh sorry

paper echo
#

@chilly zephyr start by writing out your game logic. Usually circular/cyclical relationships between parts of your application are a bad sign

#

But in general there's no reason any method on an object can't call any method on any other object

chilly zephyr
#

I saw something about nested classes so Im trying this out

paper echo
#

I don't think that's a good idea

#

This also is probably better suited for a help channel

#

This channel is for discussion about the python language itself

#

If you post in help channel @ me, im at lunch now but maybe i can help later

slim island
#

On a conceptual level, you have lots of ways to get classes talking to each other - event listeners for example. But on a specific level, it boils down to calling methods or updating attributes of one class from another. For help with your specific problem, a help channel is best

unkempt rock
#

does anyone know how to turn off css/images for selenium?

#

using the firefox webdriver

radiant fulcrum
#

๐Ÿค” Why tho

unkempt rock
#

because it takes a lot of ram

#

too much ram

radiant fulcrum
#

Thats because you're litterally running a browser

#

Its going to use alot of ram

unkempt rock
#

and also that's not really a problem, so i didn't get a channel

radiant fulcrum
#

especially if you go to lots and lots of sites with it

#

just like a normal firefox tab

unkempt rock
#

yeah but disabling it can use less ram

radiant fulcrum
#

CSS really isnt gonna be the thing increasing ram

#

not by any noticable amount

#

If you dont need JS support just use requests to get the html

magic python
#

I've been under the impression that importing within functions is unadvised, but i bump into it now and then

#

is there a consensus on whether this is alright / when to do it? I don't see why argparse can't be imported at the top of the script there

#

In seaborn there's an import of bs4 within a function, but that's because it's not a core function (it's to grab datasets), so I kinda get that

radiant fulcrum
#

I would only do it if you dont want it imported on certain things

#

e.g

#

Uvloop for example

#

cant be installed on windows but you want the program to still work with windows

magic python
#

any thoughts on the example I linked? I'm not familiar with UVloop :S

radiant fulcrum
#

so you would have a condition that only imports it if its a unix based system not windows

teal yacht
#

You can put your imports in a condition tho

#

It's not that uncommon

radiant fulcrum
#

you would rarely do it with functions

#

because of scope

teal yacht
#

Importing inside functions imo is a big no-no, there's very few benefit, and it makes the code harder to maintain, and IDEs won't like it

magic python
#

so - argparse here should be imported at the top in your opinions?

radiant fulcrum
#

yes

magic python
spice pecan
#

might as well, yeah

magic python
#

hrm ok, cool, that was what I thought but I bump into it sometimes and assume they know something I don't

radiant fulcrum
#

all your arguments aswell can be top level

teal yacht
#

this is why more people should use __main__.py :]

radiant fulcrum
#

they're only processed when you actually call parse

magic python
#

@teal yacht what do you mean - use it in what way ๐Ÿค”

#

I notice they don't have one, but often I've seen them and they've just been empty

teal yacht
#

they're importing it in the function because it's only when it's used as a standalone program

#

empty __main__.py ?

#

you sure you're not thinking of __init.py__ ?

magic python
#

yeah I think so ๐Ÿค” maybe that's init, yeah ๐Ÿคฆโ€โ™‚๏ธ

radiant fulcrum
#

Has anyone got MyPy working with Pycharm?

magic python
#

odd that this is still in there, as there have presumably been a few eyes on it and it's an easy fix, all good tho

teal yacht
#

pycharm uses its own type checker iirc, not sure if you can configure it

radiant fulcrum
#

you can configure the type hinting and stuff

#

Im trying to work out how df you use this plugin for it

magic python
#

i've finally got neovim working in a semi sensible way :')

teal yacht
#

to be fair, I understand why they might want that @magic python, it avoids import unnecessary packages in the case you're not running it as a program but importing directly

magic python
#

@teal yacht right - is it "not by the book" but makes sense in practice? That sort of thing

teal yacht
#

i'd personally just make it a package with one file + a separate entry point but that's just me i guess

magic python
#

i've not really got entry points and stuff yet

teal yacht
#

yeah, you'll always see recommendations to put imports at the top but in that case it's ok-ish imo

#

__main__.py sorry

pearl river
#

@radiant fulcrum The plugin wasn't working for me for some time, spewing gibberrish in the wrong encoding in the console, and then it just started working after an update ๐Ÿคท

teal yacht
#

to differentiate when you import the package vs run it as standalone

magic python
#

@teal yacht I've used this in the way of having a __main__.py that calls another script, and i then run the package that they're both in with python -m project.package and it seemed to work

#

all __main__.py did tho was import run and call run.main() which returned a sys argument

teal yacht
#

that's one way of doing it yea

#

I personally prefer to put the code directly in the __main__.py, not that it makes a big difference

magic python
#

yeh, i never have anything in init.py but see some people put loads in there

#

I never really know what is meant to go where ๐Ÿ™ƒ

teal yacht
#

oh, no, most of the time __init__.py will still be empty

magic python
#

all __init__.py means to me is that i can import things from there

teal yacht
#

__main__.py is a separate thing, if it exists, it is what is ran when you do python -m foo.bar

magic python
#

yeah, where bar is the directory , main is handy for that, i don't make much use of it tho really other than what i mentioned before

boreal umbra
#

Why is dunder main a separate thing instead of having dunder init be the entry point for -m commands? I guess because dunder main only gets run if you do a -m command?

north root
#

yep

#

__init__ and __main__ are two different things. __main__ is only run when you use the -m flag.

#

__init__ is always run

boreal umbra
#

But it's only like that for the directory level module

#

Unless my programs are working for reasons I don't understand

tawny shoal
#

I drafted a more expressive API to create regular expressions in Python (this is just a concept):

import regexpressive as rex


my_text = "texttexttext Name: Guido moretext"

regex = (
    rex.Regex(case_insensitive=True, multiline=True)
    + r'name: '
    + rex.Group(
        rex.Multiple(
            rex.WORD_CHARACTER
        )
    )
)
# compiles itself automatically the first time it is used
# and keeps the compiled regex internally

name = regex.search(my_text)[1]
#

regexes are super intimidating to beginners, which is a shame because they'd be so useful in solving problems that beginners are often interested in solving when trying to get familiar with Python.

#

This is an idea that could help with that.

spark magnet
#

I've seen other projects like this. They don't seem to get wider use.

tawny shoal
#

The regex described in the code translates to r'name: (\w+)'

spark magnet
#

"regexpressive" is a good name ๐Ÿ™‚

teal yacht
#

It's used a fair bit in emacs through the name rx
Another (way better imo) approach is called parser combinators

tawny shoal
#

I'm not surprised; I've honestly been baffled by the fact that re as it is exists in the Python standard library because regexes as they are aren't very pythonic I feel like

teal yacht
#

It's such a widely spread tool, you can't not include it

tawny shoal
#

Yeah; what I'm trying to say is that I'm surprised that there is no more friendly API to compose and use regular expressions in Python.

#

Python specifically tries to get rid of the amount of special characters in code that other languages suffer from, yet it makes you write regexes by hand

teal yacht
#

You should look into parser combinators, it's really interesting, and can be used to parse CFGs, not just regular grammars too

tawny shoal
#

I will definitely look into that, got a link ready? I'm not sure where to start ๐Ÿ˜…

teal yacht
#

I have several, but they may not be useful depending on whether you know the language or not

#

parsec and its derivatives in haskell are great, but the code is gibberish if you're not used to it, i'm sure we can find a simple implementation in python somewhere on gh

tawny shoal
#

I only know Java, Python and Rust, and some C, enough to port Python to a different platform ig ๐Ÿ˜…

#

Oh that looks good

#

Looking at that example code is oddly satisfying, but I could not describe why ๐Ÿ˜„

teal yacht
#

you should look at some parsec code

tawny shoal
#

If I understand correctly, this can help me create an API such as the one I described, right?

teal yacht
#

I'd say this is a generalization of what you were doing, thought you could at least take some inspiration from it

tawny shoal
#

Ohh, yeah I see what you mean!

teal yacht
#

Again, it's a generalization, it can do more than what regexes can

#

So that may be a bit more complex i guess

#

Even tho I'm not sure how exactly, it's basically building a state machine through functions

tawny shoal
#

It's definitely good to look at approaches to solving very similar or even more general problems to understand how to solve my problem

#

Thanks again for showing me this :) It will probably help me get there if I do decide to bring this project to life

teal yacht
#

I think I should mention the core idea of parser combinators is to have function that takes one or more parsers as input and return another parser as output, so you can have like

foo = Parse("foo")
bar = Parse("bar")
baz = Parse("baz")
foo_or_bar = foo | bar  # or like Or(foo, bar) if you don't like operators
foo_or_bar_followed_by_baz = foo_or_bar >> baz  # could be .then(...)
```etc
tawny shoal
#

hmm

#

I'm not sure why I would combine parsers since I'm only parsing regular expressions ๐Ÿค”

#

Yeah, right, I'm just building a regex string using the builder pattern, really

#

It's cool to know these thimgs though as they're somewhat related

#

I've seen other projects like this. They don't seem to get wider use.
@spark magnet If you don't mind me asking, can you recall one of them at least? I'd be interested in seeing how they did it

teal yacht
#

I was just googling that, and I found one

tawny shoal
#

Ah I see

#

VerEx is actually close to what I wrote, but unfortunately falls short in versatility and readability

#

don't think .find(string) is a good design choice

#

It's actually just + r'text'

#

in the API I described above

#

oh right

#

that's a lot of groups lol

#

in fact nothing is not in a group there

#

idk if I like that

#

probably better to have a string concatenation-like API

#

because that's what's happening under the hood anyways

#

which means the API would feel less like a black box

#

Just had a different idea:

import regexpressive as rex


my_text = "texttexttext Name: Guido moretext"

pattern = (
    r'name: '
    + rex.group(
        rex.multiple(
            rex.WORD_CHARACTER
        )
    )
)

regex = rex.Regex(pattern, case_insensitive=True, multiline=True)
# compiles itself automatically the first time it is used
# and keeps the compiled regex internally

name = regex.search(my_text)[1]
#

a functional design

unkempt rock
#

Guys this is a weird question but could I code something in python that would draw a non commutative ring from an equation like this

tawny shoal
#

It is similar, but works differently

unkempt rock
tawny shoal
#

I think you wanna use a help channel for that Matty

#

It is similar, but works differently
This time around I'm explicitly expecting the user to compose a pattern string to pass to rex.Regex

#

That way I am even more transparent about how things work, but also need the user to understand a little bit more

#

It does feel like just the right balance though

#

in fact it feels so easy to implement I am sure this has already been done

#

Yeah; that there is a pattern string

#

There might not be any real difference actually

#

Yeah they sure are

#

Though this is for Python :p

#

It feels like Click's style

#

Simple is better than complex

#

Yeah, I think what we got now is a really good design

#

just the vibe I'm getting

#

Yeah,,,, I think differently about code ig

#

Couldn't explain what I meant if I tried

#

I guess it has something to do with the functional nature that both the code I sent above and click.style share

torpid narwhal
#

I've been researching more into different concurrency models, and it seems python is able to implement multiple versions. Yeah, there is asyncio, but the concurrent.futures library has the classic primitives of threads and processes and you have libraries like ray that implement the actor model.

In comparison to a language like golang that favors CSP via channels and goroutines built into the language, is Python at a disadvantage since concurrency/parallelism was an after thought until recently?

For the record, I do admit a bit of recency bias after reading the book "Seven Concurrency Models in Seven Weeks" and using the actor pattern a lot at work.

(Fun aside: I think subinterpreters are interesting because they communicate CSP-like from what I can tell. I think that is cool to be an awesome game-changer when they come out.)

tawny shoal
#

That is correct, Python is indeed at a disadvantage because of that

#

but the main reason why Python is at a disadvantage when it comes to concurrency is the GIL

#

To cut it some slack, it's actually not that much of an afterthought, but due to certain design decisions Python was not thought to be or become extremely parallel for a long time

#

That is as much as I know

torpid narwhal
#

Oh....I am not a GIL hater like some out there. For many things I deal with, the GIL isn't much of a problem. Either I need to be a better coder or write my stuff in C/C++/Cython.

#

I just don't know if being a "jack of all trades" in async stuff is "better" for development and use instead of golang's model being the "one and primarily only one" way of doing things.

tawny shoal
#

Different concurrency strategies work (better) for different problems methinks ๐Ÿค”

torpid narwhal
#

Also, one of the biggest proponents of CSP was on the core team that built go. so...

#

I appreciate the heavy lifting into the asyncio stuff, but the apis still feel a bit clumsy in comparison to working with Node and doing async/await stuff.

raven ridge
#

it is still a bit of a second class citizen - the fact that Python supports multiple concurrency paradigms is from one perspective an advantage, since it lets users choose the one that seems easiest for their current problem, but the fact that there are a mix of blocking library calls and library calls that expect to yield to an event loop means that the user freedom goes hand in hand with some extra complexity.

torpid narwhal
#

Basically entrusting that the dev(s) can make decent decisions.

raven ridge
#

and can understand why, for example, there's an asyncio.Queue and a queue.Queue that behave differently.

modern frigate
#

is it ok if i understand like nothing

#

that you guys are talking about

#

lol

tawny shoal
#

I appreciate the heavy lifting into the asyncio stuff, but the apis still feel a bit clumsy in comparison to working with Node and doing async/await stuff.
@torpid narwhal I fully agree and wish something like trio would've made it into the stdlib instead

#

@modern frigate You'll get there :)

raven ridge
#

This channel is specifically for discussions about Python itself, at the level of the language and its design choices.

#

it won't be for everyone. ๐Ÿ™‚

torpid narwhal
#

@raven ridge Yeah, that is annoying.

modern frigate
#

ah lol. looking bad, i guess i do get some of it, but still confused hehe

torpid narwhal
#

And, I fully admit this is way higher level stuff. I basically have been in a deep dive in concurrency models the last few days.

#

@tawny shoal Why trio?

tawny shoal
#

Because I really like its DX (developer experience) and its API design feels very elegant

raven ridge
#

trio is definitely worth checking out. It uses the same language features that asyncio is built on top of, but builds abstractions that are more high level.

tawny shoal
#

far less clumsy than asyncio at least ^^

#

I still remember asyncio.coroutine, that was wild

#

Tysm Yury for blessing us with async/await

torpid narwhal
#

yeah. There are very few times where I will put Node above Python, but I would rather deal with promises and async/await than Python's async/await and asyncio. I will check out trio.

radiant fulcrum
#

I'm pretty sure python's async system technically isn't a promise system under the hood

#

Js has it like that just as synactic sugar for the promise system

#

Python's system is based of generators mainly and the coroutine system

#

One of the things that put python at an advantage other alot of things is the asyncio event loop

undone hare
#

Well, most languages have an asynchronous framework

wide shuttle
#

!tempban 678484214311682130 1d Please get you act together

fallen slateBOT
#

:incoming_envelope: :ok_hand: applied ban to @glad crow until 2020-08-04 10:32 (23 hours and 59 minutes).

radiant fulcrum
#

How come MyPy lints this: Mypy: Incompatible types in assignment (expression has type "Optional[str]", variable has type "Tuple[Optional[str]]")

#

when doing

#

self._host = host where host is a string

languid dagger
#

Probably more fit for a help channel, depends how self._host is declared

radiant fulcrum
#

Im just trying to work out How mypy or strict typed python classifies the types

gloomy rain
#

Looks like self._host is a tuple.

radiant fulcrum
#

Its seems its linting it as a tuple just via a standard type hint

#

host: str = "127.0.0.1", to mypy seems to be Tuple[str] which doesn't make much sense considering the Python doesn't directly deal with strings a u8 vectors no?

brave badger
#

You seem to have a stray ,

radiant fulcrum
#

its part of a larger parameter section

brave badger
#

That's odd

teal yacht
#

this really looks like a trailing comma

radiant fulcrum
#

I mean typing it as MyPy expects it being Tuple[str] i dont mind much but it seems weird that it identifies it as that

languid dagger
#

That's host the mypy is referring to self._host being a tuple

gloomy rain
#

@radiant fulcrum Show some more code.

languid dagger
#

The expression is host and the variable is self._host (in the error message)

radiant fulcrum
#

You know i think ive worked out why its doing it

teal yacht
#

would help if you posted the function

radiant fulcrum
#

I left the doc string describing it as Optional[:class: str]

teal yacht
#

mypy doesn't use docstrings

#

unless you're using like python<=3.4

radiant fulcrum
#

3.7

#

this is the chunk its complaining at

teal yacht
#

you have trailing commas

radiant fulcrum
#

yes

#

because its part of a function

teal yacht
#

        self._host = host,
        self._port = port,```
#

?

radiant fulcrum
#

wait

teal yacht
#

this makes self._host a tuple

radiant fulcrum
#

fuck

#

bruhh how did i not notice that

gloomy rain
#

That's one of those muscle memory reflexes you develop after a while. When you start getting unexpected tuples, look for stray commas.

radiant fulcrum
#

Ive been switching between Rust, Go and python non stop for the last few weeks so everything is all over the place

teal yacht
#

that being said, i'm curious, can you post the command you run with mypy

radiant fulcrum
#

Ive had alot of stray := and let's all over the place

tawny shoal
#

I feel that haha, glad you found it at least :)

radiant fulcrum
#

@teal yacht Im just using the MyPy extension for pycharm

#

it lints it in the background and then highlights accordingly

teal yacht
#

I was certain mypy cannot use docstrings ๐Ÿค”

radiant fulcrum
#

some of it is PyCharm making use of them

languid dagger
#

It doesn't. My guess is the error message was referring to the run function that was written correctly, but in the __init__ self._host was set to a tuple

radiant fulcrum
#

yeah

teal yacht
#

yeah i just looked, it's pycharm's builtin type checker

radiant fulcrum
#

the trailing , at the var defines

teal yacht
#

they call it "legacy type syntax for docstrings"

languid dagger
#

Also is mypy different? Because I thought Optional meant that None could be provided as a value

teal yacht
#

that's how mypy does it

#

same as Union[None, T]

radiant fulcrum
#

Its me not doing it properly

teal yacht
#

the optional is only specified in the docstrings, so it looks like it's somehow passing the docstring types to mypy

radiant fulcrum
#

i dont normally strictly type so much in python compared to Rust and Go which have it by default

#

trying to get into the habbit of strictly typing py aswell

paper echo
#

^ like i tell people, strict annotations prevent a whole class of errors

#

At the cost of having to occasionally use typing.cast

grave jolt
#

sometimes assert helps avoid cast

paper echo
#

Mypy is smart enough for that?

#

We need a python type checker shootout

#

Speed, user interface comparison, intelligence/cleverness, correctness

teal yacht
#

mypy checks asserts and conditionals

#

if they contain isinstance or type(x) ==

paper echo
#

Is that a mypy feature or part of the language spec

teal yacht
#

the language only includes support for type hints and the typing module really, theoretically, type checkers can implement whatever they want based on these type hints, but afaik, all the relevant type checkers implement that

paper echo
#

Right

#

Interesting

paper echo
#

How do non-functional but strictly typed languages handle this?

#

C isnt a good example because the type system is kinda loosey goosey

#

Too low level

#

Or do you basically need monads to make this work without complicated inference and/or casting

teal yacht
#

How do non-functional but strictly typed languages handle this?
@paper echo what do you mean by "this"

paper echo
#

input accepts one of 2 types, somewhere along the line one type gets cast to the other

teal yacht
#

fwiw, hindley milner is a type system capable of global type inference and it's scandalously trivial

paper echo
#

of which a special case would be Optional[A]

teal yacht
#

referring to the "complicated inference", but i see this is not what your question was

paper echo
#

yeah ive heard that term, i need to look up how hindley-milner inference works

#

by complicated inference i mean "figuring out when the programmer has asserted or cast the type of a variable"

#

because checking for isinstance is kind of crude heuristic no?

teal yacht
#

you can loosen up the constraints on the argument's type, there are multiple ways to do it, typescript does it using typeof to basically infer the type based on conditions, exactly like mypy, or we can use a subset of what would look like structural subtyping, but the N types will need to share attributes/methods, in the same way we would declare generics, except constraining it to N specific types

paper echo
#

i see

teal yacht
#

one day structural subtyping with global type inference will be the standard

#

so we can finally have true static duck typing

paper echo
#

what do you mean by "global" type inference, as opposed to any other kind of type inference?

teal yacht
#

as in you don't need any kind of type annotation, unlike for example c++'s auto which only works locally

#

like you can have

def foo(x):
  return x.y + 1```and the type could be like
```ocaml
val foo : <y : int; ..> -> int```
paper echo
#

ahh. i forget what language i was looking at with that feature recently, maybe F#

teal yacht
#

any ML, ocaml, standard ml, f#, as well as haskell like languages

flat gazelle
#

Elm, purescript, haxe can do that

#

Haskell cannot

teal yacht
#

yes it can

paper echo
#

isnt the problem with python that basically anything can return any type at any time, and if you dont annotate then python cant infer anything

flat gazelle
#

well, with generic it can I guess.

teal yacht
#

haskell uses a superset of hindley milner, which already supports global inference

flat gazelle
#

yes, but haskell records do not work such that a function like f x a = x.y + a can have an inferred type(or be made at all)

teal yacht
#

oh, right right

flat gazelle
#

inferrence to varying extent is present in most modern statically typed languages, e.g. Rust, kotlin, swift, scala. It is not full ML/Haskell inferrence, however

teal yacht
#

yeah, i'm glad it's becoming more recurrent, despite the communities adopting them with varying degree

grave jolt
#

even C++ has some inference with auto

#

but it won't be able to adopt full inference because of how coercion and overloading works

hidden osprey
#

Oh yeah

#

Makes sense

#

Hello?

subtle pike
#

huh?

green phoenix
#

This might be a silly question but has anyone tried writing a borrow checker for python like the one in rust? Or maybe tell me why that's impractical?

teal yacht
#

I highly doubt it, that'd imply a reimplementation of python minus the gc, + some extension to the syntax to make it support hints for lifetimes, there's also the issue that current implementations are commonly based on affine types, that is, lifetimes are encoded within the type system directly, that would assume static typing too

#

So while you could do something that looks like python superficially, it wouldn't really be fair to call it python anymore

radiant fulcrum
#

there would be no point of borrow checking

#

Its a garbage collection based lang

#

Borrow checking can also Decrease development speed dramatically which removes one of the biggest selling points of python

green phoenix
#

Thanks, yeah

undone hare
#

Of course that wouldn't be possible because it would be a hell of a breaking change, but if it was possible, would you prefer to import the standard libraries like it is done now (import random), or having them prefixed with python. (import python.random)? This would make it more obvious if a package more obvious if it is in the stdlib or not, but it would be a bit more typing in the import statements

spice pecan
#

I don't think it's necessary, but it does make sense to put all the standard modules into a package, perhaps not python but something like stdlib

#

from stdlib import random, for example

languid dagger
#

Part of the import structure is to search installed packages/modules if it fails to find locally (cwd)

spice pecan
#

something like that should prevent standard libraries from being overshadowed by local files, I guess

#

or at least for as long as there is no stdlib package/module present locally, which I can't see happening often

peak spoke
#

The current system does lead to cleaner imports, and makes backports somewhat nicer to use

zealous oriole
#

what does reversed(list) do under the hood? is it similar to list[::-1]

spice pecan
#

it's an iterator that just goes through the list in reverse storing indices

undone hare
#

It probably does the same thing yeah, but with something similar to a range

#

It is implemented in C

spice pecan
#

[::-1] generates a reversed slice immediately, while reversed will return values lazily

torpid bridge
#

Yes

undone hare
#

Indeed, that's a generator

zealous oriole
#

how would you recreate reversed

#

the concept at least

spice pecan
#

it keeps the last valid index known at creation time and then goes down from that to 0

torpid bridge
#

You could reimplement it in python like this:

def reversed(iterable):
  total_items = len(iterable)
  current_item = total_items - 1
  while current_item > 0:
    yield iterable[current_item]
    current_item -= 1
spice pecan
#

(I think to 0, not sure)

radiant fulcrum
#

list indexing starts at 0 so probably

zealous oriole
#

You could reimplement it in python like this:
def reversed(iterable):
@torpid bridge what do u put under the function

torpid bridge
#

hit enter early

#

Well, sort of

#

there's more detail, like searching for __reversed__

zealous oriole
#

wouldn't making all those variables take up unnecessary memory?

torpid bridge
#

gotta keep track of them somewhere

spice pecan
#

less memory than generating a reversed copy of that list

torpid bridge
#

^

#

that's the general tradeoff between [::-1] and reversed()

#

do we keep track of our place and scroll backwards as you want items? or do you just flip it now and be done?

zealous oriole
#

the former

torpid bridge
#

In all honesty, the memory consumed by two ints is very small and unlikely to make a difference

zealous oriole
#

u sure?

#

what is the official code behind reversed

#

do you know?

torpid bridge
#

yes, python has a max index size of... 64 bit I think

zealous oriole
#

lol

#

reversed_meth

#

nice variable name

#

also bast

#

do you know how to use pypy3 in windows cuz apparently python is "slow" compared to languages like c++

torpid bridge
#

"in window"?

#

windows?

#

I mean, yes, it's "slow" in comparison. But that's short perspective

#

It can still do > 1million things per second

zealous oriole
#

well c++ does more then

radiant fulcrum
#

Python is about 100x slower than C

#

PyPy is a JIT compiler for python

torpid bridge
#

pypy provides windows binaries

zealous oriole
#

yes thats why i wanna know how to use that

radiant fulcrum
#

which speeds stuff like looping up considerably

#

However you dont get much support for C based libs

peak spoke
zealous oriole
#

its recommended for competitive programming if u wanna use python

#

which is a minority of the people

torpid bridge
#

just install it, and run your code with it

#

same as regular python

zealous oriole
#

you cant install it tho?/

radiant fulcrum
#

only if you are doing long tasks

zealous oriole
#

u get a zip right?

radiant fulcrum
#

if its short tasks pypy is slower

#

also no?

#

oh yes

#

another important note

torpid bridge
#

pretty sure it runs with pypy myfile.py

zealous oriole
#

pypy is not recognized by cmd tho

radiant fulcrum
#

PyPy on windows when you install it will use your highest PATH set python version for the std libs

zealous oriole
#

i dont know how to set it up properly

torpid bridge
#

maybe pyenv works on windows (answer: not really)

radiant fulcrum
#

So i had Python 3.8 highest just under Intel py which ment PyPy inherited the 3.8 packages which isnt ideal

zealous oriole
#

anyways

#

should i learn c++

torpid bridge
#

Try what you're trying in python

#

if python isn't fast enough, take what you learned and write it in rust

radiant fulcrum
#

C++ is a very hard and annoying language to get used to

zealous oriole
#

why rust?

torpid bridge
#

and you can use PyO3 to make a python module for it

radiant fulcrum
#

because Rust doesnt fuck you

torpid bridge
#

because in rust, if you want to install a package, it's cargo install package

radiant fulcrum
#

C++ has alot of weird and wonderful things and does (I think) manage memory safety or thread safety for you

torpid bridge
#

in c++ if you want to install a package, the answer is start praying

#

also, compiling? cargo run

#

c++? praying, again

radiant fulcrum
#

not to mention the bloat machine needed on windows for build tools

torpid bridge
#

another reason why I like python. python myfile.py

zealous oriole
#

does python plan on supporting manage memory safety or thread safety for you

torpid bridge
#

yes

radiant fulcrum
#

Python does

torpid bridge
#

reference counting does the first

#

and the GIL and multiprocessing does the second

radiant fulcrum
#

Python is garbage collector Lang and GIL

zealous oriole
#

what if i wanna game develop

#

still python?

radiant fulcrum
#

probably Not

torpid bridge
#

depends

zealous oriole
#

or godot

torpid bridge
#

There are games in python, and IIRC Civ 4 was written with python for scripting

radiant fulcrum
#

Main engines Like unreal are C++ or C# in some cases

spice pecan
#

C#/C++ would be better options for gamedev

zealous oriole
#

aaaaaaaaaaaaah

torpid bridge
#

you will likely hit pain trying to write the graphics code in python, but that's to be expected

undone hare
#

If you are an artist, yes, otherwise probably not

zealous oriole
#

pain

#

so i guess ill have to start learning it then?

undone hare
#

Actually, it isn't harder in python

torpid bridge
#

If you want to update every pixel of a texture multiple times a second, it's simple rust code or numpy fun in python code

radiant fulcrum
#

What i would say

zealous oriole
#

"fun"

radiant fulcrum
#

if youre gonna do C++

#

dont use windows to dev on it

undone hare
#

Libraries like ModernGL makes integrating OpenGL really easy, like in any other language

radiant fulcrum
#

just dont put yourself through that pain

undone hare
#

The actual issue is sadly speed

#

CPython isn't fast enough for game dev

zealous oriole
#

dont use windows to dev on it
@radiant fulcrum wdym

#

is rust similar to c++ in terms of speed

#

and functionality

torpid bridge
#

Yes

#

It's got identical speed, and in some cases more, some cases less functionality

zealous oriole
#

so i can game dev with it?

torpid bridge
#

Yes

zealous oriole
#

i see

radiant fulcrum
#

you can do game stuff in rust there just isnt much support for it atm

#

tho i wouldnt be supprised if stuff came out in the future

peak spoke
#

Real gamedev from you alone will probably depend on a game engine that already exists, limiting your language choice to whatever that uses. You can create an engine with a bit of effort but it won't come close to the toolset already existing commercial engines provide

zealous oriole
#

is rust new or old

torpid bridge
#

From my experience, it's really just the 3d stuff that's painful at the moment

#

new

zealous oriole
#

like newer than python?

torpid bridge
#

much

peak spoke
#

Python is very old

radiant fulcrum
#

Rust is only 10 yrs old

zealous oriole
#

so if i had to start learning a language, c++ or rust?

radiant fulcrum
#

rust

torpid bridge
#

python 2 was started in 2000, and rust started 10 years after

radiant fulcrum
#

Its just a more enjoyable experience

zealous oriole
#

would rust do well in competitive programming

radiant fulcrum
#

Very

#

Rust is one of the fast languages around at execution speed, equal to C++ if not faster in cases

zealous oriole
#

but why do the majority still use c++ then

radiant fulcrum
#

because C++ is donkeys years old

#

C++ has been around for wayyyyyy longer than Rust has

torpid bridge
#

C++ is from 1985, rust is from 2010 and gained proper async stuff.. 6months to a year ago?

radiant fulcrum
#

and only in the recent Years has Rust gained popularity since pre 1.x was a reallly painful experience

zealous oriole
#

ok so rust is a good choice then

#

off to youtube tutorials

radiant fulcrum
zealous oriole
#

?

radiant fulcrum
#

what this dudes tutorials^^

#

He goes over the concepts that you Need to know when doing rust to get anywhere in the language

torpid bridge
#

Considering how PyO3 intergrates rust and python pretty well

radiant fulcrum
#

otherwise you will be clueless to whats going on around

torpid bridge
#

I don't think it would be strange the blend them

#

One thing you'll run into with rust is it requires you to know what you want to do very precisely

#

python is much less restrictive on that front

#

C++ pretends to be less restrictive, but it really isn't

radiant fulcrum
#

it just dicks you later on

#

instead of telling you upfront

visual shadow
#

Does c++ have ub?

#

Undefined behaviour *

torpid bridge
#

Rust: no, you can't do that
C++: You can do that sharpens knife
Python: sure. Also, I'll make sure that doesn't bite you later by keeping your stuff together for you

radiant fulcrum
#

Go is also a pretty fun language tbh

#

Its basically a compiled strictly typed python

torpid bridge
#

Go has warts

#

and this is getting a bit off topic

radiant fulcrum
#

the only issue is you really are stuck without any low level stuff or and C compatibility

visual shadow
#

Go seemed a bit bland, vs python.

torpid bridge
#

I can understand why they didn't go with try/except

radiant fulcrum
#

I like it tbh, tho ive gone back to rust again after switching for the last 7 times

torpid bridge
#

I cannot understand why they went with if err != nil

radiant fulcrum
#

overhead ig

torpid bridge
#

literally, something like 15% of all go code is that line

slim island
#

I feel like discussion of Go/Rust is OT for this channel - but Go's exception handling is very nice, it's much cleaner than try/except I feel - try/except really doesn't add all that much utility vs Go's method

radiant fulcrum
#

I do prefer Go's methods for EH

torpid bridge
#

Meet you in #ot2?

zealous oriole
#

yes

paper echo
#

when you write ProcessPoolExecutor.submit is the data for the work sent to the process right away?

#

or is it "held" in the calling process until the executor is ready?

#

wondering about overhead of big multiprocessing jobs w/ ProcessPoolExecutor.submit + as_completed as opposed to Pool.imap_unordered

vernal turret
#

If I'm understanding it correctly, then it looks like the data is "held" in the calling process.

paper echo
#

interesting

#

in the calling process, but a separate thread

#

nice find

#

so potentially there is additional process spawning overhead compared to Pool methods with the chunksize param

#

i just wish there was imap_unordered with executors, so i could use tqdm for a results progress bar but still have the option to use chunksize ๐Ÿ™‚

vernal turret
#

I'm not familiar with multiprocessing.pool. Is chunksize > 1 just a way to reduce communication between processes by sending data for multiple calls together?
I guess you could modify your code to submit batches of data to ProcessPoolExecutor, but it's not ideal.

paper echo
#

yep that's exactly what chunksize does

unkempt rock
#

Rust is one of the fast languages around at execution speed, equal to C++ if not faster in cases
@radiant fulcrum If I get good at rust, would I be able to pick up C++ quickly? Like, is rust built off of C++ syntax or is it completely different? I'm just curious about the transferability of skills between the two. For example, making the jump from Fortran to C++ is not trivial.

radiant fulcrum
#

concepts might not be as unusual for you, but Rust's system for stuff is pretty unique

unkempt rock
#

@radiant fulcrum ๐Ÿ‘ thanks for the explanation

gloomy rain
#

I think Rust was designed to be a better alternative to C++, so I do think it might one of the languages that better prepare you to learn C++, but they are quite different both syntactically and conceptually. It's just that they solve similar problems, so I think it might easier to understand C++ with Rust under your belt. Both are pretty difficult languages to learn, though.

full jay
#

Yes and no. Rust's approach to memory management is vastly different compared to how the C's do it

#

So while the level of abstraction might be the same, the way you approach writing your code don't really mesh

pearl river
#

If you're talking about C++/Rust here: what's a good language to learn for someone who has only ever learned high-level ones (Java, Python) and wants to dip their toes in lower-level? Out of C, C++, and less known ones like Rust apparently.

gloomy rain
#

@full jay That's true, but you can see how Rust's model evolved from C++, especially the modern Boost-based abstractions.

flat gazelle
#

C++ smart pointers are pretty similar to what rust has, just with less syntax support and overall worse

gloomy rain
#

Exactly

#

Unsafe Rust and C++ are pretty similar.

#

Conceptually at least.

full jay
#

Fair point

gloomy rain
#

@pearl river I think Rust is the superior language, so I would probably go with just diving into that.

#

Maybe C would be beneficial as well. It's a decent way to get introduced to manual memory management, and it can be useful if you wanted to get into embedded development.

#

C++ feels like too much of a time investment if you're just gonna move onto Rust later.

pearl river
#

Thanks!

boreal umbra
#

@random birch asked in #algos-and-data-structs if the garbage collector only activates at the end of a scope. I thought it will collect any non-permanent thing as soon as the reference count reaches zero, however that happens, but that all the variables in a given scope have their reference counts decremented at the end of a scope, which could trigger a number of collections back-to-back.

steep cove
#

HELLO

#

I NEED HELP IN A QUESTION

spice pecan
#

wrong channel bud

#

this one's for Discussion on the use cases, implementation and future of the Python programming language including PEPs, advanced language concepts, new releases, the standard library, and the overall design of the language.

clear coral
#

gc doesnt always happen immediately at 0 references @boreal umbra

>>> from weakref import ref
>>> a = A()
>>> r = ref(a)
>>> r()
<__main__.A object at 0x000001CDD66B1988>
>>> del a
>>> r()
<__main__.A object at 0x000001CDD66B1988>
>>> r()
<__main__.A object at 0x000001CDD66B1988>
>>> r()
<__main__.A object at 0x000001CDD66B1988>
boreal umbra
#

@clear coral wouldn't del a still be decrementing the reference count, but r would still contain a reference to it?

clear coral
#

no

#

weakrefs dont keep a reference

#

thats the point of them

peak spoke
#

r is a weakref, but I think that more has to do with it being in the repl

boreal umbra
#

what happens if you still have a weakref but the object has been deleted?

peak spoke
#

You get None

boreal umbra
#

wouldn't you get a lot of unexpected behavior?

peak spoke
#

of course it's still not guaranteed to happen at all in some cases

boreal umbra
#

I think if we already have weakref, I feel like my earlier global del idea isn't as bad as I thought.

clear coral
#

@peak spoke calling gc.collect will result in r() returning None afterwards. if the repl was somehow keeping a alive behind the scenes this wouldnt be the case.

spice pecan
#

I assume it kept it alive because _ was pointing to it

clear coral
#

it wasnt

#

_ is for free values that get pushed onto the stack

#

like if you just type 1+1

#

or if you call some thing() then _ will be set to its return value

spice pecan
#
>>> from weakref import ref
>>> class A: pass
...
>>> a = A()
>>> r = ref(a)
>>> r()
<__main__.A object at 0x00000191554A0AF0>
>>> del a
>>> r()
<__main__.A object at 0x00000191554A0AF0>
>>> _
<__main__.A object at 0x00000191554A0AF0>```
#

yeah no, it's pointing to it

peak spoke
#

Try it with prints wrapping the expressions

spice pecan
#
>>> _
<__main__.A object at 0x00000191554A0AF0>
>>> 5
5
>>> _
5
>>> print(r())
None```
About as soon as you drop the `_` reference, it turns to `None`
#
>>> a = A()
>>> r = ref(a)
>>> print(r())
<__main__.A object at 0x00000191554A0AF0>
>>> del a
>>> print(r())
None```
Wrapping into print skips the `_` reference
clear coral
#

then why does gc.collect kill it

peak spoke
#

_ gets an another result

#

gc's collect shouldn't have much to do with it unless the repl is keeping reference cycles in the back

spice pecan
#

yeah, collect returns a number (I assume it's the amount of collected items)

#
>>> a = A()
>>> r = ref(a)
>>> r()
<__main__.A object at 0x00000191554E2400>
>>> del a
>>> res = collect()  # skip _ reference
>>> r()
<__main__.A object at 0x00000191554E2400>```
clear coral
#

oh im stupid

#

sorry

boreal umbra
#

on a similar note

#

if you have an instance of a class that you made, you can arbitrarily give it attributes

#

why can't you do that with an object()?

spice pecan
#

I think object doesn't have a __dict__, just __slots__

boreal umbra
#

I see

peak spoke
#

types.SimpleNamespace comes in handy when you need that

boreal umbra
#

that's a thing?

#

๐Ÿ˜„

spice pecan
#

You can't give arbitrary attributes to object for the same reason you can't do it to any built-in, essentially

boreal umbra
#

I figured the not being able to add attrs to builtins was added to each builtin individually, since classes that inherit only from object have a __dict__.

peak spoke
#

Not sure if it even has slots, just no dict so can't have instance attrs

spice pecan
#

there's no accessible __slots__ attribute apparently

#

could have something to do with the fact that it's implemented in C

#

you can overwrite/add attributes via forbiddenfruit

flat gazelle
#

I think object just has attributes that map directly to fields of the pyobject struct

grave jolt
#

Why don't map and filter support asynchronous iteration?

#
f: A -> B
g: AsyncIterator[A]
h = map(f, g): AsyncIterator[B]

something like that?..

teal yacht
#

my guess is that it's simply not what the python core developers want to spend time on

#

we have async comprehensions

grave jolt
#

makes sense

torpid narwhal
#

Basically, one would use go's FFI to call the Python C api. Not sure what advantages this gives one....but interesting example of what one could do.

radiant fulcrum
#

honestly by the time you learn how todo it all and set it up you might aswell do it all in go

#

the syntax really isnt massively diffrent overall

charred barn
#

in datadog's case they have an agent that runs other peoples code and there is already a large amount of plugins written in python. there's no world where they could say "we rewrote our agent in go, everyone has to rewrite everything"

#

having written monitoring agents before though I'd probably go with a process per plugin model with IPC so plugins can be written in any language and you don't have to work about poorly written plugins messing with your agent nearly as much

paper echo
#

"run X lang from Y lang" is kind of a nice thing to have anyway

spiral willow
#

esp telling SREs to rewrite in Go gary

#

that would quickly go to "Go to hell Datadog"

hazy cloak
#

What is the best way to iterate over two lists with both zip and enumerate ?
Is this considered a good practice ?

list1 = ['a', 'b', 'c']
list2 = [1, 2, 3]

for i, (a, b) in enumerate(zip(list1, list2)):
    print(i, a, b)
teal yacht
#

yes

hazy cloak
#

Ok, thanks !

narrow kettle
#

i thought that read "is this considered bad practice" and i was like how on earth would that be considered bad

minor sinew
#

i started using VS code for some frontend stuff at work that i need to learn, and ngl, it's pretty legit

verbal drift
#

Hi, I am an intermediate level python user and wanted to know how often you use async and await at an advanced level? Do you only use it at the end for optimization purposes ?

peak spoke
#

It really depends on the app, if it's async you'll be using it a lot

unkempt rock
#

how can I install and use the latest python version on google cloud debian ssh console ?

teal notch
#

okay so

flat gazelle
#

you use it when doing asynchronous IO. If your project uses async, you will use it all the time, if not, there is almost no case where you use it

teal notch
#

Type in "||Python your mom version||" in google search

boreal umbra
#

maybe I'm missing the point of what you said though.

verbal drift
#

thanks guys

boreal umbra
#

If you're just asking about when it's used, not all advanced Python use cases use async. I think it's mostly for event-driven programs

#

Most of what I do is data science and I've never used async, but I'm also not very good pithink

low lagoon
#

!tempmute 677994881779630094 3d It seems that you're only here to make jokes about inappropriate body parts and mothers of other people.

fallen slateBOT
#

:incoming_envelope: :ok_hand: applied mute to @teal notch until 2020-08-07 19:18 (2 days and 23 hours).

cloud hill
#

Async is pretty interesting in the web-dev world because of how much "work" there is waiting on IO. There's still a ways to go (you still need to be very careful about calls to things like DBs which are usually synchronous), but it theoretically makes it so a single process can handle way more requests, making it easier to scale out

#

But, at least for me, I don't use it at all (currently)... it's still a bit rough around the edges. I think Django just had a release today adding support for async views and middleware, which is an awesome step.

verbal drift
#

is it hard to implement, or/and (&&, || lol) does it take a lot of time ?

cloud hill
#

Anyway, right now if you want to handle multiple requests at a time in prod, you traditionally use gunicorn/uwsgi and have multiple processes. This is expensive especially when compared to threads or coroutines... async lets each process potentially handle multiple requests, using async/await to yield to other requests (in laymans terms).

#

I'd personally avoid it unless you absolutely need the performance or you're making something that absolutely has to be in real time

#

It's useful, but can be fairly complex, and has a number of easy-to-miss pitfalls

verbal drift
#

okay thanks, the thing is that python tends to be on he slow end, so I thought optimization (such as async) would be used more often at a higher level

peak spoke
#

Async is not really an optimization, it's a whole another way of designing your code

paper echo
#

async/await is a programming paradigm, cooperative multitasking is an execution model

#
cloud hill
#

I'll read up on that

#

I'm admittedly more familiar with async in other languages, though I assume there are a number of similarities

#

The GIL does change things a bit though

flat gazelle
#

it does not, python async is generally single threaded afaik, just using epoll/select/poll/libuv to pick what to handle at a given time

cloud hill
#

Which, if you're specifically limited on network (and using async calls for all network calls), can perform better

peak spoke
#

The GIL should only come into play with executors, other than that it's an event loop running in a single thread

#

Most of the time anyway

paper echo
#

exactly @flat gazelle

#

terminology salad: single-threaded single-process asynchronous i/o with an event loop that implements cooperative multitasking

cloud hill
#

Fair. I think django does some magic to let you make non-async blocking calls on another thread, but I haven't looked into that...

#

async does make it a lot easier to scale out to write real-time applications... since each request taking up a full process (as would be the case with uwsgi/gunicorn) would be incredibly expensive.

#

But most people also don't need to write real-time applications

paper echo
#

one of armin ronacher's complaints has to do with backpressure

#

basically you can have an arbitrary number of coroutines all blocking themselves

cloud hill
#

Ah, there is a lot of good stuff in those articles "async/await is great but it encourages writing stuff that will behave catastrophically when overloaded."

Also, some of the benchmarks use a fairly old version of Django... I'd be interested to see similar benchmarks with the version that just released with async views and middleware.

magic python
#

{1 : 2} == {1 : 2} returns true, why is this though? this is because a __eq__ dunder is present?

spice pecan
#

yes

pearl river
#

Well, yes, dicts have comparison operations. Well, equality ones that is.

grave jolt
#

Yes, AFAIK, types in CPython contain vtables of operations like addition, equality etc.

#

So it's not that hard to implement operations that make logical sense for basic data structures.

#

This creates unsurprising (at least logically/mathematically) relations like {1: 2} == {1: 2} or [1, 2, 3] == [1, 2, 3, 4] or "abcd" == "0abcde".

drifting fossil
#

hi guys

#

guys what is the easiest way to create a command line programe using python

grave jolt
paper echo
#

Why does "create task" start an asyncio task?

#

Like what if i want to create a Task but not actually run anything yet

narrow kettle
#

give it a callback

#

then wait a set amount of time

#

then execute the callback

paper echo
#

Its more a point about language design and naming

#

But yeah

narrow kettle
#

like just creating a task but not running it is basically like just returning a coro no?

paper echo
#

Isnt that a Future and not a Task?

#

Or do i misunderstand the difference

narrow kettle
#

thats essentially just returning a coro no? or similar to that

charred wagon
#

ensure_future makes more sense as a name

#

Compared to create_task

#

But it's not really clear why we need both ensure_future and create_task to co-exist these days.

paper echo
#

im not clear on what an asyncio Future even does

charred wagon
#

Well ensure_future's name makes sense, but wat the function actually does doesn't make as much sense

paper echo
#

do they just exist for backward compatibility inside the asyncio codebase?

charred wagon
#

Futures are a lower level API

swift imp
#

Can you use asyncio as a job scheduler

charred wagon
#

It allows you to work with things besides coroutines

paper echo
#

kinda @swift imp with loop.call_at

#

and loop.call_later

swift imp
#

We use Jenkins at work to monitor when jobs submitted to be Grid Engine finish

#

I'd rather be able to do it in python

#

Jenkins kicks off additional scripts after those jobs finished

paper echo
#

call_at needs to be an absolute timestamp w/ respect to the event loop's internal clock

#

not necessarily a proper unix timestamp

swift imp
#

Yeah I feel like I need to learn how to use asynchio

#

One of the few modules I've never touched

#

Seems useful

raven ridge
#

ensure_future will return the object you pass it unchanged if it was a Future or Task, otherwise it returns a new Task - so, if you have a coroutine and want to turn it into a Task, ensure_future will do that (despite its terrible name).

#

actually, though, seems like it schedules the new Task as well - I thought it didn't. So, nevermind.

paper echo
minor sinew
#

for list comprehension syntax, is it valid to have a one-liner at the end like this?

myList = [myObj for myObj in myObjList myObj.MyBoolean = True]
brave badger
#

Nope, that's not a valid comprehension

minor sinew
#

damn it lol

north root
#

what's your goal?

brave badger
#

Does the walrus operator support attributes?

minor sinew
#

i was just trying to set a property on an object before i feed it into a list of coroutines. i can do it without a list comp though

fallen slateBOT
#

You are not allowed to use that command here. Please use the #bot-commands channel instead.

north root
#

it's just like a normal =, except it also returns the value

pliant tusk
#

it doesnt support anything except a single name

#

so no attributes, no subscripting

gleaming rover
#

i was just trying to set a property on an object before i feed it into a list of coroutines. i can do it without a list comp though
@minor sinew it's generally considered bad form to have side effects in a comprehension

north root
#

ah yeah, you're right

gleaming rover
#

like theoretically speaking you could do myObj.__setattr__('MyBoolean', True) but that would be all sorts of disgusting

north root
#

but either way, you shouldn't use a list comp there

pliant tusk
#

you could do [... for MyObj in ... if not setattr(myObj, 'MyBoolean', True)]

gleaming rover
#

I feel physically ill

minor sinew
#

that's just ugly lol

#

a for loop is fine

brave badger
#

map, partial, and setattr may be better

gleaming rover
#

I think this is rapidly devolving into #esoteric-python territory, and not in a good way

north root
#

map is a generator, so you'd need to iterate through it as well

grave jolt
#

[*map(...)] :)

north root
#

yeah these are all bad ideas lol

raven ridge
#

[(myObj, setattr(myObj, 'MyBoolean', True))[0] for myObj in myObjList]
but don't do that ๐Ÿ˜„

grave jolt
#

all(map())

brave badger
#

Then again, causing side effects on a comprehension is a bad idea like @gm had mentioned

gleaming rover
#

[(myObj, setattr(myObj, 'MyBoolean', True))[0] for myObj in myObjList]
but don't do that ๐Ÿ˜„
@raven ridge I was thinking of this too

minor sinew
#

shoehorning to the max

north root
#

don't use a list comp if you don't need to save the data

gleaming rover
#

it's so horrific the camel case doesn't even register on my radar

raven ridge
#

heh

north root
#

hahahah

minor sinew
#

putting underscores after every word is even uglier imo, but to each their own

grave jolt
#

[(my_obj, setattr(my_obj, 'my_boolean', True))[0] for my_obj in my_obj_list]

#

well, now it's pep8-compliant

pliant tusk
#

whats wrong with using inline if?

grave jolt
#

what's wrong with it?

gleaming rover
#

myObj

minor sinew
#

a regular for loop is just easier to read if a list comp can't do what you want

grave jolt
#

fixed

minor sinew
#

no point shoehorning some functionality if it's terribly difficult to read lol

grave jolt
#

what's wrong with it?
(well, not counting the fact that it has the condition after the then-branch....)

pliant tusk
#

[my_obj for my_obj in my_obj_list if not setattr(my_obj, 'my_boolean', True)]

gleaming rover
#

honestly I prefer that order to what you might see in Haskell or something

grave jolt
#

oh

pliant tusk
#

abusing not None for truthiness

gleaming rover
#

true_value if condition else false_value just seems more readable to me because of the "if" and "else" words

minor sinew
#

naming convention is pretty irrelevant as far as you being the sole dev in your own repo lol

gleaming rover
#

like I can see condition ? true_value : false_value in C etc. because there aren't words

minor sinew
#

if you work on a team (99.999% chance of this happening), you should 100% comply with what's used

paper echo
#

conditional operator syntax in python is pretty unpleasant

#

as much as i sympathize with their decision not to use ? : i really don't like how "inverted" it is

#

it's really hard to read

#

maybe that's by design, to prevent you from being tempted to use it more

gleaming rover
#

incidentally, does anyone think that empty collections being falsey is undesirable?

paper echo
#

like lambda

feral cedar
#

i definitely prefer the && and || instead of and and or

paper echo
#

python is a bit like go in that respect

gleaming rover
#

conditional operator syntax in python is pretty unpleasant
@paper echo I think I'm the only person who actually likes it

paper echo
#

@gleaming rover i think it's legitimate

#

i dont hate it, you just can't use it for complicated expressions without \ line breaking

grave jolt
#

I think allowing non-booleans in conditions is a sin ๐Ÿ‘€

gleaming rover
#

yes

paper echo
#

just pretend bool() is wrapped around everything after if ๐Ÿ˜‰

gleaming rover
#

and IMO it's weak typing (I don't mean that pejoratively)

raven ridge
#

even as the sole developer on your own repo, it's better to follow the relevant coding standards. it's easier to learn good habits from the start than break bad habits later.

feral cedar
#

that's basically what the if does right?

paper echo
#

yeah

#

@gleaming rover yeah well ducks and quacking and such right?

minor sinew
#

the coding standards for variable names is different from language to language lol

grave jolt
#

duck typing != weak typing

paper echo
#

i think the idea of an empty container being falsey is the ability to write if not lst:

minor sinew
#

so for the most part, it's pretty irrelevant unless you're working on a team

paper echo
#

duck typing != weak typing
yeah i know i know

#

good point

gleaming rover
#

I don't actually think this is ducktyping........?

#

yeah.

grave jolt
#

no, it's not

gleaming rover
#

i think the idea of an empty container being falsey is the ability to write if not lst:
@paper echo or if iterable, conversely

paper echo
#

yep

gleaming rover
#

but IMO that is weird.

#

like how many other languages treat an empty container as a false value?

minor sinew
#

python is strongly typed, but types are defined at runtime lol

raven ridge
#

the coding standards for variable names is different from language to language lol
@minor sinew oh yes, definitely - but Python has a strong standard for it that nearly everyone follows, and not following it makes your code look amateurish, and will make it harder to get a job, or get your code accepted into OSS repos, etc

feral cedar
#

it's not even that much clearer than checking the length like: if len(lst) < 1

minor sinew
#

it's not like matlab which is weakly typed, and types are defined at runtime

gleaming rover
#

python is strongly typed, but types are defined at runtime lol
@minor sinew yes, that's what I'm saying; it's not fully strongly typed

#

because you have automatic type coercion in stuff like if

paper echo
#

doesnt C++ do a lot of implicit type coercions

grave jolt
#

yes

paper echo
#

does that make it strongly or weakly typed?

gleaming rover
#

weakly

paper echo
#

makes sense

gleaming rover
#

weakly statically typed

paper echo
#

so python is weakly typed but not as weak as, say, javascript

grave jolt
#

C++ would be weakly typed without that because of memset and such

gleaming rover
#

and over there you have the weakly dynamically typed JS

raven ridge
#

C does relatively few implicit type coercions... but it does coerce between basically every numeric type.

teal yacht
#

C++ does significantly less implicit coercion than C

grave jolt
#

!e

g = (x for x in ())
if g:
    print("oops... :)")
paper echo
#

how strong is ruby's type system compared to python's?

fallen slateBOT
#

@grave jolt :white_check_mark: Your eval job has completed with return code 0.

oops... :)
paper echo
#

yeah exactly @grave jolt i was going to say

raven ridge
#

C++ does significantly less implicit coercion than C
@teal yacht Huh? C++ is (roughly) a superset of C; it has every coercion that C has.

paper echo
#

bool() needs to do the right thing

#

it's a really leaky abstraction that depends on every programmer of custom iterables writing them intelligently

gleaming rover
#

it's not even that much clearer than checking the length like: if len(lst) < 1
@feral cedar less even, IMO

paper echo
#

"intelligent" == "the iterable knows when it contains more data to be read"

#

ok so fair point @gleaming rover , maybe python didn't need falsy empty containers

#

how about falsy None?

grave jolt
#

yeah, create LengthAwareIterable protocol :)

feral cedar
#

i'd rather just have to check is None

grave jolt
#

None is another page of discussion...

gleaming rover
#

how about falsy None?
@paper echo split on this

#

what if we had three-valued logic...

paper echo
#

at least python didn't conflate None with null pointers ๐Ÿ˜›

gleaming rover
#

although I am a big fan of explicit option types

grave jolt
#

me too ^

paper echo
#

!pep 505

fallen slateBOT
#
**PEP 505 - None-aware operators**
Status

Deferred

Python-Version

3.8

Created

18-Sep-2015

Type

Standards Track

gleaming rover
#

yeah, those look nice

paper echo
#

lest we forget

grave jolt
#

and static type checkers have to do some work to make sure you don't miss a None

brave badger
#

How about making Optional an actual optional class that can be used lemon_thinking

paper echo
#

that opens up a really big can of worms though

#

how far down the monad rabbit hole do you want to go

gleaming rover
#

yeah

#

I'm not sure if it would be productive for the majority of people

#

even though from a conceptual standpoint I like it

paper echo
#

is Optional a special thing? is it a specific case of something generic?

#

etc

gleaming rover
#

also it would be ridiculously backward compatibility breaking if it would replace None

#

and superfluous if it wouldn't

paper echo
#

i think none-aware operators are good enough for the majority of Maybe-like use cases

grave jolt
#

is Optional a special thing? is it a specific case of something generic?
Well, async/await was added.

paper echo
#

true.

gleaming rover
#

incidentally, is for-else unique to Python?

paper echo
#

but they implemented it with a generic protocol which is my point

#

if Optional has some kind of monad-esque behavior, how is it actually designed into the langauge?

grave jolt
#

*redesigns language from scratch*

minor sinew
#

@raven ridge if someone is judging the content of my code in my own repos that im the sole developer solely based on my variable nomenclature, then i simply don't want to work for them lmao

everything else you mentioned is when it becomes important, which is working on a team

gleaming rover
#

while we're on stuff that is weird and crufty

#

I would really appreciate it if id was renamed

paper echo
#

yes

grave jolt
#

yeah

paper echo
#

can we also snake case everything

grave jolt
#
  1. identity
  2. some ID
raven ridge
#

@minor sinew well, the "learning bad habits" part was more generally applicable, too.

gleaming rover
#

getLogger

paper echo
#

datetime.datetime -> datetime.DateTime

raven ridge
#

if we had a wishlist for Python 4, id shouldn't even be a builtin.

#

hell, about half of the builtins shouldn't be builtins.

brave badger
#

getLogger
Yikes

grave jolt
#

id should be somewhere in sys

minor sinew
#

@raven ridge some devs like the underscores. some other devs like camel case. like i said before, it's only a bad habit if you can't break it when you go to a team, so it's a bit irrelevant otherwise.

raven ridge
#

chr and ord certainly don't need to be builtins.

gleaming rover
#

Python has like the most polluted default global namespace ever

grave jolt
#

and they removed reduce :)

gleaming rover
#

:)))

grave jolt
#

oh, and most of the exceptions are imported by default

gleaming rover
#

I have like

#

not used reversed...ever?

grave jolt
#

Hmm. Well, maybe (no pun intended) it's possible to add a decorator that would implement do-notation?!

# one_over: float -> Maybe[float]
# sqrt: float -> Maybe[float]

@do
def f(x):
    reciprocal = await one_over(x)
    the_sqrt = await sqrt(reciprocal)    
    return the_sqrt * 3 

# equivalent to:
def f(x):
    return one_over(x).__bind__( lambda reciprocal: sqrt(reciprocal).__bind__(lambda the_sqrt: the_sqrt * 3) )
    
#

like, it could parse the AST or something

torpid narwhal
#

Eh. Iโ€™m working on a rails project now. Thatโ€™s more frustrating than any bad python stuff.

teal yacht
#

@raven ridge pointers don't get implicitly casted like in C, for example, this is invalid C++

int main()
{
    int *arr = std::malloc(10 * sizeof(int));
    return 0;
}
gleaming rover
#

that code makes me feel equal parts sick and warm inside

grave jolt
#

but the weak typing part is that you can cast them like that

gleaming rover
#

but the weak typing part is that you can cast them like that
@grave jolt I don't think that's weak typing....?

#

weak typing is about implicit typecasting

grave jolt
#

Well..... maybe

teal yacht
#

weak/strong is about *implicit type coercion

paper echo
#

@grave jolt what, practically, would __bind__ do here

gleaming rover
#

explicit typecasting can be defined for arbitrary source and destination types

#

and is therefore not a problem

grave jolt
#

thanks for opening the next can of worms ๐Ÿ˜‰ @paper echo

paper echo
#

if we want to be monadic let's not privilege Maybe

grave jolt
#

i will show you an example with lists, since they are monads

gleaming rover
#

"a monad is just a monoid in the category of endofunctors, what's the problem?"

grave jolt
#
def list_map(list_, fn):
    return [fn(x) for x in list_]

def list_join(list_of_lists):
    return sum(list_of_lists, [])
#

map applies a function to each element of a container M[T], and join turns M[M[T]] into M[T], like, it flattens it

paper echo
#

i follow

gleaming rover
#

bind is flatmap, right

teal yacht
#

yes (for lists)

gleaming rover
#

isn't bind flatmap in general

#

like flatmap is another name for bind...?

grave jolt
#

So map: (A -> B) -> List[A] -> List[B]
join: List[List[A]] -> List[A]

teal yacht
#

i don't really like the flatmap name because it doesn't always make sense imo, but maybe i'm just misinterpreting it

grave jolt
#

And

def bind(list_: "List[A]", fn: "A -> List[B]"):
    return list_join(list_map(list_, fn))
teal yacht
#

not that bind make sense either lol

grave jolt
#

"shove"

gleaming rover
#

honestly I don't see why it's called bind

#

to me bind is called what unit is

#

but I'm not a category theorist so

grave jolt
#

so that it's confusing for JS programmers

#

because .bind already exists

gleaming rover
#

you know what's confusing for Python programmers

#

JS arrays convert to strings before sorting by default

#

even if it's not needed

grave jolt
#

yes, I fell for that

paper echo
#

what the actual flying fuck?

#

truly cursed language

grave jolt
#

[10, 2, 3].sort() == [10, 2, 3]

gleaming rover
#
> [23, 16, 10, 3, 1].sort()
[ 1, 10, 16, 23, 3 ]
paper echo
#

wait. is monadic binding the same as flatmap? how is that

#

or are there different meanings for the term "bind"

gleaming rover
#

the monadic operation with the name "flatmap", AFAIK, is also called "bind"

grave jolt
#

in haskell it's called bind for some reason, yes....

teal yacht
#

the bind makes sense when you do the parallel with the do notation

#

but it's still very foggy imo

paper echo
#

i know flatmap as something like chain.from_iterable(map(f, x))

#

as in scala

grave jolt
#

Well, yes, bind/flat_map is the composition of map and join

#

join ~= turn two layers of container into one

#

So

bind([1, 2, 3], lambda x: [42]*x) == [42,  42, 42,  42, 42, 42]
paper echo
#

right

#

so bind in this particular context analogous to more abstract operations w/ monads?

gleaming rover
#

in a hypothetical Python Option:

class Option(Generic[T], Monad):

    def __init__(self, value: Optional[T]):
        self._value = value

    def flat_map(f: Callable[[T], Option[T]]): Option[T]:
         # could be replaced with a singleton actually
         return Option(None) if self._value is None else f(self._value)
grave jolt
#

:D

def maybe_map(f, m):
    match m:
        case Just(x):
            return Just(f(x))
        case Nothing():
            return Nothing()

def maybe_join(m):
    match m:
        case Just(m2)):
            return m2
        case Nothing():
            return Nothing()
teal yacht
#

return Option(f(self._value)) should be just return f(self._value)

grave jolt
#

that's map, not bind

gleaming rover
#

yes

#

you are right

teal yacht
#

f is a -> M a

grave jolt
#

oh, it's flatmap

#

I can't read

#

right

teal yacht
#

flat_map fmap same shit

#

amirite

gleaming rover
#

trying to imagine what it would be like in Scala and translating to Python is confusing

#

type hinting function types in Python is Difficult

paper echo
#

i still dont understand how this "flatmap" bind is the same as >>=

#

or is it not the same thing

teal yacht
#

all 3 refer to the same function

paper echo
#

i thought i understood haskell's >>= conceptually but maybe i dont

gleaming rover
#

it's the same thing

swift imp
#

Thst coalesce operator from 505 would have been nice

gleaming rover
#

you have a monadic value, as well as a function that takes a raw value and returns a monadic value

paper echo
#

right

swift imp
#

Why won't they add that?

paper echo
#

but flatmap is binding specifically for the List monad

gleaming rover
#

flatmap is the operator that applies the latter function to the former (after unwrapping) for all monads

paper echo
#

bleh thats such a stretch

raven ridge
#

@raven ridge pointers don't get implicitly casted like in C
@teal yacht good point, forgot about that.

gleaming rover
#

or, put another way, monads are the typeclass defining flatmap and unit

#

(right?)

teal yacht
#

yes

paper echo
#

i dont like all this terminology overloading

#

not one bit

teal yacht
#

that's the primary issue with haskell and the likes

paper echo
#

why do we use map to mean apply iteratively in the first place

teal yacht
#

like, the language would be fine if it wasn't for the 173 symbols defined in Data

gleaming rover
#

that would be fine except that it also means "associative array"

#

UGH

teal yacht
#

fine for beginners to pick up*

paper echo
#

@gleaming rover i much prefer that form of "mapping" because it's analogous to the math term

gleaming rover
#

also I think the nature of function composition in Haskell is very nonintuitive for someone who isn't a mathematician

teal yacht
#

Idk I like it

grave jolt
#

It all makes more sense in the context of Functors and Applicatives.

Functor F[T] is something which has map : (T -> U) -> F[T] -> F[U] (fmap). The shape of the container doesn't change after you do map.

Applicative A[T] is a functor which has pure : T -> A[T] which returns a simple value wrapped in a container (x -> [x] for lists, x -> Just x for Maybe) and the <*> : A[T -> U] -> A[T] -> A[U] (frog asshole) operation. This operation applies each function in the left container to each member of the right container. It's more powerful, but the values themselves can't alter the shape of the container..

A monad M[T] is an applicative which defines the >>= : M[T] -> (T -> M[U]) -> M[U]. Here the value of the container can alter the shape of the result. For example, sqrt : float -> Maybe[float] and one_over : float -> Maybe[float] are computations that can fail. >>= allows to chain them easily (as in my Python example above ^ far away)

gleaming rover
#

like how Scala does it (method chaining) is more readable for the average person

paper echo
#

so yeah flatmap i think is a horrible term because the whole idea of "flattening" is kind of a list-specific concept

teal yacht
#

I miss composition so often in python

gleaming rover
#

why do we use map to mean apply iteratively in the first place
@paper echo aren't they linked

paper echo
#

as explained above ^

gleaming rover
#

I don't have a mathematical background but Wiki says "Originally, this was an abbreviation of mapping, which often refers to the action of applying a function to the elements of its domain"

paper echo
#

ah

gleaming rover
#

so yeah flatmap i think is a horrible term because the whole idea of "flattening" is kind of a list-specific concept
@paper echo I believe the idea is flattening the monad

#

because otherwise you would end up with a nested monad

paper echo
#

and yes i just realized that

gleaming rover
#

like Option[Option[T]]

paper echo
#

ok fine

grave jolt
#

Just imagine a non-technical person hearing "flattening a nested monad"

gleaming rover
#

I miss composition so often in python
@teal yacht I mean more the order

paper echo
#

s/monad/container

gleaming rover
#

like I get that mathematically f(g(h(x))) means h comes first but

teal yacht
#

x |> h |> g |> f sad

grave jolt
#

Well, you can create your own Pipe class

paper echo
#

f . g . h $ x ๐Ÿ™‚

gleaming rover
#

plate(bake(marinate(ingredient))) seems to me to be much less readable than ingredient.marinate().bake().plate()

teal yacht
#

(I know not valid haskell)

grave jolt
#
(Pipe(x) >> h >> g >> f)
teal yacht
#

but yeah i get you, definitely agree

paper echo
#

@grave jolt so map() in the "typical" sense is the implementation of fmap for Lists?

#

or, one possible implementation

grave jolt
#

I think the only possible implementation that obeys the laws

paper echo
#

ah

#

i'll leave that to the theoreticians

#

i think i can start to see how you could apply a concept like monads to a language like python if you call it a "Context"

grave jolt
paper echo
#

well let's not overload that term since we already have with

#

hm.

teal yacht
#

You know what I meant angerysad

grave jolt
#

yes, I just wanted to nitpick!!!

gleaming rover
#

well

paper echo
#

i dont even want to call it a container? a context container? an environment?

grave jolt
#

Computation in a context

#

morning pure

paper echo
#

...with could be reformulated in terms of python monads

gleaming rover
#

I beg to differ
@grave jolt I actually have no idea what & is but I'll take your word that it works

brave badger
#

Monads as containers e.g. Lists, Maybes
Monads as computations e.g. State, Reader, Writer, IO

#

Roughly

gleaming rover
#

though that really looks like a few trees separating pregnant women holding young children

#

with a weirdly shaped chair on the left end

paper echo
#

just so i understand: unwrapping a value from inside a monad like IO is when the i/o actually happens?

gleaming rover
#

I believe so...?

#

also State monad is hell

brave badger
#

I mean technically State can be interpreted as a container because it parametrizes on a result a but it's more of a computation because of the state

#

Maybe they're both ยฏ\_(ใƒ„)_/ยฏ

grave jolt
#

If you're interested, I have an entire implementation of the IO monad in python, together with an adapter to Postgres (I used aiopg instead of asyncpg for some reason, but ig it's easy to swap).

paper echo
#

i think you shared some earlier version of that

grave jolt
#

yeah

paper echo
#

im just trying to wrap my head around how something like this would look in python

grave jolt
#

or maybe here

#

async/await is another example of monads.

async def f(a):
    x = await g(a)
    y = await h(x)
    z = await j(y)
    return m(z)

def f(a):
    return g(a) >= (lambda x: h(x) >= (lambda y: j(y) >= (lambda z: m(z))))
#

if a : A and x : X, then g : A -> Awaitable[X]

paper echo
#

what is the "context" here

#

ah

gleaming rover
#

yes I've read that

#

It's a simple string parsing algorithm.

#

simple indeed

#

and I don't know...the syntax of Haskell is just so weird to me

grave jolt
#

Whenever I read "simple" on haskell wiki, I read it in rAnDOM cASe to add a little bit of sarcasm to it

gleaming rover
#

like types are just easier for me in Scala

grave jolt
#

still better than Python annotations