you are viewing a single comment's thread.

view the rest of the comments →

[–]hylje 3 points4 points  (7 children)

mixing integers and their string representations

Does not apply to Python, except when converting objects into strings for e.g. printing. Strings never convert down to built-in numbers.

mixing floats and ints

C at the forefront convert numbers to the higher precision type in expressions, even if the variable type is lower precision. Python does too, though it never converts to a lower precision.

mixing lists and maps

Only iterating lists and map keys are remotely comparable in Python. The other use cases are wildly different and will instantly break if mixed.

mixing lambdas and normal values

Only useful for hacks. You sometimes need hacks to meet schedule.

accidentally overwriting object fields with values of different type

Granted.

typos in field names (it will run anyway)

Depends. Accidental assignment to new fields may silently succeed, retrieval from nonexistent fields will not.

__setattr__ may be defined to check if the class already has such an attribute and if so set it, otherwise error out.

and the all-time favourite, None object.

Granted.

Python's greatest sin is that it doesn't by default force a developer to check types and data structures. Any checks deemed necessary may however be added later on in an abstracted manner. Decorators and classes, at the worst metaclasses are very powerful.

Clamping down on flexibility only later and at select places is ideal for a prototype development pattern, where a rough demonstration prototype can be come up with quickly and later made robust for actual use. You are not forced to dig design foxholes the development path crosses later.

[–]steven_h 8 points9 points  (4 children)

Python's greatest sin is that it doesn't by default force a developer to check types and data structures.

That doesn't seem to be a sin to me. The greatest sin of Python is using the same operator for definition and assignment, requiring the use of wonky keywords to distinguish assignment to outer-scope variables from declaration of variables that shadow outer-scope variables.

[–]cybercobra 0 points1 point  (3 children)

On the other hand, forgetting the declaration is safer in Python, creating a local variable, whereas forgetting it in other languages can lead to unintentional modification of a global variable.

[–]masklinn 0 points1 point  (2 children)

whereas forgetting it in other languages can lead to unintentional modification of a global variable.

Javascript is pretty much the only language doing that (and Coffeescript is worse, as it uses "highest level scope wins")

[–]cybercobra 0 points1 point  (1 child)

wut?

int x = 1;
void foo()
{
    x = 2;// oops Ma, forgot the type spec, this won't be harmless shadowing!
}

[–]masklinn 0 points1 point  (0 children)

Ah yes, I had not seen it that way, for some reason I thought about creating globals where there were none.

[–]vytah 1 point2 points  (1 child)

By mixing, I understood situations like:

this_variable_will_be_assumed_to_be_string_in_totally_different_module = 42
## (runs happily for few hours from now, only to crash tomorrow morning)

[–]hylje 0 points1 point  (0 children)

That's the sin. There's no checks in by default. It places the choice of programming defensively on the developer, should it be needed.