#internals-and-peps

1 messages · Page 93 of 1

grave jolt
#

Or stay at 3.7 out of inexplainable spite.

swift imp
#

I'm stuck in 3.7 and I hate it

#

Annotations work half assed

#

I don't even have Literal

raven ridge
#

I hate Literal. It's a perfect example of something that's obviously not a type jammed haphazardly into this farcical type system

boreal umbra
swift imp
#

Pylama wasn't a fan I when I didn't use it

#

It was like evaling the string and complaining it couldn't find the type

unkempt rock
#

Quick question how do i get my skills up in python?

raven ridge
#

And Literal is a hack to allow the Python "type" system to, in some circumstances, describe acceptable values rather than types.

gleaming rover
raven ridge
#

That's literally (heh) the definition. Literal specifies values.

gleaming rover
#

singleton types, AFAIK, have a well-accepted place in type theory and FP languages

#

whether their inclusion in Python is desirable is debatable, of course, but I do not think you can say they are not types

#

just like, for example, dependent types

#

which one can think of as types parametrised by values?

sacred tinsel
#

wouldn't an enum be the standard approach to what Literal is trying to do?

undone hare
#

Yeah, although sometimes it is easier to just use a literal

#

For example, the mode parameter of open() is typehinted with Literal. If it did use an enum, opening files would be more verbose.

sacred tinsel
#

yes, that would be perhaps annoying

#

but when I write a function that only takes specific values, its hard to resist using an enum

#

of course nothing will prevent the caller from trying to access a member that doesn't exist, but that's their own problem, and an exception will occur in a more logical place

peak spoke
#

I guess strings are more convenient for buitins etc; Literal will also accept enum values

sacred tinsel
#

having to import an enum for open would defeat the advantage of open being a built-in

peak spoke
#

could use something like open.READ for example, although that feels a bit ugly

sacred tinsel
#

mmm

#

well I usually just get a Path obj even if I don't have to sadclown

#

so I don't avoid the import anyway

undone hare
#

Once you are committed to typing you can’t escape the import hell anyway

peak spoke
#

shouldn't be that bad with 3.10

undone hare
#

What’s new in 3.10?

#

I thought it would have ended with generic typehints, but since you can’t do list[str] that’s pretty much useless

peak spoke
#

What do you mean can't do list[str] ?

undone hare
#

!e

def foo(bar: list[str]):
    ...```
fallen slateBOT
#

@undone hare :warning: Your eval job has completed with return code 0.

[No output]
undone hare
#

....

#

I thought it didn’t work ;-;

#

Well, nevermind then

unkempt rock
granite hatch
#

pe.moveTo(132,475,1),pe.click(132,475,1),pe.typewrite(superb bro i want this because of camera),pe.click(917,515,1)

i want to loop this program for 2 hours and after the word 'camera' in the sentence i want to add non repeating unique numbers

grave jolt
grave jolt
#

I wouldn't say it's "obviously not a type".

#

ABCs (like Mapping) or Protocols aren't really "types" either, you can't make instances of them.

#

Or, well, you can, but you don't have to.

#

A notion of "type" is a bit vague in a dynamically typed language. list[int] and list[str] are treated as different types, even though at runtime it's the same type list.

#

And Literal is a hack to allow the Python "type" system to, in some circumstances, describe acceptable values rather than types.
A type being a set of acceptable values is fine with me. Union[int, str] isn't a real Python type either, neither is Iterable[float].

gleaming rover
#

a set of values

grave jolt
#

Well, in Python it's kind of in between.

#

With duck typing and such

gleaming rover
grave jolt
# gleaming rover why do you say that definition doesn’t apply to nominal typing

In a nominal system you can't just make a type (set) like: "has a method foo that takes an int and returns a str".
You can explicitly make a type FizzBuzz: has a method 'foo' that takes an 'int' and returns a 'str', but then a function that accepts a FizzBuzz only accepts FizzBuzz, not just any value that has the right method.

#

i.e. structural typing specifies the required properties of a type, and nominal typing specifies the required name of a type.

#

So you could say that in nominal typing, a type is a set.

#

But it's a very restricted kind of set.

gleaming rover
#

it’s still a set of values

#

is it not

grave jolt
#

Well, any type is a set of values, yes.

gleaming rover
#

the constraint is just stronger than in structural typing

#

so in the original context, a literal type is just a singleton set

#

why does it have to be an attempt at structural typing?

grave jolt
#

A type being an explicitly specified set of acceptable values like {"a", "b", "c"} is not possible in nominal typing.

#

Unless you're using dependent types or something like that.

unkempt rock
#
So im working on a roblox finder and how can i do this
{
  "status": "ok",
  "robloxUsername": "vTroops", --I want my python to print this specific username and how can i do that
  "robloxId": 1323247939 
}
#

im dumb sorry

proud vault
#

Hello we are looking for dev to new project "enzy" if you know how to use python in scale 9/10 dm Me for more informations

grave jolt
#

@proud vault This server is not for recruitment. If you want to search for collaborators for your open-source project, you can go to #python-discussion or in an appropriate topical channel.

unkempt rock
#

ko k

grave jolt
#

@gleaming rover You can make a type which has only one value. But you can't make a type which is a single value that already belongs to some other type, at least in a nominal type system.

#

Again, I'm not saying Literal doesn't have a place.

grave jolt
gleaming rover
#

okay this is my reasoning

#

it’s a special case of subtyping

grave jolt
gleaming rover
#

nominal typing just means that types are explicitly declared by name, as opposed to members, right?

grave jolt
#

I guess.

#

In nominal typing, A is a subtype of B only if A is explicitly declared a subtype of B

#

So if you have a value like "foo", you can enumerate the types it is a subtype of: str, object, Iterable[str] (suppose it inherits from it explicitly, for the sake of argument)

#

but in structural typing, a value can have infinitely many types: Any, Literal["foo"], Literal["foo", "bar"], {sequence of odd length}, Union[str, int], ...

gleaming rover
#

and normally we talk about substitutability, right

grave jolt
#

In a nominal type system, a subtype of A is something which inherits from A.

#

But in structural typing, there might be more complicated rules depending on the type system.

#

In Python it's "it depends on the type checker because they are not standardized and have conflicting ideas"

unkempt rock
#

Can I somehow bypass this "Caused by SSLError(SSLError(1, '[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:852"

grave jolt
gleaming rover
#

let me think of how to express this

#

okay, so the constructor of A takes a number of parameters. there exists a set of parameter tuples, from which a set of possible values of A objects may be generated.

#

why can't a subset thereof form a subtype of A? these are all indeed members of the type A, independent of their structure.

#

I don't have the type theory necessary to express this idea

#

but it does not seem logical to me that singleton types cannot exist in nominal typing...?

grave jolt
#

what do you mean by 'singleton type'?

gleaming rover
#

types with a single member

#

i.e. literal types

#

...

#

actually, aren't literal types a special case of dependent types

#

if you think of dependent types as type constructors (at least partially) parametrised by values

grave jolt
#

Because if you have some random blob of things, you also need a proof that it forms an A.

#

In nominal typing, it's determined by the names of the types and their inheritance hierarchy.

#

The only difference in structural typing is that a type doesn't have to be a name, it can also have some structure, like Literal["str"] or {x: number, y: number}, so that subtyping looks at the structure of the type, not at its name

gleaming rover
#

okay, how about this

#

can intersection types exist in nominal typing?

#

IYO

grave jolt
#

No

#

because (in a nominal system) a value can't belong to two types at the same time, except if one is a subtype of the other, in which case you can only specify one.

#

although...

grave jolt
#

yeah, that's what I was typing after the although

#

you can have a value that implements a number of interfaces or just inherits from multiple classes

#

but

#

I actually don't know

gleaming rover
#

because

#

to me

#

okay, let's skip values first

grave jolt
#

I don't know any language with a nominal type system that has intersection types, let's say it like that 🙂

grave jolt
#

huh?

gleaming rover
#

Scala, the language

grave jolt
#

I know, I just didn't know it has intersection types

gleaming rover
#

although it does support structural typing, but that comes about through reflection

#

actually

#

does Haskell have structural typing...?

grave jolt
#

I don't think so

#

but there are so many extensions that it probably has type-level minesweeper in one of them

#

I guess intersection types can exist in nominal typing then.

gleaming rover
#

if we accept that

#

isn't it also true that the intersection type is not externally defined?

#

for example, you can have a value of type A & B without defining that type elsewhere

grave jolt
#

yes

gleaming rover
#

and nevertheless, it will not be compatible with a structurally identical type C & D

grave jolt
#

I don't follow

gleaming rover
#

say you have these classes (Python syntax)

class A:
    left: int

class B:
    right: int

class C:
    left: int

class D:
    right: int
#

A & B exists as a valid intersection type, and no values of type C & D are members of that type, despite being structurally identical, in a nominal typing system

grave jolt
#

yes, that makes sense

#

wait

gleaming rover
#

my argument is that a literal type is related to this idea - that types need not exist as externally defined entities that may be independently instantiated, as long as they exist as some refinement of an existing type, or an independently defined type

grave jolt
#

well, you could have a type X inheriting from A, B, C, D, which is a subtype of all of both, but then it turns into madness

grave jolt
gleaming rover
grave jolt
#

right?

gleaming rover
#

but now

#

A & B is really {all possible values of A} & {all possible values of B}, right

#

is it that big a leap to think of, say, Literal['this'] as str & {'this'}?

grave jolt
#

you mean str & {'this'}?

gleaming rover
#

oh

#

ye &

#

mb

grave jolt
#

but the issue is that you can't define a type {'this'}

#

str & {'this'} = {'this'}, so the intersection doesn't change anything

gleaming rover
#

I'm thinking of it as more a refinement (? not sure if right word) of an existing type

#

or rather

#

let me put this another way

#

it's basically a special case of dependent typing

grave jolt
#

yeah, I guess

gleaming rover
#

e.g. in a dependently typed system, even ints are a subtype of int

#

and you can express that with a type-level predicate

#

a literal type just has a predicate applied that is only valid for one value

#

...is what I'm thinking

grave jolt
#

yes, I suppose it's some kind of dependent typing

#

because it's mentioning values at the type level

gleaming rover
#

ye

gleaming rover
grave jolt
#

well, in a dynamically typed language it's a little bit unclear and vague

#

you could say that a structural type {x: int, y: int} is a type Any refined with

lambda v: (
    hasattr(v, "x")
    and hasattr(v, "y")
    and isinstance(v.x, int)
    and isinstance(v.y, int)
)
#

@gleaming rover ^

#

or that a nominal type str is a type Any refined with lambda v: isinstance(v, str) (ignoring instance check hooks)

gleaming rover
#

especially in Python

#

but I was thinking more in the general sense

swift imp
#

Generators/iterables are what fuck up the entire idea of type checking right

#

Like run time checking

swift imp
#

I've toyed with decorators that take type hints and use them to do all sorts of type and value checking

#

But if something returns a generator, I just consumed it

#

It's actually kinda ez to take type hints and use them for run time checking

#

But generators fuck it all up

grave jolt
#

@swift imp

It's actually kinda ez to take type hints and use them for run time checking
That doesn't work for functions either

#

i.e. when you pass a function to another function.

swift imp
#

Right u can't check the input and return types

grave jolt
# swift imp Right u can't check the input and return types

Another point is that it can take a lot of time. For example, if you have a binary_search : (Sequence[int], int) -> Optional[int], you'll have to go through the entire sequence to make sure it only has ints, which makes this function 100% useless.

#

and you can't really check generic types at runtime

#

So in general, type-checking is a static thing. Type errors ought to be caught (mostly) at look-at-your-editor-time or at automated-build time.

swift imp
#

The only thing I miss about compiled languages

#

All those sweet sweet errors to make debugging ez

grave jolt
#

Well, you can use type hints, and you'll catch quite a lot of type errors that way

swift imp
#

If u use descriptors to any complexity you're fucked

#

I've noticed that

grave jolt
#

@swift imp Well, yes. Type hints don't cover the whole language.

swift imp
#

I love descriptors

grave jolt
#

although in statically typed languages, descriptors don't really exist, right? 🙂

swift imp
#

True

grave jolt
zealous tusk
#

I do like Literal and structural typing to work with an existing codebase or external input that isn't really statically typed, but without adding too much runtime overhead

#

like hmmm, say, passing specific keys you expect in JSON dictionaries you've received, but without using an Enum
Literal makes it easier to pass the specific key value you expect without creating a whole new type for it

#

but I always prefer using my own types from the start where and when I can

#

I assume this kind of thing may be easier in more functional languages where everything is statically typed from the start? but in the meantime structural typing is kind of helpful

steel solstice
#
from typing import ParamSpec
_P = ParamSpec("_P", bound="Client.start")

class Client:
    async def start(self, token: str, *, bot: bool = ..., reconnect: bool = ...) -> None: ...
    def run(self, *args: _P.args, **kwargs: _P.kwargs) -> None: ...
```can any typing wizards tell be if this use of bound is valid?
#

i cant tell what the other use of the bound would be from the pep or the doc for it

grave jolt
#

🙂

unkempt rock
#

I want to make a cmd like when i use it it send a particular msg to a user in DMS like

+DM (ID) (MSG)

#

ping me if u know how to do it

grave jolt
unkempt rock
#

ight

raven ridge
grave jolt
#

you're welcome❤️

raven ridge
#

I get the rationale. I'd probably find more uses for it than I find for Literal. But yeah, I don't like it.

desert peak
#

I don't understand why there are multiple type linting packages

#

I don't get how one can be different from another from a technical level

#

at this point, I don't get why someone doesn't make a typescript-esque thing for Python

spark magnet
sacred yew
#

normal typecheckers haven't reached that stage yet

spark magnet
sacred yew
#

where you can have typechecking that actually works well

spark magnet
#

you don't like mypy?

sacred yew
#

i mean its good

#

but its also lacking in a bunch of ways

spark magnet
#

what do you miss in it?

desert peak
#

knowing what my types are.

spark magnet
desert peak
#

the frameworks I depend on don't

sacred yew
#

honestly the type inference is kinda bad

#

but adding all the imports from typing makes it too verbose

unkempt rock
grave jolt
# desert peak I don't understand why there are multiple type linting packages

Because the PEPs don't specify the behaviour (the "type system") exactly, so type checkers have their own opinion on stuff.

For example, mypy thinks that all callable attributes of a class must have a self argument https://mypy-play.net/?mypy=latest&python=3.9&gist=dece2a49e22531eded9b72ea569c94e0, which is weird and unexpected IMO

Another example is that pyright supports recursive type aliases (like JSON = Union[dict[str, "JSON"], list["JSON"], int, str, bool, None]), and mypy doesn't.

Another area is type narrowing. AFAICT, type checkers do it very differently.

grave jolt
# grave jolt

I agree that it would be better to create a "single source of truth" for typechecking, just like there is CPython as a reference implementation. But the type hinting system is still in rapid development, and people are disagreeing on it all over the place.

#

And then there's 10000 features that only 1% of people need, so they don't get implemented

unkempt rock
#

Hi could anyone help me with a webserver i am writting

grave jolt
unkempt rock
#

Could i discuss my project then

grave jolt
#

@unkempt rock This channel is for discussing the Python language itself and its ecosystem in general. If you want to get a review on the structure of your project, #software-architecture is more appropriate. If you want help on solving some issue you have in your code, see #❓|how-to-get-help or #web-development.

swift imp
#

AND no type checkers properly support descriptors

#

They also don't support getatrr and setattr

gleaming rover
#

types aren't simple

#

and, to use that example, TypeScript itself also has weird problems

desert peak
woeful sinew
#

expected result should be state

limpid marten
#

You're misunderstanding the chars argument of lstrip.

#

@woeful sinew

#

Optional. String specifying the set of characters to be removed. If omitted or None, the chars argument defaults to removing whitespace. The chars argument is not a prefix; rather, all combinations of its values are stripped.

#

The chars argument is not a prefix; rather, all combinations of its values are stripped.

woeful sinew
#

I guess i'll be using "...".replace() insetead. and yes huge misunderstanding

gleaming rover
cold oar
#

Why do some programs use Queue.put(item) and then process the item from that queue in a thread, rather than just do ThreadPoolExecutor.submit(process_item, item)? ThreadPoolExecutor.submit does not block. So can we just skip using the queue to store the items? I do not know how this works, so I would appreciate if someone can help me understand

sacred yew
#

idt queue.put blocks either

cold oar
#

Is it not an extra step?

sacred yew
#

but queue + threading is more lower level compared to concurrent.futures

#

threadpoolexecutor uses a queue internally for tasks anyways

cold oar
#

Thanks 🙂

cunning niche
#

I have talked to a few different people and everyone seems to have different opinions, so I was wondering if anyone could weigh in with their preferences and experience. Lets say a system that reads json from an external API, the data needs to be transformed into a generic "internal" structure and passed on to either other systems or saved to a db. Would you rather transform the data into a new dict with your key names, or would you use several dataclasses for that. Lets say that the json is fairly nested and represents several related objects with a few levels deep hierarchy.

gleaming rover
#

this is a channel for discussion of the language itself

cunning niche
#

Will do, thanks

woeful sinew
#

:= is called the walrus operator in python. why not name it fangs ??

limpid forum
sinful sky
#

i am very advanced

#

WHAT EVEN IS THAT

desert peak
#

you've.. never seen a walrus?

unkempt rock
#

will python have a native compiler?

radiant fulcrum
#

no

#

It is highly unlikely that python will ever be able to be compiled to complete native code

unkempt rock
#

ok

raven ridge
sacred yew
#

does cython qualify?

unkempt rock
limpid marten
#

Nuitka translates the Python modules into a C level program that then uses libpython and static C files of its own to execute in the same way as CPython does.

#

Is this different than Cython?

grave jolt
#

Unless by 'native compiler' you mean 'compiler that ships with CPython'

unkempt rock
gleaming rover
#

not what I thought you meant tbh

unkempt rock
#

ok

raven ridge
#

not what I thought you meant, either.

#

I think there's about zero chance of that ever happening. There's no reason why the CPython devs would ever want to bundle such a thing with the CPython interpreter, and there's no reason why the devs who work on such things would want to live with the loss of control over their release schedule, support schedule, copyright assignments, etc that would come with handing it over to the CPython owners

#

and wanting to compile to native machine code is a niche use case

#

And the CPython developers probably want to keep developing CPython, rather than building an alternative or replacement.

grave jolt
limpid marten
#

I was a bit surprised to learn about the mutable default parameter, have you guys ever found a use for it?

>>> def b(a=[]):
    a.append(1)
    print(a)
>>> b()
[1]
>>> b()
[1, 1]
>>> b()
[1, 1, 1]
#

Maybe it's just a quirk of having a mutable object as a default parameter.

deft pagoda
#

the "normal" use of it is to cache

#
In [1]: def f(x, cache={ }):
   ...:     if x in cache:
   ...:         print(f"Cached value: {cache[x]}")
   ...:     else:
   ...:         cache[x] = x
   ...:         print(f"Non-cached value: {x}")
   ...:

In [2]: f(1)
Non-cached value: 1

In [3]: f(1)
Cached value: 1
#

of course, there's a common decorator for caching function calls now, so this idiom is less common

raven ridge
#

that is: default values for a parameter aren't evaluated when the function is called; they're references to objects that are saved when the function is defined.

#

in fact, you can even see that it works this way.

#

!e ```py
default_a = []
def foo(a=default_a):
a.append(1)
print(a)
foo()
print(default_a)
print(foo.defaults[0] is default_a)

fallen slateBOT
#

@raven ridge :white_check_mark: Your eval job has completed with return code 0.

001 | [1]
002 | [1]
003 | True
sacred tinsel
#

I don't think I've ever seriously used a mutable default, if you want to take e.g. a list and default it to an empty one (and not use None as a temp value), I find that you can usually default it to e.g. an empty tuple instead, and relax the annotation to a Sequence or Collection, depending on how you use it

#

not always, but usually I find that I don't actually really need it to be a list

#

some of my colleagues think that the annotation should be as lax as possible, and that annotating something as a list when it really only needs to be an iterable is a lie

grave jolt
#

well, not lax, but rather the most precise -- you should annotate the interface you need, but no more

#

(sorry for nitpicking!)

sacred tinsel
#

yea, but I think there's also a practical point of view, where asking for a list always means that you can start using it as such without breaking existing code calling your function

grave jolt
#

@sacred tinsel why would annotating it with Sequence break existing code?

sacred tinsel
#

well you may run into a situation where you want to pass the arg to another function that does want a list, for example (even if it doesn't really need one)

#

and in that situation you have to start thinking about what needs to change where, so that the annotations are compliant everywhere

grave jolt
#

you could pass it a list(sequence), but that's extra overhead, and maybe a bit confusing

sacred tinsel
#

but I do very much agree with this

you should annotate the interface you need, but no more

grave jolt
#

I think it's called 'interface segregation principle' or something like that

#

well, there's also a noise aspect to this.

#

When you start putting in MutableMapping, Protocol, TypeVars in, it can become a huge mess

sacred tinsel
#

yeah and I think for various people the threshold for when it becomes noise (the practicality of just using something everyone knows vs the purity of theoretical correctness) is in very different places

grave jolt
#

e.g. Dict[str, Dict[int, bool]] is nicer than MutableMapping[str, MutableMapping[abc.Integrel, bool]]

grave jolt
# sacred tinsel yeah and I think for various people the threshold for when it becomes noise (the...

Overgeneral functions can make it hard to understand what a function does.
I'm learning PureScript, and I was a bit scared by this function:

any :: forall f b a. Foldable f => HeytingAlgebra b => (a -> b) -> f a -> b

Most of the time, the function will work like one of

any :: forall a. (a -> Boolean) -> Array a -> Boolean
any :: forall a. (a -> Boolean) -> List a -> Boolean

^ and now it's more or less clear what it does

#

but sometimes it makes it clearer, e.g. if a function expects Sequence[int], it's pretty clear that it doesn't mutate the list you pass in.

sacred tinsel
#

I can barely read the second example 😫

grave jolt
# sacred tinsel I can barely read the second example 😫
any :: forall a. (a -> Boolean) -> Array a -> Boolean
--        |            |             |         |
-- this is a generic function, with a generic type `a`
--                     |             |         |
--             first argument is a function (a -> Boolean)
--                                   |         |
--                    second argument is an array of `a`s
--                                             |
--                                function returns a Boolean

basically

A = TypeVar("A")
def any(fn: Callable[[A], bool], Array[A]) -> bool:
    ...
#

(works exactly like the built-in any) the function checks if any element satisfies a function

sacred tinsel
#

okay yea this makes sense now

#

well seeing the first signature would definitely have me googling Foldable and HeytingAlgebra even if I had an easier time reading the syntax

grave jolt
#

@sacred tinsel correction: it's more like any after map (seeing if any value in an array satisfies some condition)

#

Well, the main point is that this is an example of how you can overcomplicate things. It's technically the right interface, but at what cost

#

I guess you could compromise by including a very concrete example in a docstring:

A = TypeVar("A")
B = TypeVar("B", bound=HeytingAlgebra)
def any(fn: Callable[[A], B], Iterable[A]) -> B:
    """
    >>> any(lambda x: x > 0, [-1, 0, 1, -42])
    True
    >>> any(lambda x: x > 0, {-1, 0, -42})
    False
    >>>
    """
    ...
sacred tinsel
#

yeah, although assuming that's something like an stdlib function or a general utility, allowing it to be used in the most broad variety of cases makes sense

#

sometimes you can be more or less certain that your function will only be called from a specific context, and then it's easier to justify just going for the simplest interface

distant girder
#

Anybody ever heard of descriptors thinkmon

earnest raptor
#

I was just playing with python and made this code on my pc and ran it and I saw something wierd while the program was printing all of these numbers I couldn't go back since the program was running so I pasted the code in Programiz to find that there's a bug that happened without any touch of the user, it seems that there's a very small percentage for this to happen but it does. so why is that?

raven ridge
#

that looks like a bug in whatever program you're using to run the Python code to me - try with IDLE or a regular Python shell and it probably won't occur

#

I think Programiz ate two \n without displaying them, which would be a bug in Programiz

#

it could be that when output is being produced faster than it can keep up, it skips some?

woeful sinew
#

@limpid forum In response to the fangs operator. I don't think any aspect of a walrus is reflective of the python language. (blubbery + slow != python ) well maybe the slow part 😆

#

In addition, the name walrus operator doesn't fit the actual symbol. this looks more like a walrus o= or beaver 😆

sacred yew
#

: are eyes?

limpid forum
#

Yup, what hmmm said. Walrus's face is basically eyes + tusks, so := makes sense. It also introduces another animal besides Python 😛

#

Remember that Python itself is named after Monty Python, so a bit of goofiness in the naming is in the spirit of the language

#

hm, I also googled "walrus emote" and it seems := with sometimes additional characters have been used as text emoticon for longer than Python's walrus operator

woeful sinew
#

@sacred yew :0= perhaps

limpid forum
#

one of the examples of walrus emote I saw was (:=), but there were also :3= and similar ones. I already closed my search results but I think something like :0= might have been there

woeful sinew
#

:3= 👍

spark magnet
#

("New Python Implementation", which is complete nonsense vaporware, followed up with insults)

raven ridge
#

Thanks for the sentiment but I am not relying on luck.
👀

#

wow, that's cringeworthy.

spark magnet
#

i would love to find out what that guy is actually thinking, but it's impossible.

brave badger
#

I am also creating Ada and Haskell implementations which have a similar requirement
I refuse to believe what I'm reading but if said person claims that their universal compiler is able to compete with the likes of GHC, then I'm not sure they understand the implications of going head-to-head with 30-year-old implementations with hundreds and hundreds of contributors and various white paper publications for the case of GHC and just FP in general

limpid marten
#

I think they do have a point about the lack of a standard being a bit detrimental to Python.

#

I've never really heard of universal compilers though.

spark magnet
#

@limpid marten how is the lack of a standard hurting Python?

#

did you see the later posts about c needing standards because multiple implementations were disagreeing? Does Python have that problem?

limpid marten
raven ridge
#

pypy is the most mature of the other implementations - in what sense is it an imitator?

limpid marten
#

PyPy3 implements the Python language version 3.7.9. It has been released, but Python is a large language and it is quite possible that a few things are missing.

#

The fact they can't definitively say it implements Python 3.7.9; which would be possible to say if there existed a Standard means it's simply just an imitation, but I could be misunderstanding.

raven ridge
#

which would be possible to say if there existed a Standard
I don't think that conclusion follows

#

If there were a standard, it would be quite a large standard, and it would still be possible that a few things are missing.

limpid marten
#

It would be much easier to design an implementation given a standard rather than implementing behavior and comparing it against an original implementation.

As other compliant implementations like PyPy, IronPython and Jython find areas they have a problem with, they seek clarification from python-dev as necessary (the C API, reference counting and the GIL are all CPython implementation details, for example).
Whereas they could otherwise access a standard being the source of truth, and not rely on some dev channel.

feral cedar
raven ridge
#

and... where the standard is ambiguously worded, or unclear, people would still need to check what CPython does or risk incompatibilities.

#

I daresay that reading a standard to see how something is supposed to behave is likely much harder than just trying it against a reference implementation - you may not find all the edge cases that way, but you don't need to have all the edge cases covered from the start - if someone finds something you missed, accept a bug report and fix it.

#

and it's not clear that you'd find all of the edge cases by reading a spec, either. specs are really, really hard to read.

limpid marten
#

I'd really like to see a real non-contrived Python program that behaves differently in both implementations. It seems weird to rely on some of the different behaviors.

raven ridge
#

I suspect most of those would still exist even if there was a standard. The standard would specify most of garbage collection as implementation-defined behavior, so as not to exclude creating things like Jython and IronPython that directly leverage the JVM or CLR GCs.

limpid marten
#

But anyway, just an interesting thought. I've always found it weird that CPython doesn't have a JIT.

#

Has there just never really been a need for Python to be fast by default?

raven ridge
#

It is possible (though not recommended!) for the __del__() method to postpone destruction of the instance by creating a new reference to it. This is called object resurrection. It is implementation-dependent whether __del__() is called a second time when a resurrected object is about to be destroyed; the current CPython implementation only calls it once.

limpid marten
#

Despite it saying it is only called once, the PyPy differences page I linked mentions how this is false and there exist counter examples.

gleaming rover
raven ridge
#

that's a failure of documentation, then - but the docs explicitly say that it's implementation-dependent how many times it will be called.

gleaming rover
#

on the other hand JS can’t because it runs in the browser

limpid marten
#

That's a really good point.

silk pawn
# spark magnet when smart people run off the rails: https://groups.google.com/g/comp.lang.pytho...

just read the whole thread, it seems like, at least according to Ned Batchelder, that Fibble has been claiming to have been doing this for at least 2 years, which seems backed up by the git repo's commit history, as 166 of the 171 commits were 2+ years ago. as such, there seems to have been a long period of inactivity on the repo, so I think that the OP was/is trolling, because I'd think something so important to him would be actively maintained or something

limpid marten
#

I can't help but feed that nedbat, and Ned Batchelder may be the same person.

raven ridge
#

indeed they are.

silk pawn
#

wait shoot

paper hatch
raven ridge
#

true, but you're a language user, not a language implementer. Python has higher level features that frequently make it easier to use than C++, but all of those high level features would need to be fully specified in order for people to rely exclusively on a spec when making alternative implementations

mighty cedar
#

Is there a resource for idiomatic advanced python for experienced devs transitioning from other languages?

#

I liked some of Hettinger's talks, but he only has so many of those

boreal umbra
#

Is there any reason that all the function-like types don't have a class hierarchy?

raven ridge
#

I'm having trouble parsing that question - what do you mean?

boreal umbra
#

why is MethodType not a subclass of FunctionType?

raven ridge
#

why should it be?

#

a bound method is a callable, but isn't a function

boreal umbra
#

!e

import typing as t
import types
print(isinstance(types.FunctionType, t.Callable))
fallen slateBOT
#

@boreal umbra :white_check_mark: Your eval job has completed with return code 0.

True
boreal umbra
#

hmm I guess there's that.

raven ridge
#

a function is one type of callable, a method is a different type of callable (conceptually, a method is a lot like a partial that binds a self arg to a function).

boreal umbra
#

right

#

conceptually I think of methods as a subclass of functions

raven ridge
#

they're not, though - it's composition, not inheritance.

#

a method has-a function and an object

vale flax
#

not entirely sure what distinguishes a method from a "function with an object in its closure"

raven ridge
#

it could be implemented that way, and thus be a subclass, but it isn't, so it isn't.

vale flax
#

i mean, the question was why its not

raven ridge
#

the inheritance hierarchy accurately reflects the implementation. MethodType is not a subclass of FunctionType because a method is not an instance of function

vale flax
#

i would be more accepting of the hierarchy if we stuck to the "functions are pure", "methods can have side effects" thing

#

but alas python doesn't do that

paper hatch
visual shadow
#

Some things there might not be up to date perhaps but looks like it covers what you need somewhat

sacred yew
#

don't most languages use "methods are functions attached to classes"

brave badger
#

Likewise, that also means limiting the state available to top-level functions, unless you're doing implicit state for a DSL like matplotlib, but I don't see how that relates to the hierarchy of callables in Python

#

Duck typing works extremely well with Python, in this certain case

spark magnet
grave jolt
#

Use the same compiler to compile Rust, Python, and Haskell? They must be joking

spark magnet
#

I had some long discussions with him in the ##programming IRC channel before he was banned there. He seemed uninterested in the differences between Java classes and Python classes.

grave thistle
#

I don't know if it's ok to say this but I recently started learning python and have no friends to discuss with. Anyone willing add me as a friend and shoot me a text.

#

Mentors and study buddies are both welcome

unkempt rock
#

isn't the difference between python classes and java classes are that python's classes are just sugar for a dictionary.

flat gazelle
#

python classes are not sugar for dicts

#

attribute access is not analogous to dict lookup

unkempt rock
flat gazelle
#

you can even have a class without a backing dict at all, such as int, str, Function

#

they do use a dict to store attributes

#

if you specifically define them from inside python

unkempt rock
#

yea so I mean, that's not really close to how java treats classes

swift imp
#

Any slotted class, specially, doesn't have a dict

#

Or is it instances of slotted classes?

flat gazelle
#

ye, but it is not the difference. The difference is more in that java classes do differentiate between fields and methods, have compile time deterministic attribute access, and are overall less flexible and more safe. And that is disregarding the more minor details like multiple inheritance.

#

the class has a mappingproxy under __dict__, which generally means there is no dict, and the instance doesn't get a dict at all

unkempt rock
#

everybody hashes something at some point guess that was a bad point

flat gazelle
#

python is closer to OOP as described by the original smalltalk

#

java is the deviant one, it just turns out to be the better approach years ago.

unkempt rock
#

realistically though, they both suffer from their design decisions.

grave jolt
#

well, there's no perfectly designed language

unkempt rock
#

yea for sure

flat gazelle
#

honestly, I do like python classes

unkempt rock
#

I really don't, I mean they are a convenient way to bundle code, but the FP approach is kind of more enticing

#

they don't offer a whole lot except some code reuse

grave jolt
#

Well, you'll still need to use classes in one way or another to define types (e.g. with dataclass).

#

just in a stripped way, I guess

#

and honestly, if you want to do functional programming, Python is probably not the best language

unkempt rock
#

yea it's really not that great for FP nor for OOP really - not the worst though!

#

there aren't a lot of strong FP langs out there 😦

flat gazelle
#

haskell is the only one you really need tbh

unkempt rock
#

yea but haskell is more than a can of worms to take into production

#

that's something python did get right

swift imp
#

you guys a good example snippet of a functional programming in haskell. I see people talk about how awesome it is but i can never think up a pattern to use it

unkempt rock
flat gazelle
#

classes do have some advantages over FP discriminated unions, FP doesn't handle "the user needs to provide these functions, some of which are optional" very well, which turns out to be very common. I do not consider constructors that have 8 variants each of which takes a different amount of functions a great solution to the problem. Typeclasses do solve this to an extent, but they do have their issues as well.

unkempt rock
#

I really like the way julia handles its type system and balances FP + imperitive paradigms

swift imp
#

Man. Fucking multiple dispatch looks enticing

#

Like it just seems so clean, even if its a bit more verbose

grave jolt
#

you mean, pattern matching?

unkempt rock
#

multidispatch is seductive for sure, it makes a ton of sense once you use it.

#

it runs fast as hell too

swift imp
#

No I mean multiple dispatching

#

Where you write multiple functions, all same name, indicating the type of each argument and the language picks the appropriate one at run time

grave jolt
#

ah

#

the typeclasses mechanism?

flat gazelle
#

haskell doesn't have multiple dispatch, it would not do well with the type system

unkempt rock
#

its pretty glorious

unkempt rock
swift imp
#

Python has a multiple dispatch library, and it has singledispatch built into functools?

unkempt rock
#

haskell does have algebraic types and a lot of other fancy stuff though

flat gazelle
#

it is really neat in Julia, true

grave jolt
unkempt rock
swift imp
#

Yeah, you get the organizational part but not the speed

unkempt rock
flat gazelle
#

to be fair, most statically typed languages do have multiple dispatch, C++, Raku, Nim, Java, Haxe...

grave jolt
unkempt rock
#

C++ is pretty awesome though, I wish I knew some of the more modern stuff

swift imp
#

thanks

unkempt rock
grave jolt
#

This project: https://github.com/gurkult/py-gurklang (on which mostly I and lakmatiol are working on) uses functional ideas to some extent, but uses a more imperative core for the main tight loop

#

It's a... functional stack-based language

unkempt rock
#

interesting

#

yea for python you don't wanna fuss with FP loop controls anyways

#

there's no TCO I don't think in python lol

grave jolt
#

no, there isn't

unkempt rock
#

but yea having the choice between FP and Imperitive has proven to be really powerful

grave jolt
#

and then run it in a while loop

#

but that's weird

grave jolt
unkempt rock
grave jolt
# unkempt rock how are you doing it?

It's a bit of a mess with spaghetti: https://github.com/gurkult/py-gurklang/blob/master/gurklang/vm.py#L52
Basically, I have a "pipeline" of instructions that are executed one-by-one. When I see a function, I just put all of its instructions on the pipeline. If the function needs a local scope, it's created from the current one (and a scope-popping instruction is put at the end).

So functions that don't require a local scope (since it's a stack-based language, so you can do {2 + 3 *} or something like that) can be run in constant stack-space; and all functions in general (even with local scopes) don't have a stack limit.

Right now these scopeless functions are not automatically detected, so you have to tell that to the interpreter. But this will probably be fixed in the future.

flat gazelle
# swift imp TCO?

TCO: for example, scheme

(lambda (fac n acc)
  (if (< n 2)
    acc
    (fac (- n 1) (* n acc))))
``` will convert this into a while loop akin to
```py
def fac(n, acc):
    while n >= 2:
        n, acc = n - 1, n * acc
    return acc
```, which means that you can't get a stack overflow, which is very possible with normal recursion. This conversion, although always possible, is only trivial in cases where the result is directly another call to the function, rather than some expression containing it.
grave jolt
flat gazelle
#

mb

#

the two traditional examples, always get them confused

unkempt rock
#

I don't blame ya lamatiol for recursion the 2 gotos are fac or fib lol

flat gazelle
#

there is also the much cooler fib version which uses the halving formula, but I do not have that one memorized.

unkempt rock
flat gazelle
#

It should be pretty easy to derive from the matrix power method

unkempt rock
#

I have a slightly weird question - not intended to be abrasive

#

Given the 5min conversation we just had, I've determined you all are smart. I spent the last few months scouring programming languages to help me out at work, and really ended up pivoting pretty far away from Python. What draws you in to using python?

flat gazelle
#

I don't ever have to drop a project because there is no library for what I want to do.

#

that really annoyed me about nim

unkempt rock
#

oh yea nim is super young

flat gazelle
#

isn't nim like, pretty old

unkempt rock
#

if it is old, it feels new

flat gazelle
#

nim is 2008

unkempt rock
#

wow thats pretty old!

flat gazelle
#

and I don't have to wait 10s for every code change, that really annoyed me about java, even with hotspwapping

unkempt rock
#

yea Java has slow compile times. I've had scala projects take 20min to compile on a good day

flat gazelle
#

every compiled language has slow compiles, except like... C in debug mode and even then only on a small project

unkempt rock
#

yea Go has really fast compile times, but it's end performance isn't amazing, and the language itself is very lean.

flat gazelle
#

hmm, never tried Go

unkempt rock
#

honestly, it's sugar is pretty meh, I like Rust a lot more. But - Rust can be slow to compile for large projects

#

If I'm doing mathy stuff I find myself using Julia, if I'm doing systems stuff C++(but now learning Rust still super new to it though)

flat gazelle
#

yeah, I can agree with that. Another thing I like in python is that things focus on being simple, unlike something like Rust. I know there is merit to the complexity in rust, but it doesn't make it any less complex. I would prefer a static type system though, but I don't think there is a simple type system which is useful and doesn't get in your way.

swift imp
#

Can you guys think up a good overloading using for @

grave jolt
#

salt-die's email class

unkempt rock
grave jolt
#

ye, I can't imagine a total beginner to programming starting with Rust or Haskell

flat gazelle
#

matrix multiplication, function composition are two main ones I can think of for @

unkempt rock
swift imp
#

a non standard one lol

shy saddle
#

hello there cupcake

swift imp
#

So the email class is def interesting

unkempt rock
shy saddle
#

;)

flat gazelle
#

Haskell is sort of possible, since you can just ignore some of the complexity and use ghci for everything

shy saddle
#

i think i could use haskell with a beginner

unkempt rock
#

I feel like a CAML would be better to see if they lean more towards imperitive or FP

#

FP to some people just clicks

shy saddle
#

hmm

#

true true

flat gazelle
#

scheme is IMO the best lang for beginner FP

unkempt rock
#

never tried scheme, is it a LISP?

flat gazelle
#

yes

#

though some people would disagree

unkempt rock
#

see I would lean more toward julia probably just because LISP's can be a little hairy to read. But, never tried it so I can't say

grave jolt
unkempt rock
#

julia isn't a lisp but it has a lot of lispy stuff in it

flat gazelle
#

LISPs are pretty readable once you get used to it

shy saddle
#

i know someone who learned programming with F#

#

F# is a fine lang

unkempt rock
#

F# is basically a ML

flat gazelle
unkempt rock
#

sure 😄

spark magnet
#

@unkempt rock when i mentioned the difference between java classes and python classes, i was thinking of things like __str__, or multiple inheritance, or @property

flat gazelle
#

__str__ is almost the exact same semantics as .toString()

spark magnet
#

"almost"

#

@flat gazelle but even so, if you want to implement Python, somewhere you need to talk about a method called __str__

#

@flat gazelle the implementor in question is talking about "implementing" Python with a declarative json file.

grave jolt
#

wha-

flat gazelle
#

I mean, xslt does work and is turing complete

#

don't see why json couldn't have such a schema

grave jolt
#

well, of course you can implement Python like that

#

just like you can implement it in brainfuck

flat gazelle
#

it does seem like a slightly superfluous idea, considering that you could just use a programming language instead

spark magnet
#

@flat gazelle i think their idea is that once you have a large collection of programming language parts, a json file can pick and choose which ones to put togethr to compile a language.

flat gazelle
#

that still just seems worse than writing a compiler in a programming language

#

JSON is not a great config format

grave jolt
#

yeah, especially considering that e.g. Python and Haskell have completely different execution models

#

and different GC algorithms if I understand correctly

#

and how is he going to encode different type systems? (e.g. Agda vs Rust vs C++)

spark magnet
#

as far as I'm concerned, it's all nonsense, with a thick wall of aggressive insulting to defend it.

grave jolt
#

if it's just a JIT compiler for dynamically-typed interpreted languages like Python or Javascript or Smalltalk, then maybe it's not that crazy. But they're still different, so I can't imagine how it would work

spark magnet
#

"it can compile any language"

grave jolt
#

and also be faster than CPython

flat gazelle
#

I am not doubting this is possible, a JSON schema that is designed to emit LLVM IR would definitely be possible, and neos just seems like LLVM as far as this project is concerned. It doesn't seem at all worth the effort

limpid marten
#

Apparently it's enough to write a language inside a schema file and it will compile it. PES2_Shrug

flat gazelle
#

I mean, what is a C++ compiler source code but a schema

#

my key issue with this is really just that I don't want to write a JSON schema as a compiler, since JSON is not a good format to write with your own 2 hands

grave jolt
#

next step: make a json generator...

spark magnet
#

@flat gazelle to be fair, he says he is using "relaxed json", so you get to have trailing commas and comments

flat gazelle
#

json5 is a thing indeed

#

I feel like the only config powerful enough to make this not boilerplate is dhall

spark magnet
#

ugh, another one?

grave jolt
#

hahaha

#

it's the language PureScript uses by default for configs

#

but maybe we have enough config languages already

spark magnet
#

sorry, but if a syntax designer puts commas at the start of the line, they have already surrendered

grave jolt
spark magnet
#

right. it's absurd, and unneeded heree.

#

leading commas are only to work around the lack of trailing commas.

#

so why do it here?

grave jolt
#

i have no idea, it does look strange

flat gazelle
#

I think it's to make it hard to forget one

spark magnet
#

no, it's to make lines diff-able in languages that don't allow trailing commas

grave jolt
#

for some reason JSON doesn't do that, which seems strange to me

spark magnet
#

JSON doesn't allow it because JS didn't used to, and to be strict.

grave jolt
#

and I wonder why

spark magnet
#

i see

#

if all languages allowed trailing commas, no one would have used leading commas

grave jolt
#

Maybe I should ask about dhall in an FP discord

#

@spark magnet
I guess dhall has some reason to use leading commas, since it allows a leading leading comma for better alignment

{
  , foo = "a"
  , bar = "b"
}
spark magnet
#

it's just a bad habit. you can put the commas at the ends of the line

grave jolt
#

or at the starts

flat gazelle
#

I am guessing it is to be consistent with things like

name
  | True = 4
  | False = 5
```, since FP does have leading operators in quite a few cases
grave jolt
#

why are trailing commas better?

grave jolt
#

but then, we have bullet lists, where the 'delimiter' comes first

- a 
- b
- c
#

and also: You choose between a) broccoli b) salad

flat gazelle
#

honestly, I feel like configuration languages should be whitespace aware

spark magnet
#

yes, because it's more consistent with usual writing

grave jolt
#

but in a config, it's more like a bullet list, isn't it?

spark magnet
#

no

#

@grave jolt can i put a comma before the first item?

grave jolt
#

yes

flat gazelle
#

like, isn't

{
  foo = "a"
  bar = "b"
}
``` better overall
grave jolt
grave jolt
flat gazelle
#

that was actually a pain point quite a few people had with dhall, since it gets nested easily, you can easily lose track of the many many different kinds of closing braces.

grave jolt
#

@spark magnet Do leading commas really surprise you more than a config language having a type system? 🙂

flat gazelle
#

in real text, you never write comma separated lists on multiple lines. I don't think I would ever find this in a real text. Everyone would use bullet points or numbered lists

spark magnet
#

@grave jolt oh, there's plenty i'm concerned about in dhall-lang 🙂

#

it's just that having the very first thing you see use quirky syntax was a red flag

#

@flat gazelle but also in real text, you would never put space between a thing and the comma following the thing

gleaming rover
#

admittedly not many

spark magnet
#

it is, but only because trailing commas are forbidden (or were) in those regions (assuming by regions you meant programming language subcultures)

gleaming rover
#

wait, when you said "real text"

#

I took it to mean "natural language"

#

if that wasn't your intention then my bad

#

I meant geographical regions

spark magnet
#

no, you are right, we meant natural language

gleaming rover
#

which is a bit 🥴 to me but well

#

quite a minor point though

grave jolt
#

yeah ,that's pretty uncanny ,at least for me

gleaming rover
#

STOP 😡

grave jolt
#

okay ,no more ,sorry

gleaming rover
#

🤢

grave jolt
#

I promise , don't be mad , calm down

raven ridge
feral cedar
#

grammatically correct doesn't mean correct though

spark magnet
#

bottom line: if every language allowed trailing commas, no one would ever have started using leading commas

swift imp
#

What are we discussing

raven ridge
#

I've seen it mostly in SQL queries, which also don't allow trailing commas in lists

feral cedar
#

also, that snippet, starting the contents of the {} on the line where you put the {, but not ending the contents on the line with the }, it just looks lopsided

swift imp
#

Yaml sucks

#

There's too many ways to define the constructs

spark magnet
#

agreed

#

but that doesn't mean i want functions in my configuration files!

grave jolt
#

I think types and functions like that might be more useful in some markup language?

#

I made a small language that explored this a bit https://github.com/decorator-factory/python-fnl Not in any static-analysis way, but kinda works.
Basically, in HTML you can't put a "block" element inside an "inline" element, e.g. a <div> container inside a <b> (bold), otherwise you get undefined/quirky behaviour. And this checks that it doesn't happen.

#

But in theory, it can do a bit more

grave jolt
swift imp
#

Anyone think it's a shame bindings can't have docstrings?

#

Like a variable can't have one

vale flax
#

the name is the docstring /s

raven ridge
#

and so most of the dissent here comes from the fact that docstrings are good enough for functions/classes/modules, and that anything that works for variables/attributes will necessarily look very different from docstrings.

raven ridge
#

That said, Annotated might be the eventual solution for this

lime walrus
#

guys i wanted to start learning pygame
can i get some suggestions of how to start?

wide shuttle
#

Hey @lime walrus, it's probably better to ask your question in a channel like #game-development or #python-discussion. We try to keep this channel reserved for more advanced discussion of the Python programming language itself, as we want to give those kind of conversations a place in our community too.

lime walrus
#

my bad @wide shuttle thanks btw

paper echo
#

@swift imp ^

#
x: int
"Sphinx interprets this as a docstring"
raven ridge
# paper echo If it makes you feel better, Lisp does it too. It's more a clever use of syntax ...

Introspection stands in the way of attributes and names ever getting proper support for docstrings. Docstrings result in __doc__ being set, which means that they're only possible in places where new objects are created. You can never have a real docstring on something like x = 1 because there's no place to put the __doc__. So in that sense Sphinx recognizing docstrings on name bindings is even more of a hack. It's assigning meaning to them by parsing the code by itself and investigating the AST, not by introspecting the objects the way docstrings are meant to work. Which is why it's the only tool I know of to support that.

swift imp
#

Well then where are annotations held for a variable?

#

I know variables are just names and lack a dict but something is storing the annotation isn't it?

raven ridge
#

In bar: int = foo there's no new object being created, so there's no possible way to introspect the int annotation from bar, because instead you'd just find whatever annotation foo has.

flat gazelle
#

you can get int from the __annotations__ dict

swift imp
#

They're definitely stored

flat gazelle
#

in theory, bar: (int, "the bar attribute") = foo is possible

raven ridge
#

Huh, I stand corrected. So they're stored in a special property on the namespace the assignment happens in.

sacred tinsel
#

I did not realize __annotations__ existed even in globals

#
>>> number: int = 5
>>> __annotations__
{'number': <class 'int'>}
#

only ever accessed it on a class

swift imp
#

So like in theory if python had an eol character, typical docstring convention could work for variables and attributes lol

#

Ok color me this

flat gazelle
#

ye, it exists on modules too

swift imp
#

If I have an annotated variable in module x and import that variable from x into y, does the annotation hold

flat gazelle
#

well, the annotation is stored in the module x

raven ridge
#

In other words, no.

swift imp
#

I'm wondering if the import system causes it to move it into module y

flat gazelle
#

so once you alias to a new variable in a different module, it gets lost unless the typechecker keeps it

#

I would be very surprised if it got copied

swift imp
#

In which case importing a variable would cause it to lose its docstring

raven ridge
#

But I guess you're right that it would be possible to actually support docstrings for bindings by creating a new special variable like __docstrings__ for holding them. With the caveat that it wouldn't follow the object around, it would be stuck to the namespace.

#

That would be partial support, but enough to make it work in the context of ```py
import module
help(module)

swift imp
#

Yeah

#

I mean would copying them really matter?

#

Would it be that costly?

#

And then if you use like as to alias it can use that new alias instead

#

I have no idea how to do that at the c level, I'm just saying

#

Doesn't seem that that difficult

raven ridge
#

That would make py from mod import foo do something different than ```py
import mod
foo = mod.foo

swift imp
#

How so?

flat gazelle
#

foo = mod.foo would be a lot more difficult to get to copy

swift imp
#

Oh NVM

#

Yeah

#

It would add a lot of overhead right

#

Fuck

flat gazelle
#

it's more a matter of = takes a value on the rhs and never gets to touch the expression ast

#

the more stupid solution is to add a __doc__ next to the refcount in the pyobject struct

swift imp
#

Might as well add annotation there

#

Not literally, but if u were gonna

raven ridge
#

Neither of those work, because the same object can have different annotations and different docstrings for each reference

flat gazelle
#

oh yeah

#

that would require boxed references, rather than just raw pointers

#

which is a bit too silly for me

swift imp
#

I think the problem is that when you do the assignment or import, the annotation and doc is technically on the lhs

#

And it's all fucked

raven ridge
#
min: int = 0
"The minimum value ever read"
average: float = min
"The average of all values read"
``` There's only one `0` object there, and it can't hold both annotations and both docstrings as properties.
swift imp
#

Yup

unkempt rock
#

how to get connection uri for a dtabase?

grave thistle
#

Anyone doing the Pirple python course here?

cold forum
#

I'm dynamically creating classes for some tests using type(name, bases, clsdict). How do I specify the metaclass though? I tried setting __metaclass__ in the clsdict but it doesn't seem to work.

peak spoke
#

I'd use types.new_class

#

But to answer your question, metaclass would be used instead of type

raven ridge
#

Right: instead of calling type, you call the metaclass (which is itself a subclass of type)

cold forum
#

@peak spoke @raven ridge Makes sense. It did cross my mind, but for some reason I didn't try it at first.

raven ridge
#

TIL about types.new_class - I hadn't seen that before.

spring trellis
#

where can i learn python i want to learn

hexed spire
fallen slateBOT
#
Resources

The Resources page on our website contains a list of hand-selected learning resources that we regularly recommend to both beginners and experts.

spring trellis
#

thanks

frank violet
#

so is pywinauto what most people use for interacting with mouse/keyboard inputs?

#

I'm new and it just seems like I am guessing on how to fix my own code and eventually get it to work... I just don't know if its due to lack of experience or that the old code that is referenced doesn't work anymore.

noble depot
#

What type of real life problems you face which you think can be tackled digitally ?

limpid marten
unkempt rock
#

hi does anyone know django rest framework

unkempt roost
#

hi, i need to practice beautifulsoup, anyone have any tutorial

grave jolt
#

@unkempt roost @unkempt rock This channel is strictly for discussions about the Python language itself, not for general help with Python. You can look at the topical channels or see #❓|how-to-get-help.

bronze acorn
#

I wonder if alot of software companies use pypy with python for performance boost

open acorn
#

Hi- I have got python to read and name a specific excel cell that contains a URL(with openpyxl) , ALSO i have written a script with selenium to automate visit a website. How do i BRIDGE these 2 scenarios. And get SELENIUM to read that cell URL and visit the website automatically.(USING SUBLIME TEXT)

open acorn
#

ok

bronze acorn
#

Problem is pypy isn't compatible with Cpython apis, which make it less useful

feral cedar
#

i believe instagram uses pypy

peak spoke
#

Unless it changed recently, the few articles I stumbled upon from them were about cpython

feral cedar
#

huh, yeah, i can only find cpython articles

weary garden
#

I reckon I should have implemented Python by the summer; just need to get my multi-precision arithmetic lib finished then I can start...

raven ridge
weary garden
#

balanced by the fact that CPython is so much slower than pypy 🙂

raven ridge
#

well... pypy is much faster at running Python code than CPython is, but CPython is much faster at running C extension modules than pypy is.

gleaming rover
#

solution

#

make a third implementation with all the C extension speed of PyPy and the Python code speed of CPython

#

🚀

grave jolt
weary garden
#

something to think about when I create mine.

brave badger
grave jolt
gleaming rover
raven ridge
#

But... performance sensitive Python modules are commonly written as CPython extension modules. So, counterintuitively, pypy speeds up the parts of a program that don't need to be fast, and makes the parts that do need to be fast slower. More or less.

weary garden
#

I will have created one by the summer.

grave jolt
#

Are you planning to implement an entire Python interpreter from scratch?

weary garden
#

not quite, I will be creating a Python compiler from scratch

brave badger
#

lol

gleaming rover
grave jolt
#

Wouldn't a JIT/AOT compiler perform better for a dynamically typed language than a machine code compiler?..

weary garden
#

the goal is for my implementation to be about 3x faster than pypy

raven ridge
fallen slateBOT
#

@raven ridge :white_check_mark: Your eval job has completed with return code 0.

10
weary garden
#

@grave jolt my solution is JIT/AOT

grave jolt
#

but then it's not really a compiler, right?

gleaming rover
#

I don't mean to be mean

#

but I'm getting flashbacks to that Google Groups link @raven ridge posted here

#

a few days ago

#

sorry 😔

grave jolt
raven ridge
#

Ned posted, not me. 🙂

gleaming rover
#

oh

#

my bad

#

you talk the same way

weary garden
#

it compiles to byte code which is then JIT'd

open acorn
#

hey how do i use excel cell value as input for driver.get(cellValue) to vist that url in cell. I have already imported the cell value and workbookwith openpyxl. cant find help anywhere

grave jolt
#

right, like pypy

weary garden
#

my python implementation will actually just be a schema file for my universal compiler

grave jolt
#

I think I am indeed getting flashbacks

#

are you making a compiler that would compile any programming language at all?

weary garden
#

yes

#

python will be the first language I will support

grave jolt
#

so it would be able to compile Agda, Python, and VHDL?

weary garden
#

due to popularity of python

#

any programming language that can be compiled

grave jolt
#

okay, VHDL is a stretch

#

But how are you going to configure different runtimes? e.g. Agda is lazy, and Python is strict; and Agda has quite a complicated type system

weary garden
#

there is only one runtime

#

a "universal" runtime one might say

bronze acorn
grave jolt
#

@weary garden so how would you encode a type system in a schema?

bronze acorn
#

switch to c++

raven ridge
#

Yeah - it supports enough of the CPython C API as of now that most extension modules can compile fine for pypy

weary garden
#

by creating the relevenet semantic concept library(s)

#

relevent*

#

the schema in combination with semantic concept libraries defines the syntax and semantics of the programming language

raven ridge
#

just compiling Python isn't likely to make it much faster. The things that make Python slow to execute are all of the dynamic type checks and dynamic name lookups - which need to happen, unless you're implementing something that looks like Python but with different semantics.

bronze acorn
#

Pypy latest version support up to python 3.7

raven ridge
#

You can make a faster language that looks Python-like, but there's only so much faster that you can make Python without making pretty drastic changes to its semantics.

bronze acorn
weary garden
#

pypy does it and I will do better than pypy

bronze acorn
#

Even for basics types like int

raven ridge
#

well, like I was saying above - pypy does it, at the cost of being slower for the very things that people have optimized by writing them in C.

brave badger
weary garden
brave badger
#

By limiting the dynamic features, you get a superset/subset that's much easier to work with in terms of speed/optimization

raven ridge
#

I'm not sure about RPython, but yeah - one of the things that makes Cython faster is that it binds some names at compile time - you can't monkeypatch builtins in Cython modules.

bronze acorn
raven ridge
#

though with Cython that's an option that can be disabled, for better Python compatibility.

bronze acorn
#

That how is int is implemented in cpython

#

Oh wait

bronze acorn
#
/* Long (arbitrary precision) integer object interface */

extern typeobject Longtype;

#define is_longobject(op) ((op)->ob_type == &Longtype)

extern object *newlongobject PROTO((long));
extern long getlongvalue PROTO((object *));

raven ridge
#

one nice thing about open source is that it should be relatively easy to steal an arbitrary precision integer library, or a decimal floating point library, or whatever from another project.

grave jolt
weary garden
#

@raven ridge I am making my own.

raven ridge
#

micropython's int implementation is a bit easier to understand than CPython's, I think.

bronze acorn
#

What is micropython

bronze acorn
raven ridge
bronze acorn
#

But i would agree for rust being a good pick for performance

raven ridge
#

micropython is a Python implementation designed to run on resource constrained environments, like microcontrollers

bronze acorn
#

Cool

raven ridge
bronze acorn
#

At least python is the best for ML and data science

raven ridge
#

there's also a fork called circuitpython, maintained by adafruit, that is designed to be supportable across a wider variety of platforms.

bronze acorn
#

Python gui programming isn't that bad, but there are better options

raven ridge
#

or - circuitpython has fewer features than micropython, but the features that it does have are implemented much more uniformly across all of the platforms it supports.

weary garden
#

I think people say python is best for ML and data science simply because python is pervasive.

bronze acorn
#

Because syntax

#

You can still do it in c++, but God it is complicated.

weary garden
#

you will be able to visualize your python program as nodes and set breakpoints on nodes 😄

#

connected nodes*

raven ridge
#

I don't think it's pervasiveness, I think it's the robustness of the library ecosystem.

#

combined with the ease of getting started, perhaps.

weary garden
grave jolt
#

you mean, like the cascading debugger in Thonny? 🙂

weary garden
#

don't know what that is

grave jolt
feral cedar
#

it looks similar to pythontutor

grave jolt
#

Unless you're talking about visualising a syntax tree, not a running program, in which case I don't really see the point

weary garden
#

running program

#

or syntax/code

grave jolt
#

yeah, pythontutor does that as well

weary garden
#

(debugger/editor)

raven ridge
#

that debugger seems like by far the best thing about Thonny. It's an excellent way to teach people how stack frames work.

weary garden
#

you will also be able to create GUIs like that from Python itself

#

you will also be able to mix C and Python in the same source file

raven ridge
#

you can already do that in Cython.

grave jolt
#

Can you give an example of how you would mix JavaScript, Agda and Forth in one file?

weary garden
grave jolt
#

I've seen that

weary garden
#

it shows you how you mix code

grave jolt
#

yeah, but those are languages with very similar semantics, right?

#

To pick from the language list, how would you mix Brainfuck and Haskell?

weary garden
#

if there is no common semantic subset between the two languages when the code references each other then a compilation error will result

grave jolt
#

honestly, I don't see how this mixing could be useful

weary garden
#

which is why the ability to mix isn't a functional requirement; it is just a side effect of my chosen architecture that you can do that

#

a mere curiosity

sacred yew
#

hmmm, i still don't see how you can mix languages though

#

will you be able to access variable and stuff cross-language?

weary garden
#

yes

sacred yew
#

even though every language has a different type system?

weary garden
#

as long as there is common semantics associated with the variable

sacred yew
#

like mixing JS and C variables

#

or haskell with anything

grave jolt
#

hey, Haskell with PureScript should work!

#

minus the strictness and the concurrency model

sacred yew
#

*anything on the mentioned languages

grave jolt
#

ah

visual shadow
#

the convo earlier makes me curious, what exactly would it take to make a python "like" language fast?

raven ridge
#

nim is kinda Python-like, and statically transpiles to C.

visual shadow
#

never heard of nim before

raven ridge
#

there's only so fast you can make the language when everything is specified to be a dynamic lookup.

visual shadow
#

say, if i wanted to turn python into something that's fast, by forcing static types, but didn't want the added overhead of explicit declaration in terms of the code for example, that doable?

raven ridge
#

I've never written anything in it, but it looks quite nice

visual shadow
#

some kind of type inference

grave jolt
#

Type inference is pretty hard with an OOish type system, tho, right?

feral cedar
#

is it? doesn't c# have it now?

visual shadow
#

actually fundamental question, forgive my lack of knowledge here: how does a type inference system understand im trying to reassign a bad/different type in the code? Does it have to do essentially the same work that overhead of dynamic typing also underoes?

spark magnet
#

@weary garden you should spend more time implementing, and less time boasting.

raven ridge
#

someone on python-ideas had a suggestion for making Python faster by moving towards a two-phase execution model, with a separate "import time" that's distinguished from "runtime", and where certain dynamic operations - like rebinding a module level global - are allowed at "import time" but disallowed at "runtime", allowing you to cache the values of globals, and in theory making it easier to JIT calls to global functions.

visual shadow
# grave jolt Type inference is pretty hard with an OOish type system, tho, right?

i dont know, this is primarily an "outsider lookin in" perspective. but if you say that* it's hard with an OO type system then i'd be willing to even forego that. i suppose the thought experiment is this: what is the least amount of change a programmer might have to do such that their code still is as close to "python" as possible and this new "fast-python" language can achieve massive speedups?

#

And is this a futile endavour to begin with?

grave jolt
visual shadow
#

oh okay, that's something

unkempt rock
#

blah

grave jolt
#

@visual shadow type inference isn't an optimization technique, it's just a feature of static type systems where you don't have to specify the type yourself.

#

It's like solving an equation.

feral cedar
#

but knowing the types at runtime would allow you to do further optimization right?

grave jolt
grave jolt
feral cedar
#

so you don't have to check what types things are before performing operations on them?

visual shadow
#

basically im thinking type inference helps keep the cognitive load on a python programmer low, while enabling this "fast-python" language to work faster

#

so the inference is purely a "convenience" aspect i was going for

#

one thing i understand from the discussion so far is that in any fast language, dynamic typing has to go

grave jolt
feral cedar
#

oh

#

that's what i meant 😔

raven ridge
#

the biggest change you could make, with the most impact, would just be to make variable types "sticky". Once a value has been assigned to a variable, don't let anything else ever be assigned to it that would change its type, from the POV of the JIT. Or something like that.

spark magnet
visual shadow
#

is it possible to make these sticky variables optimized for 2 types of data types without much overhead? trying to think of None and python's default params and so on now

weary garden
#

@spark magnet maybe some other time; I am about to go to bed.

visual shadow
#

or let me rephrase that. A common construct in functions is having a None as a default value

raven ridge
visual shadow
#

where we check if its None before setting it to an additional value

spark magnet
visual shadow
#

hm okay

raven ridge
#

or perhaps by special casing None entirely, to force dynamic lookups if the value is the None singleton - the fact that it's a singleton may allow that.

visual shadow
#

i suppose we could introduce special syntax for specifically declaring default Nones

bronze acorn
#

I just wonder why python types weren't made to be Primitives rather than Objects?

visual shadow
bronze acorn
#

Hmm

visual shadow
#

Like at the end of the day, python is excellent at what it's built for. cutting down developer time

bronze acorn
#

Kinda make sense

feral cedar
#

huh

bronze acorn
#

Um

#

Delete

grave jolt
#

!pban @rotund quest nsfw

fallen slateBOT
#

:incoming_envelope: :ok_hand: applied ban to @rotund quest permanently.

grave jolt
#

oh crap, I probably shouldn't've deleted

bronze acorn
#

Why not

raven ridge
#

not having primitives means that the language is slower, but allows some things you couldn't otherwise have - like a unified type hierarchy, subclasses of builtin types, etc

grave jolt
bronze acorn
#

Banning from the server is enough

grave jolt
raven ridge
#

Python integers even have methods.

bronze acorn
#

I don't know much about js

visual shadow
#

i tried to search further for reasons why python chose to avoid primitives. one of the top article says "Python has four primitive types: integers, floats, booleans and strings. "

#

:/

raven ridge
#

!e ```py
x = 256
print(x.to_bytes(5, "little"))

fallen slateBOT
#

@raven ridge :white_check_mark: Your eval job has completed with return code 0.

b'\x00\x01\x00\x00\x00'
bronze acorn
grave jolt
raven ridge
#

not None? 😄

grave jolt
bronze acorn
#

Just throw "everything is object" meme at these articles

visual shadow
#

haha yeah, unfortunate

bronze acorn
#

"wait, so it is all objects? "
"always has been"

raven ridge
#

It seems impossible to come up with any definition for what "primitive" could possibly mean in Python that would include str but not bytes

#

even if you accept a "nontraditional" definition for "primitive", str and bytes are equally primitive.

grave jolt
#

@raven ridge maybe the article is talking about Python 2 lemon_pleased

#

but then, it has unicode

raven ridge
#

then str and unicode are equally primitive

#

🙂

bronze acorn
#

I once wasted my time on reading an article about "how can python be faster than c++" and he compared multithreaded program to c++ single threaded program

visual shadow
#

for ints, i can atleast think of the "infinite precision" feature that's handy. would primitives even be able to support that?

grave jolt
bronze acorn
#

I will try to found out the article

visual shadow
raven ridge
bronze acorn
raven ridge
#

primitive in the sense that it doesn't participate in the OOP object model

visual shadow
#

conversations here make me want to understand and peel away the layer of abstraction that im comfortable with, and actually try to understand the underlying semantics of it all

raven ridge
#

I've been writing some C++ for the last few days that has been driving me absolutely crazy for lack of expressiveness. I really, really just want to be able to return a type from some functions. 😕

bronze acorn
#

@visual shadow oh yeah, they used Numba for python to make it faster

raven ridge
#

I could do some type erasure crap and come up with something that works, probably, but - not having types as first order objects has been killing me in this project.

bronze acorn
visual shadow
#

return int is how i understood it.

bronze acorn
#

Me too

raven ridge
#

yeah, exactly.

bronze acorn
#

Why would you do that?

visual shadow
#

perhaps what_dataype_i_need("params")("input") if i had to guess?

#

ie. the type is probably being used to process something down the line to create actual objects/values

#

or would have been*

raven ridge
#

because I have something whose type isn't known at compile time, but is known at runtime - which means I need to have functions at compile time that are equipped to deal with any possible type, and I need to decide which of them to call at runtime. But that means I need to do something like:

if (var.type == INT_TYPE)
    return do_something_with_value<int>(var, param1, param2)
if (var.type == DOUBLE_TYPE)
    return do_something_with_value<double>(var, param1, param2)
if (var.type == FLOAT_TYPE)
    return do_something_with_value<float>(var, param1, param2)
feral cedar
#

🤢 that's terrible

raven ridge
#

it'd be much nicer to be able to do:

if (var.type == INT_TYPE)
    T = int
else if (var.type == DOUBLE_TYPE)
    T = double
else if (var.type == FLOAT_TYPE)
    T = float
return do_something_with_value<T>(var, param1, param2)
#

but I can't, because variables can't hold types in C++.

bronze acorn
#

@raven ridge i am sure there is an std function that check variable type

#

Like typeid()

visual shadow
#

that's probably covered in this part var.type == INT_TYPE.

raven ridge
#

nah, you're misunderstanding - I'm not checking what type a C++ object has, I'm checking what type of value it should be interpreted as.

#

Imagine the value is always a str, and I'm deciding whether to parse it as an int, or a double, or a float, based on a schema. Something like that.

visual shadow
#

ha, had a feeling it would be something like that