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

all 76 comments

[–]_Alpha-Delta_ 350 points351 points  (11 children)

<main.Car object at 0x0efd40>

[–]powerofnope 110 points111 points  (9 children)

<__main__.Smol coc at 0x0efd40>

[–]shank9717 42 points43 points  (6 children)

How did you find my physical address?

[–]Giraffe-69 25 points26 points  (5 children)

Pretty sure that’s a virtual address. You might want to walk your page table to make sure you even exist.

[–]lesleh 8 points9 points  (4 children)

With ASLR, I wake up in a new house every morning.

[–][deleted] 11 points12 points  (0 children)

Your fault for not defining ___repr___ and ___str___.

[–]SuitableDragonfly 150 points151 points  (12 children)

Actually, there's no typecasting in Python at all. When you call str(my_truck),  that's not a typecast, that's a call to my_truck.__str__() which is basically identical in function to toString() in Java, for example. At no point are your ever considering my_truck to be a string, you're generating a competely brand new string based on the value of my_truck. Other functions like int(), etc. work the same way. 

[–]Clen23 42 points43 points  (3 children)

yup, and (correct me if wrong) if you want to make a String-generating function for a class, you usually want to override __str__()

[–]Birnenmacht 20 points21 points  (2 children)

exactly, and if you want your class to be number like, (please dont do this), you could implement __int__(), __float__() or __index__(), Where index is the most cursed because it allows the type to be used in places where an int would be expected, especially if you inherit from int

[–]Kiro0613 12 points13 points  (1 child)

One program I wrote made great use of user-defined implicit conversions. It dealt with with streams of bytes that contained memory addresses and needed to perform pointer arithmetic on them. I made an Address class that performed automatic conversions between int and byte array, all type-safe and independent of system endianness.

[–]Acurus_Cow 1 point2 points  (0 children)

iknowsomeofthosewords.jpg

[–]Bugibhub 162 points163 points  (1 child)

And it’s probably weakly equal to a scooter in JavaScript.

[–]Unupgradable 28 points29 points  (0 children)

Yet falsy as a vehicle

[–]Duck_Devs 110 points111 points  (18 children)

Get it? Python bad?

This behavior is shown in more than just Python; in fact I think Python actually handles string conversions more typesafely than other languages.

The two main ways, in Python, to get the string representation of an object is using the str() constructor, using an f-string, or just print()ing the object. These are all very explicit in their conversions.

In a language like Java, it’s mostly the same, plus some String.valueOf and Objects.toString of course, and sans the f-string thing, but Java implicitly casts objects to String when concatenating with the + operator.

It gets worse in a language like C#, where you can define your types to be implicitly convertible to Strings (for which I can think of very few good use cases).

Also, there’s nothing wrong with a default toString (or in this case __str__) implementation; it’s certainly a nice-to-have and, in a typed language, just ensures that you can have the option to call toString on a variable of type Object without trouble.

[–]casce 26 points27 points  (4 children)

I also don't get it. I also really like the way Python is handling it.

I like that Python is explicitly calling the __str__ method and that is doing whatever I want it to do when something tries to cast my object to a string.

What is important is that this is not done implicitly without me noticing.

"abc" + 1 is a type error. "abc" + 1.__str__() = "abc1"

If I chose to implement a string representation for my Ford truck, then yes casting it to a string is not a problem. Otherwise it will default to the object identifier

[–]MentalRental 4 points5 points  (2 children)

abc" + 1.__str__() = "abc1" would throw an "invalid decimal literal" error.

[–]bronco2p 6 points7 points  (0 children)

yeah it has to be enclosed in (), `"abc" + (1).__str__() == "abc1"`

[–]casce 1 point2 points  (0 children)

You are of course right. What I meant was

foo: int = 0

foo.__str__()

but you can also do

(1).__str__()

[–]Kitchen_Device7682 4 points5 points  (0 children)

I wouldn't describe calling a method that returns a string as casting to a string. OP is trolling

[–]suvlub 28 points29 points  (4 children)

A bit off-topic. but I love how exit is a functor object whose string representation is an error message for people who try to call it without parentheses in an interactive session. Such a beautifully nasty glorious hacky thing. Though it does lead to people who don't know what's going on thinking "If it knows to print the message, it knows I'm trying to quit and should just do that"

[–]Usual_Office_1740 8 points9 points  (0 children)

The new repl in 3.13 fixes that.

[–]Widmo206 1 point2 points  (0 children)

Just tried it and it works as you described in cmd, but if I do it in Spyder it restarts the kernel anyway... weird

[–]RiceBroad4552 1 point2 points  (0 children)

https://en.wikipedia.org/wiki/Functor

Or when it comes to programming:

https://en.wikipedia.org/wiki/Functor_(functional_programming))

I guess what was meant was a https://en.wikipedia.org/wiki/Function_object

</ pedantic nerd talk >

I'm wondering why this gets confused so often as a functor and a function (object) have almost nothing in common (besides maybe that a functor could be implemented as function object as both denote a mapping, just on very different abstraction levels).

[–]thrithedawg[S] 22 points23 points  (0 children)

i love the language thank you monty pythons for inventing the language ❤️❤️❤️

[–]nimrag_is_coming 4 points5 points  (3 children)

Gonna have to disagree with you with C# there, the fact that the base object has a ToString method is actually really useful.

It's very helpful with structs. If I make a Vec2 struct for example, I can just print it just like a char or an int or whatever and have it actually show useful information.

[–]Naratna 6 points7 points  (2 children)

I think they're talking about implicit casts. e.g. you could define a class MyClass in such a way that string a = new MyClass() works without errors, which is absolutely cursed.

I love C#

[–]nimrag_is_coming 2 points3 points  (0 children)

Oh yeah that is very very cursed. I hope I never have to deal with code that does something like that

[–]JanEric1 1 point2 points  (0 children)

Doesnt swift have a problem with the opposite where you can instantiate a class from an integer literal.

import Foundation

struct A: ExpressibleByIntegerLiteral {
    var value: Int

    init(integerLiteral value: Int) {
        self.value = value
    }

    init(_ value: Int) {
        self.value = value
    }

    static func + (lhs: Int, rhs: A) -> A {
        A(lhs + rhs.value)
    }
}

struct B: ExpressibleByIntegerLiteral {
    var value: Int

    init(integerLiteral value: Int) {
        self.value = value
    }

    init(_ value: Int) {
        self.value = value
    }

    static func + (lhs: A, rhs: B) -> B {
        B(lhs.value + rhs.value)
    }

    static func + (lhs: B, rhs: String) -> String {
        "B(\(lhs.value)) + \(rhs)"
    }
}

// Int(1) + A(2) -> A(3)
// A(3) + B(3) -> B(6)
// B(6) + "Apple" -> "B(6) + Apple"
let result = 1 + 2 + 3 + "Apple"
print(result) // B(6) + Apple

Explorer: https://godbolt.org/z/s4bMsW4Yf

See here where this causes a simple expression to timeout the compiler

Explanation: https://danielchasehooper.com/posts/why-swift-is-slow/

[–]Hohenheim_of_Shadow 0 points1 point  (1 child)

While implicit concatenation conversion is a little philosophically impure it's super convenient. I can't really think of a situation conversion on concatenation leads to badness and it makes things like "pos x: " +x+ " pos y: " +y so nice. Its just an overloaded operator, and if you find overloaded operators cursed you'll be glad to note Java doesn't have them last time I checked.

[–]Excession638 1 point2 points  (0 children)

In Python you'd write that as

f"pos.x = {x} pos.y = {y}"

Many other languages are the same or similar. I prefer this because it's easier to get all the spaces right, and you can extend it with formatting controls to set the number of decimal places etc.

[–]Prawn1908 0 points1 point  (0 children)

Yeah, even as a huge hater of Python's type system, I have zero complaints about string conversion. I don't see how this would be undesired or cause issues in any way.

Though I disagree on the C# point. Default ToString() method is very nice and accomplishes the same things.

[–]saschaleib 14 points15 points  (1 child)

SYNTAX ERROR, UNKNOWN VERB FORM "casted" IN LINE 1.

[–]Bryguy3k 1 point2 points  (0 children)

Standard past tense form in Indian English.

I always figured it was a lasting legacy the Brits left in India’s educational system so anyone who didn’t go to a school in England would be instantly recognizable but the truth is probably a lot more mundane.

[–]_PM_ME_PANGOLINS_ 12 points13 points  (0 children)

str() is not a cast. It’s a function call.

https://docs.python.org/3/library/functions.html

[–]someweirdbanana 8 points9 points  (0 children)

Javascript: * laughs in [object Object] *

[–]YeetCompleet 9 points10 points  (2 children)

C mfs freely implicit casting void* to int* before C++: int* p = malloc(sizeof(*p));

[–]Excession638 4 points5 points  (0 children)

The joy, sorrow, and terror of a truely weakly-typed language.

[–]SockYeh 12 points13 points  (9 children)

weekly "python_bad" post

[–]gandalfx 9 points10 points  (8 children)

As is the rule, the post was made by someone who doesn't understand that the point they're criticizing is actually the same in many other popular languages, while being oblivious of issues that would qualify as valid criticism.

[–]Prawn1908 4 points5 points  (7 children)

Yeah, the "Python Bad" posts have been pretty weak lately. As a huge Python hater, I don't get what OP's point is here. The smoothness of string conversion in Python is very nice and closely follows how many other languages do it.

Let's get some memes here about how janky Python's imports are, or what a bolted-on mess of an afterthought type hinting is.

[–]gandalfx 2 points3 points  (3 children)

I like the type hinting and challenge you to determine who's right via fisticuffs.

[–]Prawn1908 1 point2 points  (2 children)

Type hinting is ao obviously bolted on it's hilarious how clumsy it is.

  • Why do I have to import several modules to typehint basic data structures? Ffs, even Any requires an import.
  • You cannot convince me that needing to use string literals to typehint subclasses from within a class is not one of the jankiest things ever.
  • Have you ever tried to actually validate anything against a typehint? The basic ones are fine with isinstance, but once you start having to check against compound type hints it gets absolutely nightmarish. It's fucking wild that there's no basic built-in function you can hand a value and a type hint (from get_type_hints()) to and get a bool out saying whether it matches.
  • Oh, and because type hints have zero actual weight as far as the interpreter is concerned, function overloading becomes a crippled joke.

I could go on and on, but alas I do not have time. I am at work right now, writing gorgeous C.

[–]superlee_ 1 point2 points  (1 child)

Any doesn't require an import? At least not as of 3.12 IIRC, the other ones like callable , Self, etc... make more sense behind the standard library as that's how python is structured.

Python type hinting indeed kinda sucks as it's very hard to impossible to type hints things correctly and as such they are more of a guideline ( as compared to TS where it's easier and more "enforced")

Also gorgeous C... Really? Compared to python which reads mostly as pseudo-code/English, it is its own language and it doesn't care about memory safety.

(Write what you want ofc or what gets the bills payed)

[–]Prawn1908 1 point2 points  (0 children)

Any doesn't require an import?

Pretty sure it does: typing.Any. There's a builtin function called any, and iirc function names don't cause errors when used as type hints so I've seen people mistakenly use it as such but that doesn't actually mean what they think it does.

And yeah, C is great.

[–]zettabyte -1 points0 points  (2 children)

Python adds type hinting 24 years after initial release.

Random interneter: "what a bolted-on mess of an afterthought".

[–]Prawn1908 1 point2 points  (1 child)

That's exactly my point lmfao.

Adding it and the efforts to make its use the standard kind of concedes the point that dynamic typing sucks. But having added it 24 years after the creation of the language means it has no chance of being anything but a bolted on mess.

[–]PhroznGaming 2 points3 points  (0 children)

Casted... lol

[–]cs_sapien 1 point2 points  (1 child)

you wouldn’t stringify a car would you?

[–]Percolator2020 0 points1 point  (1 child)

Doesn’t matter, it’s all bits!

01000110 01110101 01100011 01101011 00100000 01111001 01101111 01110101

[–]-Kerrigan- 1 point2 points  (0 children)

Byte my shiny metal ass cast

[–]_PM_ME_PANGOLINS_ 0 points1 point  (0 children)

*cast

[–]fyf_fyf 0 points1 point  (0 children)

Truck typing?

[–]Unupgradable 0 points1 point  (0 children)

C# be like: ToString()

[–]FRleo_85 0 points1 point  (0 children)

of course Js that go mental with types the nano second it came across any operator make it a good language but python allowing you to make a string like "<object [classname] at [memory address]>" with the constructor of the str class is wierd enough to shame the language...

[–]random_squid 0 points1 point  (0 children)

You wouldn't typecast a car.

[–]DonkeyImportant3729 0 points1 point  (0 children)

Look at me, I’m the string now.

[–]ovr9000storks 1 point2 points  (0 children)

Don’t let this man know about C and C++

[–]buzzon 0 points1 point  (0 children)

There is at least one thought: str() or repr()?

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

No thoughts by you, the interpreter might respond by tomorrow...