#internals-and-peps

1 messages Β· Page 141 of 1

worn zephyr
quasi hound
#

what does this mean

#

@ me please

prisma lantern
prime estuary
#

This feature was going to be default in 3.10, but that was reverted and the core devs haven't decided exactly how annotations should be handled in 3.11. It's still in alpha so any features can be added/removed without notice.

prime estuary
# quasi hound what does this mean

Variable annotations for attributes are only allowed on local variable definitions, since those are discarded. Global variable annotations are stored in __annotations__, but there's nowhere to put your attribute annotation. You should just annotate the original definition of this class.

As an aside, __names are not syntax for "private" names, that's just a single underscore. Two are indented for the specific case of multiple classes inheriting from each other, so their attributes don't stomp on each other.

#

True, but it's not that important, it should be set to a proper value by the time of release.

grave jolt
#

can you show TimeState?

#

Oh, I see

stone steeple
#

is there anyone that can help with R here?

#

thank you

verbal escarp
elder blade
#

Why bother though

thorn temple
#

Guys guys how do i di oython

#

Is that a hacker tool?

#

Yall working in fbi!?!!

#

Cool

#

How do i hack also

#

Woahh cool hacker thing

#

Youre doing right there

#

Soo how do i do it?

verbal escarp
verbal escarp
verbal escarp
candid pelican
#
def main() -> None:
    while True:
        collection_handler = CollectionHandler()
        document_handler = DocumentHandler()
        data_handler = DataHandler()

        command_list = {
            'new collection': collection_handler.create,
            'del collection': collection_handler.delete,
            'use collection': collection_handler.use,
            'see collection': collection_handler.read,

            'new document': document_handler.create,
            'del document': document_handler.delete,
            'use document': document_handler.use,
            'see document': document_handler.read,

            'new data': data_handler.create,
            'del data': data_handler.delete,
            'upd data': data_handler.update,
            'see data': data_handler.read
        }

        command = input(">> ")

        for cmd in command_list:
            if command.startswith(cmd):
                data = command.removeprefix(cmd)
                try:
                    command_list[cmd](eval(data))
                except NameError:
                    try:
                        command_list[cmd](data)
                    except SyntaxError:  
                        command_list[cmd]()
                break

there's some way to avoid these try except???

candid pelican
#

can u show me how?

spice pecan
#

You could parse that in two parts

#

You have a lot of repetition going on, so instead of specifying each particular action subject case you could generalize it to something like

actions = {
    'new': 'create',
    'del': 'delete',
    'use': 'use',
    'see': 'read'
}

handlers = {
    'data': data_handler,
    'document': document_handler, 
    'collection': collection_handler
}

action, subject, data = input('>> ').split(maxsplit=2)
handler = handlers[subject]
method = getattr(handler, actions[action])
method(data)```
candid pelican
#

that's soo good

surreal sun
#

Does anyone know why _ is handled as a soft keyword and not an identifier?

#

!e

import keyword
print(keyword.softkwlist)
fallen slateBOT
#

@surreal sun :white_check_mark: Your eval job has completed with return code 0.

['_', 'case', 'match']
native flame
#

!e

x = 5
match x:
  case aaa:
    print(aaa)
fallen slateBOT
#

@native flame :white_check_mark: Your eval job has completed with return code 0.

5
native flame
#

!e

x = 5
match x:
  case _:
    print(_)
fallen slateBOT
#

@native flame :x: Your eval job has completed with return code 1.

001 | Traceback (most recent call last):
002 |   File "<string>", line 4, in <module>
003 | NameError: name '_' is not defined
surreal sun
spice pecan
#

3.10, yeah

#

It used to be a regular identifier before that

surreal sun
#

Ah alright

spice pecan
#

Tbh I still think * would be a better wildcard

verbal escarp
quasi hound
#

ok why does this function return a generator

#

why isn't it a generator

native flame
#

the function itself is a generator function

#

it returns a generator

quasi hound
#

when i print the result of this i get <generator obj at 0x....>

#

so how do i do what i want here

elder blade
elder blade
feral cedar
#

the type of the result of the function is a generator

peak spoke
#

If that's all the generator is you could also just use itertools.cycle

quasi hound
native flame
quasi hound
#

i think i get it now

#

i was trying to last night

#

but it was doing the same shit

#

ty

#

but now

#

i'm getting "itertools.cycle obj is not callable"

TIME.advance = itertools.cycle([ts for ts in TIME.values() if isinstance(ts, TimeState)])
...
if __name__ == '__main__':
    while True:
        print(TIME.advance())
#

so if the function returns a generator you would just call that again wouldn't you

#

im definitely misunderstanding something here

peak spoke
#

No, to use a generator you step through it in some way

#

cycle returns an iterator so if you want a single value from it you can use next on the cycle object, or iterate through it with a for loop

quasi hound
#

makes sense

grave jolt
#

people often use imprecise terminology which I don't really like

#

When you do (x**2 for x in range(10)) or _advance(), you get a generator or a generator object.

But _advance itself isn't a generator, it's a function. So the right way to call it is generator function.

paper echo
#

A function with yield is a generator function. It returns a generator

grave jolt
#

yep

#

same with async. some people call an async def function(...) a coroutine, but it's a coroutine function. It returns a coroutine.

#

some people includes the python docs πŸ˜”

#

If I remember correctly

sacred tinsel
#

you do

#

the asyncio docs call async functions coroutines

surreal sun
#

Are coroutines just asynchronous generators?

spice pecan
#

They represent a different concept, but they are implemented as generators IIRC

surreal sun
#

Ahh

#

Wasnt the concept of asynchronous programming introduced into Python itself with async generators?

#

Besides stackless python and what not

spice pecan
#

At first, before async def and await were a thing, you'd use a decorator on a generator

surreal sun
#

Ah

spice pecan
#

The main semantic difference is that a generator's purpose is to produce values, while a coroutine's purpose is to allow for asynchronous programming. The underlying mechanics that generators use do allow to conveniently achieve async programming, and although very similar (if not the same under the hood) in their implementation, generators and coroutines are used in different contexts

#

await does return a value, but what matters most is that it hands the control back to the event loop. yield can be used to give the control back to the event loop, but the main idea behind it is that it returns a value

paper echo
#

Like how there's no clear definition of a "file object"

#

This knowledge is communicated tribally, not via structured documentation

spice pecan
#

IIRC they mention at the top of the page that they use the word coroutine to refer both to actual coroutines and coroutine functions

peak spoke
#

pretty sure the glossary has both

sacred tinsel
#

"Note that simply calling a coroutine will not schedule it to be executed"

paper echo
#

Oh yuck

sacred tinsel
#

coroutines are not callable

paper echo
#

πŸ€¦β€β™‚οΈ

#

You can have a callable awaitable!

#

That would actually be an interesting trick

spice pecan
#

Have it await itself in the body

#

Oh, wait, you'd have to await the call then

paper echo
#

You could have it call asyncio.run on itself

#

Or you could have two different implementations

#

Or the available version would run itself in a thread

spice pecan
#

True, that would work

#

Interesting idea

paper echo
#

Probably confusing to end users

elder blade
paper echo
#

@verbal escarp re: p2p package distribution, https://pretalx.com/packagingcon-2021/talk/RWR89G/

#

if you're on libera.chat, this is the user cnx

verbal escarp
#

uh!

#

hu.. last time i talked to the ipfs guys, they didn't recommend using it for python packages, i might have ignited something there

#

i'm a bit skeptical now

#

were the talks recorded?

paper echo
#

it hasn't happened yet!

#

you might want to connect w/ them on irc

#

i told them about you, too

verbal escarp
#

oh, right.. still october

#

you did? oh man :p

#

😊

#

ok, i'm on libera

#

i don't see any cnx on libera #python..

white nexus
#

how to submit a fix for a typo on the python documentation?

paper echo
#

#pypa @verbal escarp

white nexus
paper echo
white nexus
#

don't worry bout it

#

its actually an intentional typo and the docs explain it

#

hm, you seem confused

paper echo
#

Oh that, yep

white nexus
#

ye

lusty scroll
#

are there other languages where the coroutines are callable?

#

exactly what it sounds like

#

try a regular coro

lusty scroll
#

forget it 🀣

carmine kraken
#

hey guys, i have a random time complexity question:

#

if there is an if loop in a nested for loop in a for loop, the time complexity would be O(n^2 + n) right?

#

but you dont write O(n^2 + n), so you just write O(n^2)?

pine cosmos
naive saddle
#

I just spent like a good hour trying to implement PEP 660 - editable installations in setuptools. Turns out I completely misunderstood the way build_editable is supposed to work >.<

The editable wheel should basically just contain .dist-info and support files that actually make it "editable", in this case being a .pth file. I originally thought you could just reuse a normal wheel and stick the extra .pth file in there 🀦

paper echo
#

!pep 660

fallen slateBOT
#
**PEP 660 - Editable installs for pyproject.toml based builds (wheel based)**
Status

Accepted

Created

30-Mar-2021

Type

Standards Track

pine cosmos
paper echo
#

Are editable wheels a security risk

#

E.g. can you upload an editable wheel on pypi that links to some malicious payload?

#

Or is that no worse than just uploading the payload directly as a wheel

naive saddle
#

although I'm not sure if say PyPI would block it

paper echo
#

but they could and it'd be spec-compliant

naive saddle
#

I can't imagine it being worse than just uploading a payload directly as a wheel

paper echo
#

right

raven ridge
#

a non-editable wheel could already contain a .pth file, and .pth files are evaluated whenever the interpreter starts, regardless of whether the installed module is imported or not

naive saddle
#

oh huh

#

I'm not surprised as the install operation is usually unpack + entry_point scripts but I never considered that

raven ridge
#

yeah, but the things that are unpacked can include .pth files, which will be used by the next run of the interpreter automatically

#

in other words, even with a regular wheel, ```py
python -m pip install some_lib && python -c 'print("hello world")'

naive saddle
#

Indeed

naive saddle
#

finally, I hacked up a functional build_editable, it's very specific to my setup but at least it works =p

delicate sage
#

How does __future__ work? like before python 3 released, it wouldn't have existed in python 2 right?

#

it did? but it didnt have the print_function right?

raven ridge
#

yes, it did.

#

it was added in 2.6

delicate sage
#

oh

#

oh nvm

undone hare
#

Hey @still torrent, please claim an help channel like said in #β“ο½œhow-to-get-help pixels_snek_2

Sorry for deleting your message, that was a missclick. Lmk if you want me to DM you the original content.

fallen slateBOT
#

failmail :ok_hand: applied mute to @unkempt rock until <t:1634559849:f> (9 minutes and 59 seconds) (reason: duplicates rule: sent 4 duplicated messages in 10s).

forest kite
#

How do you fix a bug which does not occur when run from source but happens only when you run it from binary/installed package?

#

Like what can be said about the nature of the bug?

pliant tusk
#

Depends what the bug is

forest kite
#

thats what i want to know

#

how do you approach to debug?

#

I ran the program(from source) using different shells but none of them reproduces it.

verbal escarp
#

you can try to aspectize all functions and methods

#

that is, decorate everything with log.debug to log all function calls and their parameters

forest kite
#

hmmm

verbal escarp
#

decorating everything manually usually is too much trouble, but you can do it programmatically

#

advantage is that decorating stuff doesn't care about interpreters and runtimes

#

disadvantage is that some decorators don't play nice with others

#

i've had good success with that approach, though

forest kite
#

i will try it!

verbal escarp
#

performance implication is also limited which makes it suitable to debug "realtime" applications like pyqt

#

if you need help with it, just poke

forest kite
#

i will

verbal escarp
#

(shameless plug: if you were using justuse, you could do that in the future with mod = use(your_thing) @ (use.isfunction, "", decorator) πŸ˜‰ )

forest kite
#

ok. now its really weird

#

Bug does not reproduce when its compiled using make. It happens only when installed through a package manager

heady mauve
#

Is there a way to prevent an instance of python.exe from being able to open files or certain libraries? The current train of thought is to run the "sandboxed" instance of the interpreter via subprocess and do whatever shenanigans to prevent it from doing certain things. I would have to have a whitelist of imports that would be allowed and only allow those.

#

IE: allow numpy, configparser, but not sys, os, ctypes, importlib, etc.

pliant tusk
#

@heady mauve not easily

heady mauve
#

As my research thus far has shown

sly jay
#

@heady mauve even if you block all those imports it's not actually hard to execute arbitrary things.

#

The generally correct way to do what you want is to limit the user which Python is running as to access only certain things on the system.

#

I.e, create a new user with basically no privileges, and then give that user privileges on only what your program needs

#

You can do more advanced configurations but this is the simple way

raven ridge
#

Or use containerization to give the process its own private system to abuse.

sly jay
#

That too

#

windows group policy has a ton of options but that's kind of a big ball of wax worth studying entirely on its own

#

plus you generally don't and shouldn't work directly with group policy as an application developer. You define what permissions your application needs and then it's up to the sysadmin to configure the policy however they want within those parameters.

junior surge
#

I was about to post this to the Stanford server: "My nineteen year old daughter is enamored of Harvard. Please help me show her the error of her ways."

unkempt rock
#

!e Hmm py print(124849745640593184256214502788000232711984346194239284918599169775251467106591187580476305077269760425019686159071753053924227569816588462643229463821875763427430576080998505780547826368760514503807579784278708008217584939464444237989070811887584423210788916656247499281**0.5)

fallen slateBOT
#

@unkempt rock :white_check_mark: Your eval job has completed with return code 0.

3.5334083494636332e+134
unkempt rock
pliant tusk
unkempt rock
#

Really I though it was a standard lemon_thinking isn't that the point

red solar
#

windows py2.7.18

3.53340834946e+134
windows py3.9.5
3.5334083494636337e+134
ubuntu py3.6.9
3.5334083494636332e+134

#

ok well py2 wasn't very helpful there

#

i want to assume it's due to difference in rounding modes for the platforms? I can't think of another reason, the hardware representation should be the same (both platforms are x86_64 and use IEEE754 64bit double afaik)

#

and PyFloat just has an double fval member to store the double as is

#

hmm

unkempt rock
#

!e more digits may help ```py
x = 124849745640593184256214502788000232711984346194239284918599169775251467106591187580476305077269760425019686159071753053924227569816588462643229463821875763427430576080998505780547826368760514503807579784278708008217584939464444237989070811887584423210788916656247499281
print(f'{x**0.5:.1000}')

my pc gives: 353340834946363365023871148628525120617391104199092003518319856057556622071902666612556464998161371385578049019244746510418552744312832.0```

fallen slateBOT
#

@unkempt rock :white_check_mark: Your eval job has completed with return code 0.

353340834946363324676216803520578407243654041652031467116666843100939234092850220664937370985017705297369404017091130324431490670133248.0
raven ridge
#

I don't know if this is what's causing that or not, but modern CPUs have 80 bit floating point registers that are used for intermediate results, so that operations with 2 64-bit floats can be performed with less loss of precision, even though the final result needs to be rounded back down to 64 bits.

red solar
#

Floating-point contractions, machine instructions that combine floating-point operations, may be generated under /fp:precise.

#

What u said?

#

(Maybe gcc doesn’t do this with the flags cpython gets compiled with?)

#

/fp:precise is the default for msvc

unkempt rock
#

According to mathematica the result is 353340834946363345257473017597911079933781446508208388719162940497886257062411267034976578524965264261618554821962433800999907190674409 but idk whether to trust it lemon_glass

raven ridge
#

That's one of the leading reasons for differences of the sort that you're showing, anyway. It could be that in one case the generated machine code is able to keep the result in the 80 bit register longer, and is able to get slightly better precision.

unkempt rock
#

!e oh it works exactlypy y = 353340834946363345257473017597911079933781446508208388719162940497886257062411267034976578524965264261618554821962433800999907190674409 x = 124849745640593184256214502788000232711984346194239284918599169775251467106591187580476305077269760425019686159071753053924227569816588462643229463821875763427430576080998505780547826368760514503807579784278708008217584939464444237989070811887584423210788916656247499281 print(y*y == x)

fallen slateBOT
#

@unkempt rock :white_check_mark: Your eval job has completed with return code 0.

True
raven ridge
#

But also, floats only have 17 significant digits of precision, anyway. You shouldn't expect accuracy with numbers this large

unkempt rock
#

I know ducky_australia

prime estuary
#

Interesting report from Łukasz Langa, our Developer in Residance with statistics about the CPython codebase:
https://lukasz.langa.pl/f15a8851-af26-4e94-a4b1-c146c57c9d20/

elder blade
unkempt rock
#

!e Decimal works given enough precision ```py
import decimal as d
y = 353340834946363345257473017597911079933781446508208388719162940497886257062411267034976578524965264261618554821962433800999907190674409
x = 124849745640593184256214502788000232711984346194239284918599169775251467106591187580476305077269760425019686159071753053924227569816588462643229463821875763427430576080998505780547826368760514503807579784278708008217584939464444237989070811887584423210788916656247499281
d.getcontext().prec = len(str(y))
s = d.Decimal(x)**d.Decimal(1/2)
print(f"{s:f}")
print(y)
print(y == s)

fallen slateBOT
#

@unkempt rock :white_check_mark: Your eval job has completed with return code 0.

001 | 353340834946363345257473017597911079933781446508208388719162940497886257062411267034976578524965264261618554821962433800999907190674409
002 | 353340834946363345257473017597911079933781446508208388719162940497886257062411267034976578524965264261618554821962433800999907190674409
003 | True
unkempt rock
#

Fractions got off pretty quickly

elder blade
unkempt rock
#

Yeah but sqrt needs floaty stuff I guess?

elder blade
#

So you're just creating a decimal with no decimals?

unkempt rock
#

Oh I though you were asking about fractions

#

the goal was to take sqrt of x which is where the floats come in

#

but it is a perfect square

heady mauve
elder blade
#

Are you reinventing subinterpreters lmao

timber island
#

there is the mysql.connector thing for ur responses in python to mysql is there something like that for csv files

paper echo
red solar
#

the c-api provides a way to give members their own docstring

#

is it possible to do this in Python too? all i could find was giving functions/methods and classes docstrings

paper echo
#

i don't think so unfortunately

#

sphinx supports it with

class Thing:
    x : float
    """The 'x'."""

but python itself doesn't

red solar
paper echo
#

(i don't think there's any sensible distinction to be made between a class attribute and a static attribute)

red solar
#
>>> a = Thing()
>>> a.x
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'Thing' object has no attribute 'x'

i haven't done python in a while, but what am i missing here?

paper echo
#

the type annotation just says what its type should be if it exists

#

there are no uninitialized variables in python

#

it declares the type, but doesn't make it exist

red solar
#

oh, i need x: float = 5 for it to actually exist?

paper echo
#

you still have to assign to it, e.g. in __init__

#

yes:

class Thing:
    x: ClassVar[float] = 5.0

    y : float

    def __init__(self):
        self.y = 0.0
red solar
#

wym by ClassVar? (i get that it's a type annotation, but i thought we said x was still part of the instance?)

#
>>> class Thing:
...     x: float = 5
...
>>> Thing.x
5
>>> a = Thing()
>>> b = Thing()
>>> a.x
5
>>> b.x
5
>>> a.x = 4
>>> a.x
4
>>> b.x
5
paper echo
#

ClassVar declares that it's a class member

#

without it, it's an instance member

red solar
#

but it's an annotation? annotations can actually affect things?

paper echo
#

nope, that's why you need a static type checker to check these things

#

without a type checker like mypy, annotations are just suggestions / documentation

red solar
#

ah ok

paper echo
#

everything after the : is ignored at runtime, and in 3.10 they aren't even evaluated, they're just left as strings

pliant tusk
#
Python 3.10.0 (default, Oct  5 2021, 01:38:49) [Clang 12.0.0 (clang-1200.0.32.29)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> a:print(1)
1
>>> class a:
...     x: print(1)
... 
1
>>> ``` i think they are still evaluated
paper echo
#

huh

#

i thought that was the whole point of from __future__ import annotations

#

maybe it's just a repl thing?

#

i guess you still need from __future__ import annotations in 3.10

#

i thought it was on by default in 3.10+

#

i just tried it, that seems to be the case

peak spoke
#

the pep didn't make it to the release because of libs that use annotations for non type hinting purposes

paper echo
#

ty, didn't realize

grave jolt
#

Actually, how are they going to solve things like this?

def make_foo():
    Item = GenericItem[int, str]
    def foo(item: Item) -> str:
        return item.name
    return foo

inspect_annotations(make_foo())
peak spoke
#

There is an another PEP proposed that I think handles that for the evaluation

paper echo
#

so mypy knows that Item is a type alias, python at runtime knows you're just assigning something opaque to something opaque

#

but that's why you can't do TypeVar('T', bound=str | bytes) in 3.8 even with from __future__ import annotations, because that isn't on the RHS of : so it still has to get evaluated

grave jolt
#

Yes, that's what I meant

#

because stringly annotations are just that - strings - my example will break

elder blade
#

Sucks if you're trying to support anything older than that though :/

boreal umbra
#

For those visiting this channel for the first time, please refer to the channel description. If you're looking for help with a specific problem, see #β“ο½œhow-to-get-help.

obtuse knot
#

This is more of a question about low-level and OS code, but with current process affinity and scheduling, the core layout is homogenous
With existing ARM big.LITTLE CPU's and upcoming Intel versions of big.LITTLE, the core layout is heterogeneous with a set of high performance and a set of high efficiency cores, some of which may or may not have simultaneous multithreading

Are there existing or planned ways to get and set the CPU core affinity and scheduling for processes on these CPU's?
I know the general idea is to let the OS handle scheduling, but the other recommendation I've heard is to set the affinity for programs to either the high performance or the high efficiency cores, rather than setting the affinity on a per-core basis

red solar
#

Why do I feel like i’ve seen this question asked before?

#

Did u ask it on a Python mailing list?

opal warren
#

hi fellas

#

i want to develop a program which can identify difference between 'ideal image" and 'difference image' . can anybody help

opal warren
red solar
obtuse knot
#

Thank you for the link to the mailing list post! I'm pretty I've never posted this question on any Python mailing list
I'm less about super fine control like setting individual cores to a task and more about "this task is a priority and should be scheduled into the high performance core" or "this task is less CPU-bound and can sit on a high efficiency core"

#

We're both in the Raspberry Pi discord server, and I think I posted a similar question there before they purged their programming channel and made a new one

obtuse knot
# red solar Tbh i’m of the opinion that if you need such fine control over your cpu, Python ...

It's already possible to set specific CPU core affinities with either os.sched_setaffinity and os.sched_getaffinity for Unix systems, or with the pywin32 library for Windows, and the psutil works on pretty much all operating systems.
There just isn't a specific way to see that core A is different in performance/power draw than core B.
Comparing CPU frequency is one thing, but you can have situations where a higher frequency doesn't mean that the core is faster when it comes to things like IPC and such

toxic birch
#

Hey guys this might be easy but for me it is advanced topic: Can anyone tell me which programing path comes natively when you use a MacBook Pro with M1 chip?

verbal escarp
solar haven
#

Hello! How do you type your packages? Do you create a types.py module? For example, do I create a T = TypeVar("T") in every module?

verbal escarp
#

you mean add type annotations to python code or something else?

solar haven
verbal escarp
#

is it your own code?

solar haven
verbal escarp
#

then just add the annotations right inside your code

#

you write your python code as a prototype. when you're confident about the code structure, you start adding annotations everywhere, maybe use beartype and icontract while you're at it

solar haven
verbal escarp
#

what do you mean by "repeated types"? if you have a class you want to use across your project, you annotate it once in a module and import it everywhere else

solar haven
verbal escarp
#

why do you need a TypeVar? can you give some concrete code?

solar haven
verbal escarp
#

my point is that you shouldn't use those placeholders if you can avoid them - just write your code until you're happy with the structure and nail down things with concrete types

#

there's no point in using placeholders if you only do it to make some nitpicking typechecker happy

#

there are some cases where you can't avoid them, but those are rare

#

are you sure you need TypeVar?

solar haven
verbal escarp
#

well, what are "any types" in your case? πŸ˜‰

#

is that function supposed to be called by a user from an outside library?

#

or is it internal to your own code? in that case you could specify the exact types as a union

lusty scroll
verbal escarp
lusty scroll
#

because it makes it 99,999 times easier to inspect

#

oh

solar haven
verbal escarp
#

so - don't annotate, write your code and when you know which types are passed in, you can pin it down

lusty scroll
#

but if you know it doesn't hurt to annotate, you could always change it

#

I mean in other languages people don't even have the luxury of choosing

#

it's List<? externds Entry<? super T>> right off the bat 🀣

#

guess that's part of the the benefit of the dynamic typing

solar haven
lusty scroll
#

mypy ? πŸ˜…

solar haven
lusty scroll
#

yeah it's quite an effort to appease it. I sort of see @verbal escarp 's point. if you have to get it by mypy, it would be quite a bit of extra work during development

#

the insistence on explicit Optional made me stop using it

verbal escarp
#

yeah, using Any wherever it was unclear did it for me

#

if you need to resort to those, your code just isn't ready for actual typechecking yet

feral cedar
#

isn't that the same as just not typing it

verbal escarp
#

yeah, but mypy won't complain

#

defeating its purpose, really

feral cedar
#

huh, I thought it just checked stuff you had typed

verbal escarp
#

usually you can't clearly separate those

feral cedar
#

ic

lucid anvil
#

im working on my own language, need opinion for something. Should i enforce indent blocks for conditions, loops and things alike or just have end keyword instead

verbal escarp
#

if it's your own language, why are you asking in a python channel? πŸ˜„

lucid anvil
#

i'm not even sure how if statments with else looks like?

if condiiton
  do_something
else
  do_nothing
end

- or is it -

if condition
  do something
end
else
  do_more
end```
#

because im writing the compiler and interpreter in python

#

LMAO

boreal umbra
#

Also, please refer to the channel description for this channel.

lucid anvil
#

ooo

#

ok

astral gazelle
#

<@&831776746206265384>

boreal umbra
#

!mute 894585668771139674

fallen slateBOT
#

:incoming_envelope: :ok_hand: applied mute to @crimson plaza until <t:1634736511:f> (59 minutes and 58 seconds).

last panther
lucid anvil
#

wdym?

#

thats what im trying to decide lol

last panther
#

Well if you’re creating your own lang try to make it minimalistic

lucid anvil
#

i am. still trying to decide if end is better than enforcing indent blocks

last panther
#

Compare memory consumption

lucid anvil
#

meh not worried

#

its just about user preference

last panther
#

Then don’t bother

lucid anvil
#

with which?

#

i just wanted opinions on what others think is better lol

last panther
#

Is this a project or for production?

#

Personally I prefer typing less

#

The backend should be able to determine the scope by indentation.

#

Anyone working on a project that would like a contributor?

verbal escarp
last panther
lucid anvil
halcyon trail
#

I would say neither indent nor begin/end are the way to go, but braces. But this is a long discussion on language design that only touches somewhat on python

verbal escarp
#

why not both braces and indents πŸ˜‰

halcyon trail
#

because what purpose do the indents serve at that point?

lucid anvil
#

lmaooo

#

god

halcyon trail
#

err, nobody is saying that the code wouldn't be nicely indented?

red solar
#

Oh

halcyon trail
#

this is just the definition of the language grammar

red solar
#

Ok nvm

halcyon trail
#

hah I see now why you reacted that way, the rolling eyes seemed a bit harsh πŸ™‚

lucid anvil
#

LMAOO

red solar
#

That’s rolling eyes? I thought it was just looking up maybe slightly exasperated

lucid anvil
#

im just tryna figure out what people prefer πŸ˜”

halcyon trail
#

I just put my mouse over it and saw what popped up πŸ™‚

astral gazelle
#

uh, does python do loop unrolling and if yes, does the bytecode reflect that unrolling (where can i see it)

flat gazelle
#

honestly, it makes no difference, syntax is quite insignificant compared to other properties of a language

halcyon trail
#

Eh, I don't really agree, python's delimitation by whitespace has definitely had consequences for the language

astral gazelle
#

alright well that solves a whole bunch of questions i guess haha

red solar
#

Isn’t there a niche case of unrolling with strings somewhere?

halcyon trail
#

it's been oft-cited as the reason why it's so hard to come up with a multi-line lambda syntax

flat gazelle
#

yeah, I wouldn't go with indents personally, since it makes the grammar really hard to express sensibly.

#

and multiline lambdas are also an issue

halcyon trail
#

My $0.02 is that at this point in time, it's been more-or-less-proven that braces + auto-formatters are the way to go

flat gazelle
#

but in the end, nim has multiline lambdas and indentation based syntax

halcyon trail
#

when python was created good auto-formatters didn't exist

flat gazelle
#

but yeah, braces are probably the way to go

halcyon trail
#

so python's take was a reasonable solution on solving the problem of "how do we ensure that the what the code does and what the code appears to do agree?"

#

Python was developed in like 1990. "production level" auto formatters weren't a thing until like 15+ years later.

#

when google said "we want to just run this auto formatter on a billion lines of C++" and they developed clang-format, and that kicked off the trend

#

the irony is that not only does the whitespace put python in a tougher position parsing wise, but python still wants/needs auto-formatters, and then they end up not working as well in python as in many brace-based languages

lucid anvil
#

Braces are kinda ew tho

#

Like they're good but it's kinda eye sore at times

halcyon trail
#

compared to begin/end?

lucid anvil
#

Just having end

#

Wouldn't be so bad

halcyon trail
#

eh, it's a lot more intrusive than braces

#

Kotlin/Swift have done some really amazing things with braces in their syntax

verbal escarp
halcyon trail
#

But there's no reason to have both in a new language....

flat gazelle
#

braces are more or less the standard, you would be hardpressed to improve on them

halcyon trail
#

^

lucid anvil
#

Hmmm

halcyon trail
#

If you want to write a new language with nice syntax, I'd really start by looking at Kotlin/Swift, they're two of the newest mainstream languages, they allow you to do very slick things with their approach to creating and passing lambdas

lucid anvil
#

I just don't think braces suit the language style. My language is more python like

flat gazelle
#

sure, go with end then, like julia

#

it doesn't really hard anything

verbal escarp
#

i don't like braces either, it's more to type and more visual noise

lucid anvil
#

So end > forced indents?

flat gazelle
#

forced indents I wouldn't hate, but they do have issues and with automatic formatting, they are a lot less needed

lucid anvil
#

Fair

flat gazelle
#

also they are a damn pain to implement

halcyon trail
#

i guess it really depends what you want your language to look like

#

END seems fine when you are mostly thinking about basic constructs like loops, if

lucid anvil
#

Loops, ifs and macros/functions

visual shadow
#

there is a case to be made for forced indents being easier to read, simply because even with braces we've seen indentation make things nicer

flat gazelle
#

ruby has end and does just fine being one of the most expressive languages

halcyon trail
#

Less fun when you start thinking about lambdas

lucid anvil
#

Anything that requires its own scope

#

Thing is you can still use indents with end it's just not required

visual shadow
#

so then the thought goes: if we have to* indent anyways to make things easier, then why have extra syntax on top

lusty scroll
#

i like braces

halcyon trail
lusty scroll
#

πŸ‘€

lucid anvil
#

Braces are just

#

I want to go minimal. Cleaner.

flat gazelle
#

the issue with forced indents is when you need a block as part of an expression

verbal escarp
#

i would like to have braces with lambdas, simply because indents don't work well inline

halcyon trail
#

but END is not more minimal than braces

lucid anvil
#

Originally went enforcing indents but maybe that's annoying

flat gazelle
#

which is something a modern language should always do

visual shadow
halcyon trail
#

and whitespace-only has a lot of practical issues once you go beyond the basics

lucid anvil
flat gazelle
#

nim has that syntax, and it gets confusing

visual shadow
#

sounds like, just have braces for scope, forced indentation for indents, win win? or no good.

lusty scroll
#

end is definitely the worst of all worlds though

halcyon trail
#

still 3 characters instead of 2. and END to me looks very bizarre at the end of a line as opposed to on its own line

verbal escarp
flat gazelle
#

end is just fine

lucid anvil
#

Optional*

flat gazelle
#

opening braces aren't exactly needed

lucid anvil
flat gazelle
#

they are in C because of the way C syntax works

halcyon trail
#

needed for sanity πŸ˜‰

lusty scroll
#

end with no begin πŸ‘Œ πŸ‘Œ

flat gazelle
#

but they don't actually help the syntax over just not being there

halcyon trail
#

I think END is ok though, kidna ugly but eh. Still better than whitespace. If you want end then look at Ruby.

lucid anvil
verbal escarp
#

like an implied comment - something like ```
foobar for ...:
...
end foobar

flat gazelle
#

yeah, ada does that

#

it is pretty neat

lusty scroll
#

thinking of sql server's ugly
end else begin

halcyon trail
#

you have to label every for loop in Ada?

lucid anvil
#

So like

if 1 + 1 == 2
     do stuff
end if
#

?

flat gazelle
#

ah no, it just does it for procedures and a few other constructs

#

no reason to have end if

lucid anvil
#

Exactly

#

Just end

halcyon trail
lucid anvil
#

Yeah so what's the tag?

lusty scroll
#

it's not ambiguous with no tag right

raven ridge
# verbal escarp i would like to have braces with lambdas, simply because indents don't work well...

there's no reason we couldn't have multi-line lambdas by wrapping the entire thing in parens. There's no reason that Python couldn't have:

def sort_the_list(lst):
    lst.sort(key=def lambda elem: (
        field1 = elem.field1
        field2 = elem.field2
        return (field1, field2)
    ))

Python has multi-line lambdas today. What it doesn't have today are multi-statement lambdas. (My def lambda here is pseudocode for "a lambda that allows statements")

verbal escarp
#

not ambiguous but harder to parse visually

halcyon trail
#

also, afaics that is still whitespace dependent

#

how do you know where the if clause ends and the body begins?

lucid anvil
#

Check if the indent level is greater by one then the If statement

halcyon trail
#

so now you dependent on whitespace and use end

#

so this is pretty much the worst of both worlds tbh

lucid anvil
#

But I didn't like that it was so annoying

#

LMAOO

lusty scroll
#

in cmake they're optional

flat gazelle
#

well, right now indentation in expression doesn't exist

lucid anvil
#

Nono I said originally I was using enforced indents

halcyon trail
lucid anvil
halcyon trail
#

well, if you're determined to use whitespace, then just use that? Why ask here?

#

I'm confused.

lucid anvil
#

I'm just curious about people's preferences

flat gazelle
#

I will not make a decision about a language based on their block syntax

raven ridge
flat gazelle
#

I like pascal despite their insanity

lucid anvil
flat gazelle
halcyon trail
lusty scroll
#

fortunately

halcyon trail
#

So it can't be parsed, unless how it's parsed is changed, so that it can be parsed?

flat gazelle
halcyon trail
#

Yeah I think we agree πŸ™‚

lucid anvil
halcyon trail
#

lol

lucid anvil
#

Lmaoo

halcyon trail
#

this is called a "distinction without a difference"

verbal escarp
flat gazelle
#

yes, it is possible, look at nim

raven ridge
# raven ridge yes, exactly.

it's not a fundamental limitation of using indents rather than braces. It's just a limitation of Python as it exists today.

halcyon trail
#

yes, that is not in question

flat gazelle
#

but honestly, it gets really messy in nim

halcyon trail
#

good to know

#

I stopped reading about nim after I saw the whole foo_bar will automatically call fooBar thing or whatever it was

flat gazelle
#

I still argue that it is great in a glue language

halcyon trail
#

maybe in theory, but it has minimal traction, and if there's one crazy decision like that, there's going to be others, and it's probably not going to get traction

flat gazelle
#

if you have 2 libraries, where one is in C and one is in python, they will use different conventions, and you can still use the same one in your code using both

#

but yes, nim is more or less useless

halcyon trail
#

when you see a decision like that you immediately know 99% of the decisions in the language are made by one person because the odds of two randomly sampled software engineers thinking that's a good idea are 0

#

the same is true with Pony's divide by 0 = 0 thing

raven ridge
verbal escarp
#

somebody didn't pay attention in maths there

lusty scroll
#

undefined is so much better than 0 /s

flat gazelle
#

it doesn't do enough to be worth adopting

#

well, pony has 3 division operators

#

but yes, trying to be a theoretically sound language while focusing on performance is silly

#

should've just not been cowards and gone with / is a partial function

raven ridge
#

in a language without exceptions, making x / 0 return 0 doesn't seem crazy to me. Why return a sentinel value like undefined or an error return code that the user will have to check, when the user could just check the divisor before calling /?

verbal escarp
halcyon trail
#

because 0 is a nonsense value... when a function gets nonsense input, it shouldn't guarantee that it returns a specific nonsense value

#

0 is also reachable by division in other ways, so it doesn't work well as a sentinel

#

it's just terrible

flat gazelle
#

well, that's what /? is for

#

but yes / being useless is a bad decision

halcyon trail
#

I stopped reading about Pony after learning about divide by /

#

there's so many languages that are actually good and in use that I know much less about than I want to

raven ridge
halcyon trail
#

it's nice for performance

#

and if you use C++, you care about performance

lusty scroll
flat gazelle
#

Pony has this really cool actor model runtime thing with insanely strong guarantees, atop which a wonky language is written

raven ridge
#

it's nice for performance, but really, really bad for correctness.

elder blade
flat gazelle
#

I mean, pony also has /!, which does UB given 0 as a divisor

halcyon trail
#

yes, but C++ is performance focused? I don't know what else to say.

verbal escarp
raven ridge
#

yeah. I'd be willing to bet that >90% of real-life C++ programs are ill-formed.

halcyon trail
#

C++ is not only performance focused, but it's only very focused on running on a very wide variety of hardware

raven ridge
#

which means that the fact that they work is just dumb luck.

halcyon trail
#

ill-formed and UB are two different things

#

and no, not really

lusty scroll
#

if this teaches anything it's that language design is a minefield

elder blade
flat gazelle
#

like idk, I don't really care about minor problems like picking a bad / default

halcyon trail
#

there's a lot of UB that is in practice guaranteed on a specific implementation, that people end up depending on

#

for sure developing for C++ is a headache relative to most languages but it's not dumb luck

flat gazelle
#

there are more useful ways to do division than just /

elder blade
raven ridge
verbal escarp
#

in a language that doesn't have exceptions, you will have to cover every goddamn corner case properly

elder blade
#

Segfault or-?

flat gazelle
#

yeah, I would argue that pony shouldn't have / at all and force you to choose between /? which is more or less a checked exception and /!, which is the raw LLVM instruction

raven ridge
#

we were talking about Pony, which doesn't, AFAIK

halcyon trail
elder blade
flat gazelle
#

things don't go wrong

verbal escarp
#

and returning undefined is proper behaviour for some operations in math

#

that's a sad fact

flat gazelle
#

you are forced to handle all erroring states

#

except signals

#

the language will not crash except by running out of memory or being killed by the OS

raven ridge
#

that's an alternative way that it could have been handled. divide by zero could trigger a SIGFPE signal.

halcyon trail
#

the actual problem is probably simply that integers don't have representations for NaN/Inf/-Inf like float do, and they don't have built-in handling of these things the way that floating point does

#

(on modern hardware)

#

so the buck gets passed to the programming languages

#

and there is no great solution, but there are some terrible ones

elder blade
lusty scroll
#

like checked exceptions?

#

another terrible idea

flat gazelle
#

there is no panic

elder blade
flat gazelle
#

except you can of course bypass it with C interop

raven ridge
# halcyon trail ill-formed and UB are two different things

AFAIK, that's not a correct nitpick. UB is a special case of "ill-formed, no diagnostic required". But regardless, it is absolutely true that programs depend on how their current compiler behaves in the presence of UB - which means that compiler upgrades frequently break C++ programs, because those programs have always been incorrect.

verbal escarp
#

couldn't exceptions be handled in a seperate overwatcher thread?

#

so that when something happens there's a way to resolve and return?

elder blade
# flat gazelle yes

Is there an equivalent to RuntimeError because it seems awfully annoying to having to deal with that in a program like asyncio where get_running_loop() may raise RuntimeError if the event loop isn't running... even though you are in a task/coroutine which has to have an event loop running to execute.

lusty scroll
#

if something goes wrong, just let it burn

flat gazelle
#

like, that wasn't really an inconvenience for me

halcyon trail
#

IFNDR is usually discussed in relation to compile/build time

#

UB in general depends on runtime

elder blade
flat gazelle
#

yes

halcyon trail
#

it's not at all a nitpick, I wasn't trying to nitpick

#

this is how C++ engineers use these terms, day to day

flat gazelle
#

or declare the caller as partial, at which point it can call partial functions without an explicit check

raven ridge
halcyon trail
#

UB is not entirely about what the compiler is allowed to emit, no

#

that's just wrong

#

UB affects what the compiler is allowed to emit, yes

#

whether your program actually has UB or not can depend on runtime values

raven ridge
#

true.

elder blade
# flat gazelle yes

So what happens if you want to make a function call inside of an except, and this can raise an error? Handle that as well?

I think I feel satisfied with this conversation though because I know that APIs will be designed differently to account for this annoyance

halcyon trail
#

Anyhow, I honestly did not mean to turn this into nitpicking. IFNDR is most commonly a think when you have some kind of error between TU's that only the linker could in theory diagnose but it cannot because the linker is shit.

lusty scroll
#

the program either has undefined behavior or not, though, I thought.

raven ridge
halcyon trail
#

IFNDR can cause UB, e.g. ODR, but there are many other ways of causing UB, most commonly having to do with things that happen at runtime e.g. dereferencing a null pointer

#

"the program" in the sense of the whole run of the program, including its inputs, is technically what has UB or not

#

in practice some programs will have UB every time they're run, regardless of inputs, so then we might just say "this code has UB" which is essentially shorthand

lusty scroll
#

the compiler would be allowed to make whatever assumptions ut wants, if, say, you forget to check before dereferencing somewhere, I think

halcyon trail
#

correct

#

the compiler assumes that UB never happens

#

so if you dereference a pointer, afterwards the compiler can assume it's not null

#

fun things like that

lusty scroll
#

including removing your checks

halcyon trail
#

yep

raven ridge
#

which was the cause of a recent-ish Linux kernel security vulnerability.

halcyon trail
#

it seems crazy, because people think "why would I write checks only to have them removed"

#

people tend to not consider how much inlining happens in a real program

#

and when inlining happens, you end up with code next to each other that's silly and redundant, so these optimizations make sense

raven ridge
#

even across TUs, with LTO.

halcyon trail
#

yeah

lusty scroll
#

ODR violation counts as UB?

halcyon trail
#

i'm sympathetic to people who find all the UB and edge cases in C++ rough, I do too.
Not sympathetic to people who want the compiler not to optimize UB.

#

yeah I'm pretty sure

#
One and only one definition of every non-inline function or variable that is odr-used (see below) is required to appear in the entire program (including any standard and user-defined libraries). The compiler is not required to diagnose this violation, but the behavior of the program that violates it is undefined.
raven ridge
#

the same people who think "why would the compiler remove that check, I wrote it for a reason" are the people who otherwise would say "oh, that's OK, that will get optimized out", and not realize that it's exactly the same process that's allowing one bit of clearly useless code to be optimized out as another.

halcyon trail
#

hah, it is? πŸ™‚

#

I've been tripped up by ODR rules many times

#

literally yesterday in fact

lusty scroll
#

that you're screwed 🀣

halcyon trail
#

LOL

#

I got played

lusty scroll
#

yes, same

halcyon trail
#

Being a C++ engineer is like being a well paid Sisyphus

raven ridge
#

yeah, you ain't wrong.

lusty scroll
#

it is nice to get warned about it

#

even though NDR

halcyon trail
#

you don't really get warned for it in the situations that matter

#

because, remember, the linker is 50 year old dogshit

#

It doesn't know anything about C++

#

or even C

#

it just knows symbols

lusty scroll
#

with LTO i guess you do at times

halcyon trail
#

C++'s build stack is the craziest thing imaginable by modern standards

#

Yeah, that could be true, perhaps LTO allows issuing extra diagnostics, I can't speak to that

#

we don't really use LTO, the way our application is structured it's not that useful

halcyon trail
#

I'm withholding judgement πŸ™‚

lusty scroll
#

any day now..

#

but yeah, C++ pretty much decided exception specifications are junk

#

the prognosis for compiler-verified error handling doesn't seem bright

#

another feather in the cap of "don't save the user from themselves"

elder blade
#

I think you should save the user from themselves, but you shouldn't protect them from themselves

#

Though guess it's hard to differentiate with a compiler like that

halcyon trail
#

Well, you can only compiler verify up to a certain point really

#

trying to really have the compiler verify error handling was tried... it's called checked exceptions

#

and it was a disaster

#

if you look at more modern languages, what they mostly tend to veriffy at the compiler level is "can this function error or not" but in many/most cases they don't try to verify "did you handle all the possible errors" outside of the immediate context

elder blade
# lusty scroll what's the difference?

You should simplify API and raise errors and warnings (saving them from normal mistakes made), but if someone wants to get down into the internals and do some advanced stuff you should allow them to do so (meaning that you don't protect them from it).

elder blade
#

Exactly πŸ˜‰

#

But it extends to libraries too I think

halcyon trail
#

eh I mean python is nice in that it's simple and readable but definitely goes way too far in not even trying to protect users from many kinds of errors, unnecessarily.

#

but then it's dynamically typed so what do you expect

noble kelp
#

a long standing requests.Session seems to drop connections, i think due to linux not enabling TCP keep alive, I've seen some suggestions that altering the HTTPConnection socket options in urllib can alleviate this error. anybody have experience in the area?

lusty scroll
scenic geyser
#

why do we create class inside a class?

flat gazelle
#

it is quite rare to see this. One case I can remember is django using a nested class for metadata about a model, but it is very rarely the correct thing to do

halcyon trail
#

it's usually a bad idea. nested functions often makes sense because when a function is nested it can capture some nested state, which is useful

#

but classes already are designed to capture state, in another way, explicitly. So when you have a nested class, now you potentially have both explicit, and implicit state, being used inside the class.

astral gazelle
#

sqlalchemy moment

scenic geyser
#

@halcyon trail by nested functions you mean decorator functions right?

halcyon trail
#

No I mean like defining a function inside a function generally

spice pecan
#

!e Functions enclosed in other functions, like this: ```py
def adder_maker(num):
def adder(other_num):
return num + other_num
return adder

add5 = adder_maker(5)
print(add5(10))```

halcyon trail
#

Often when you write decorators you do implement them that way

fallen slateBOT
#

@spice pecan :white_check_mark: Your eval job has completed with return code 0.

15
scenic geyser
#

ah

noble kelp
lusty scroll
lusty scroll
halcyon trail
#

err yeah

#

what do you mean by "reliably"

#

it either works or it doesn't?

spice pecan
#

so yeah, it is reliable

lusty scroll
#

nice

lusty scroll
noble kelp
halcyon trail
lusty scroll
halcyon trail
#

@lusty scroll can you give a code example or a link explaining it?

#

afaics Java is actually doing this to save you from shooting yourself in the foot, in a way that is easy to do in python

#

seems like a mix of that and also language limitations re heap and stack πŸ™‚ keep in mind that python will prevent you from trying to re-seat capture variables as well, a restriction with some of the same motivations. that's what nonlocal is for

lusty scroll
halcyon trail
#

yeah I suppose. on the flipside Java lambdas actually suck less than python's... who would have thought that would happen twenty years ago

feral cedar
#

it's hard to do worse than lambda as a keyword πŸ˜”

surreal sun
#

^

red solar
#

what's bad about lambda as a keyword?

feral cedar
#

compared to other symbols like: ->, \, it just looks terrible

surreal sun
grave jolt
#

yeah

#

it's like replacing tuple with Ξ 

#

and Union with Ξ£

surreal sun
#

I was really confused when I learned about lambda, as compared to other things in python, the name for the keyword wasn't that intuitive. It took me a while to realize it was just an anonymous function

feral cedar
#

i remember in a talk, raymond hettinger said it could have just been named makefunction

surreal sun
#

Why was it named lambda, a design choice from Guido?

grave jolt
#

IIRC it was copied from scheme or other lisp dialect

surreal sun
#

Ah

grave jolt
#

To be honest, lambdas are rarely useful in Python

#

you don't strictly need them

surreal sun
#

Yeah true

#

there's never something where you absolutely need them (I think)

#

they just make some things easier

grave jolt
#

I think def x: 42 would definitely make them easier to explain πŸ™‚

surreal sun
halcyon trail
#

lambda looks bad, and also the fact you can't have multiple lines

halcyon trail
undone hare
#

I feel like lambdas are made to be discouraging

surreal sun
#

Possibly

halcyon trail
#

they are in python

surreal sun
#

I really hope a core dev takes on PEP 505 soon

#

I would really love none aware operators

feral cedar
rich cradle
halcyon trail
#

idk, you could say the same thing about map

surreal sun
#

map is pretty nice

halcyon trail
#

possibly mostly backwards compatibility at this point

#

why map instead of list comp?

surreal sun
#

I prefer map(int, iterable) rather than [int(j) for j in iterable]

#

applying callables to each item in an iterable looks much nicer with map

#

personal preference ofc

halcyon trail
#

sure it's personal preference but also pretty explicitly against the grain of python

undone hare
surreal sun
halcyon trail
#

I mean list comprehensions are clearly the preferred way of doing things, by the language

#

they're much more common in real code, they extend better to the case of not having the exact callable you already need

#

they were introduced explicitly as a feature to the language when map already existed

#

so it's pretty obvious that was done because they think LC's are a better solution

surreal sun
#

You shouldn't use map for everything ofc, but I do love map for conversions and what not

halcyon trail
#

eh it's just a loss of consistency with no real benefit

feral cedar
#

something something only one way things should be done

feral cedar
#

from the zen

surreal sun
#

Oh

#

map would be pretty damn cool if we had function composition

halcyon trail
#

you still need nice lambdas for map to be cool

undone hare
#

I never used map, I always find comprehension way more readable

sand python
#

same

undone hare
#

I can understand it for reduce and stuff like that, along with checks

grave jolt
halcyon trail
#

LC's are nice but the fact that you have to first class it into the language has all kinds of downsides

grave jolt
halcyon trail
#

and also the fact that it can just be one expression is pretty lame

#

if you have more complex logic then in python you either define a function locally and then use an LC, or you create an empty list and append into it. both of these feel lame.

surreal sun
halcyon trail
#

it would be nice to be able to write stuff like

new_list = old_list.map {
    first line of logic...
    second line of logic...
    third line of logic...
}
sand python
#

map(lambda x: f(g(h(x))), iterable)

grave jolt
#

that is not point-free smh @sand python

feral cedar
#

what does that mean

surreal sun
#

what would yo uall think would be better function composition syntax, assuming f and g are callables

f @ g
or f + g

grave jolt
# feral cedar what does that mean

"pointful" is when you name the argument, like lambda x: f(g(h(x))). "point-free" is the opposite - you don't name the argument, like compose(f, g, h)

feral cedar
#

interesting

halcyon trail
#

neither πŸ™‚ I don't think function composition is worth having special syntax for

grave jolt
surreal sun
#

imo python having more functional features would be pretty nice, like function composition and the likes

#

i might learn haskell sometime soon

grave jolt
#

Python already has function composition, you can write a function that does it

#

but yeah, it's not as nice as .

surreal sun
sand python
#

"point-free" smh

grave jolt
#

speaking of new syntax, what about this? ```py
@EXPR1
with EXPR2 as TARGET:
BODY

<=>

with EXPR2 as __x:
TARGET = (EXPR1)(__x)
BODY

or maybe?

with EXPR2 as __x:
with (EXPR1)(__x) as TARGET:
BODY

Not sure where it would be useful... but that's a thought
surreal sun
#

using context managers for decorating? that looks interesting

#

oh wait

#

decorating context managers**

sand python
#

how would that work with multiple items in the with statement?

grave jolt
sacred sun
#

does anyone know c# and familiar with pyobjc? I'm trying to use the pyobjc-framework-Quartz to get the toupe of a window location in osx in python3. I found this script written in python that uses obj-c quartz wrapper but it lists info on all open windows. I'm trying to get toupe coordinate of specific window to feed to mss to take a screenshot for opencv/OCR. https://github.com/drksun/ocr-gspro-interface/blob/main/ListWindow_osx.py trying to get kCGWindowBounds by giving a kCGWindowName

#

the issue is the pyobjc-framework-Quartz documentation says see apple's doc and that's all in obj-c I'm confused

sacred sun
ashen summit
#

Hi, can someone help me figure out how to use functions in python?
I just started programming πŸ™‚

red solar
red solar
#

does PyPy have a buffer class? i keep seeing it referenced but I can't find it anywhere

#

or at least it doesn't appear on my pypy interpreter

#

ok nvm apparently i can do this:

from pypy.module.cpyext.api import (
    cpython_api, Py_buffer, Py_ssize_t, Py_ssize_tP, CONST_STRINGP, cts,
    generic_cpy_call,
    PyBUF_WRITABLE, PyBUF_FORMAT, PyBUF_ND, PyBUF_STRIDES)
#

or not :/ time to figure out how i can do that

swift imp
#

I do wish we had a compose and pipe operator

#

Like pipe would create a closure that called the functions in order, automatically feeding ones output to the other

halcyon trail
#

why would it create a closure that does that instead of just doing it

swift imp
#

I guess

#

f(x)|g

#

But if you did f|g then it would delay the operation

#

Like maybe you don't want to execute it immediately

halcyon trail
#

then you'd make a lambda out of it

#

a better solution if you don't want something to execute immediately is to just have a good lambda syntax, and then that works for everything

#

the problem is that f | g can't delay the operation, because when you have pipe that already means something

#

it means g(f)

lusty scroll
#

how about f * g

surreal sun
grave jolt
#

I think it's somewhat of a lost cause because lots of things are callable

lusty scroll
#

as a hypothetical operator

#

i guess whatever issue f | g has, any binary operator might also have

fallen slateBOT
#

@lusty scroll :white_check_mark: Your eval job has completed with return code 0.

001 | 40
002 | 49
lusty scroll
#

!e

def f(x): return x * 10
def g(x): return x - 1 

def fun___mul__(self, f2):
  def apply(*args, **kwargs):
    return f2(self(*args, **kwargs))
  return apply
from forbiddenfruit import curse
from types import FunctionType
curse(FunctionType, "__mul__", fun___mul__)

print(f"{(f * g)(5)=}")
print(f"{(g * f)(5)=}")
fallen slateBOT
#

@lusty scroll :white_check_mark: Your eval job has completed with return code 0.

001 | (f * g)(5)=49
002 | (g * f)(5)=40
lusty scroll
#

@surreal sun πŸ˜‚

scenic geyser
#

can some one briefly explain to me what is Metaclass

sand python
#

it's literally the class of a class

native flame
#

if a class is a blueprint for objects, a metaclass is a blueprint for classes

scenic geyser
#

oh okay thanks

lusty scroll
verbal escarp
#

actually, i know how it could work in practice

#

replace * by @ for consistency with decorator syntax and then rewrite the functions that are essential to functional programming like map, reduce etc. with a variant that returns a closure

verbal escarp
#

downside would be the changed signature in normal situations

#

like map(lambda x: x**2)(range(10))

#

on the upside, it would be explicit which params are used for "configuration" of the function and which param is iterated over

#

i had just realized i used that pattern in my fuzzylogic library, somehow never relating it to function composition

native flame
#

hmm but if you use operators that already exist, what would happen for f @ g if they had both __matmul__ and __call__ implemented

verbal escarp
#

i don't think i've ever seen pure functions implement __matmul__

#

nobody does that, for obvious reasons

#

but __call__ is a problem for backwards compatibility, yeah

#

replacing map and reduce with those variants is breaking

#

but it actually might enhance performance in many cases to consider two phases

#

in fuzzylogic, i use this pattern not just because it's nice to work with. in some cases it's useful to prepare heavy math ops in the first (initialization) phase and then reuse the results in the second (work) phase

#

so you don't have to repeatedily calculate exponentials and whatnot

#

for general purposes, the initial phase could be used to prepare a JIT of sorts

#

there could be a hook in __matmul__ that triggers a JIT - "hey, something's about to happen, look!"

#

just contemplating

lusty scroll
verbal escarp
#

exactly that

#

but with an explicit initialization phase for those complex functions that could be remedied

#

(map(func) @ filter(lambda x: x > 2) @ list)(iterator) doesn't even have a direct simple list comprehension to compare to

#

it would require a comprehension-comprehension

#

[x for x in (func(y) for y in iterator) if x > 2] i think?

#

ugly as hell

#

the ugliest part in the composition is the lambda, imo

#

let's replace that by a hypothetical (map(func) @ filter({x => x > 2}) @ list)

#

that looks nicer

lusty scroll
#

might have to special-case stuff like classmethod too

spice pecan
#
def map(func, iterable=None):
    if iterable is None:
        return composable_map(func)
    return regular_map(func, iterable)
verbal escarp
#

i had thought of some kind of dispatch, yeah

#

nice and simple

spice pecan
#

Although I guess that's not exactly correct yet

#

This should be equivalent to map's current behavior, given that you do define regular_map and composable_map

def map(func, *iterables):
    if iterables:
        return regular_map(func, iterables)
    return composable_map(func)
#

But yeah, there are ways to achieve this without introducing a breaking change

verbal escarp
#

i think composable complex functions like that could help with comprehension-comprehension situations

verbal escarp
#

tbh i find comprehension-comprehensions very hard to write correctly, i almost never get them right in one go

#

having a clean and simple alternative to plug stuff together would help greatly in those cases

#

i'm just pondering, if generators supported __matmul__, we could actually plug comprehensions together like that.. maybe forbidden fruit can do that?

spice pecan
#

with a bit of wrapping you can achieve that without dark magic

#
gen @ composable(other_gen) @ function @ whatever_else_you_want_im_not_sure

if composable implements __matmul__ and __rmatmul__, this should be functioning

verbal escarp
#

that could work. a bit of dark magic would make it a bit more elegant, though πŸ˜‰

spice pecan
#

Having this out of the box would be convenient, but having a lack of dark magic makes this a significantly more stable solution that you can use in production environments without a feeling of guilt

verbal escarp
#

true

spice pecan
#

You could opt in for a slightly-less-magical wrapping value that would make this more elegant, something like

makepipe @ gen @ func @ ...```
verbal escarp
#

actually, that whole approach would easily be PEP-able. no AST-fiddling necessary, backwards compatible..

#

would have to build an actual prototype for it and test it a while though, i guess

spice pecan
#

This leaves some consistency questions in the air. As fix said, lots of things are callable, but you can't auto-force composition onto each and every one of those automatically, since they just implement __call__ and don't have a common callable ancestor

#

You can soften it with reflected operators, but if you try to compose several things that don't support it themselves, you'd either have to patch them beforehand or force a blank in there just to convert to composables

#

And lots of things that pretend to be functions aren't actual functions

verbal escarp
#

can't really make an educated guess as to how hard it would be to catch those without some actual examples

#

and i don't know how often people try to call stuff that isn't a function in a functional way

#

maybe the most prominent example of that would be something like list()

spice pecan
#

Every class (mostly applicable to built-ins such as int, range, str and so forth), classmethods, singledispatch objects, map and filter (perhaps reduce as well, not sure there), etc

verbal escarp
#

map isn't a function?

native flame
#

nop

spice pecan
#

It's a class, and so is filter

#

!e help(map)

fallen slateBOT
#

@spice pecan :x: Your eval job has completed with return code 1.

001 | Traceback (most recent call last):
002 |   File "<string>", line 1, in <module>
003 | NameError: name 'help' is not defined
spice pecan
#

Oh wow

verbal escarp
#

oh man

#

πŸ˜΅β€πŸ’«

spice pecan
#

Since all of them use class constructors, you could technically patch type

#

Since, after all, calling any of those is equivalent to calling their __new__

#

But that still falls short for static/classmethods, which are classes used as decorators that return callable instances, same for singledispatch

#

Partial might actually return functions, not sure about that one

#

Oh, attr/itemgetter and methodcaller... There are lots, to say the least

#

Cases like these make me feel a bit bitter about duck-typing, since this would be a lot easier in a language with extension methods on interfaces

#

It would be a matter of overloading @ for some abstract Callable that every callable type inherits from

verbal escarp
#

got a point there

spice pecan
#

This is why it would be significantly cheaper to just shove a blank in front that would wrap the chain into composable of some sorts

surreal sun
spice pecan
#

I think so too, can't check right now

#

but it could be easily implemented as a wrapped function

surreal sun
#

Yeah I can confirm, I think I was messing with functools source code the other day and saw that

verbal escarp
#

maybe all it takes is a little helper function that people can wrap their callables with if they run into a situation with AttributeError: foobar has no __matmul__

spice pecan
#

It really is, yeah

surreal sun
#

I though / after means that parameters before it are positional only

fallen slateBOT
#

@surreal sun :white_check_mark: Your eval job has completed with return code 0.

hi,test
spice pecan
#

All it needs is a / after function so you can still have function as a kwarg

surreal sun
#

For parameters before

spice pecan
#

It does

#

And having that allows you to receive kwargs that are named like pos-only args

#

!e ```py
def f(a, /, **kw):
print(a, kw)

def g(a, **kw):
print(a, kw)

f(10, a=20)
g(a=20)
g(10, a=20) # This one's going to crash

fallen slateBOT
#

@spice pecan :x: Your eval job has completed with return code 1.

001 | 10 {'a': 20}
002 | 20 {}
003 | Traceback (most recent call last):
004 |   File "<string>", line 9, in <module>
005 | TypeError: g() got multiple values for argument 'a'
verbal escarp
#

that is left as exercise to the curious reader

uncut sage
#

@stable grail Just letting you know I've updated the repo for PyPacker, it's sorta-kinda useable outside of my own test cases now.

atomic egret
#

I want to make a ListenerFuncABC that would pass the isinstance(func, ListenerFuncABC) check if the function object has certain attributes and meets some other defined conditions in the ABC, I know that there's __subclasshook__ that can override issubclass, but how would I override isinstance function?

native flame
#

metaclass with __instancecheck__ would work

atomic egret
#

do I need a metaclass? can't I just override something when inheriting from abc.ABC?

#

what I'm essentially trying to achieve is a structure like this: ```py
class Foo(Controller):
@Controller.listener(name="bar")
async def my_listener_func(self, *args, **kwargs):
...

the `Controller.listener` decorator will set certain attributes for the `my_listener_func` object itself for which I then want to perform a simple `isinstance(function_object, ListenerFuncABC)` check within the metaclass `__new__` so that I can know whether it's a listener function or not. Alternatively, I could probably just make a standalone function that checks these, but I think the ABC makes more sense here, or should I go with the standalone check function approach instead (something like `is_listener(function_object)`)
#

(Controller is inheriting from ControllerMeta that defines that __new__)

spice pecan
#

__instancecheck__ on your class should be sufficient I believe Nvm, you do need a metaclass

modest tangle
#

Does anyone knows hot to do video stitching using python ??

verbal escarp
atomic egret
modest tangle
verbal escarp
spice pecan
#

Something like if issubclass(type(instance), cls): return True would make a lot of sense in virtual subclass context

atomic egret
lusty scroll
lusty scroll
#

maybe if python aded extension methods that could be enough

#

well ABCMeta is a type, so disregard

spice pecan
#

I'm not sure how that would work, honestly

lusty scroll
#

I guess some aspect-type feature would be necessary

#

you're right, it wouldn't work if we just had extension methods, pretty sure

#

probably simpler to retrofit the callables with some kind of common base type, and some more unlikely magic

#

maybe by overriding __get__ somehow

spice pecan
#

Retroactively making them actually inherit from ABCs would be the optimal solution IMO

#

Though that won't fix the issue of new types with __call__ not being registered, hmm

atomic egret
# lusty scroll is other always a `type`? or could it be some metaclass like `ABCMeta`

well, it could probably even be Any, the user can pass anything in there the checks happen internally without any prerequisite for what the object that it's comparing is. I figured Type[type] will essentially cover anything since it's just an object created from type, which should include type itself since that class is a bit weird, type(type) is type # true

lusty scroll
#

yeah, that's the contract I suppose, not everything anyone could possibly pass in

red solar
#

can i not have a class in test.py, put from _impl.test import MyClass inside __init__.py, and then outside of the package do from test import MyClass?

#

(to hide the fact that it's in its own file)

elder blade
#

You can

red solar
#

hmm it gave me a module not found error tho

#

wonder if i can create an MRE on repl.it or something

#

basically want to create a package that appears as a module

raven ridge
#

Why?

red solar
#

because i want multiple files, but i like the convenience of being able to do from mdl import cls

raven ridge
#

Then just put from ._private_submodule import cls in mdl/__init__.py

#

The globals in mdl/__init__.py are the things that show up in, and are importable from, the mdl module

red solar
#

that breaks too

#

ah you're on mobile :/ nvm

#

ahhhh i didn't have the .

#

it works now, yay πŸ™‚ thanks

#

i mean, my code doesn't, but the import does πŸ™‚

lusty scroll
#

oh you did ```python
from _impl.my_cls import MyClass
all = [MyClass]

raven ridge
#

that should be __all__ = ["MyClass"]

#

the elements of __all__ are str

red solar
#

yeah i realised once it complained lol

red solar
#

Does any linux distribution not come with a compiler?

#

Seems easier to just compile something required for a package on install rather than deal with multi linux and stuff? (And have precompiled versions for windows and Mac)

honest turtle
#

try /kill all

nocturne delta
#

is there any internal name for dunder/magic method

#

because i cant find anything on searching dunder in python docs

red solar
#

special methods ig

nocturne delta
#

dayum thanks

lusty scroll
#

"special" indeed, they make up 90% of the attributes on any simple class πŸ˜ƒ

verbal escarp
#

in fuzzylogic on the other hand it's almost 99% of all methods because i'm wrapping stuff with additional logic, which is nice if you can use python syntax

#

at least they are "special" in terms of unique behaviour regarding the syntax

spark magnet
#

what are you trying to compare in this example?

#

the first three bytes of a Python string are not the characters in the string.

red solar
#

Tbf it’s a bytes object

spark magnet
#

ok, same point

left gyro
#

Anyone have any idea for mini project using Python ?

spark magnet
red solar
#

does ctypes.c_char_p(b'hah') keep around a reference to the bytes object once the call is evaluated?