Reason why I hate dynamic typing in programming languages

Started by TomToad, March 20, 2018, 12:13:53

Previous topic - Next topic

TomToad

So how many hours are wasted by Python programmers trying to track down a bug like this?
class MyClass:
    count = 10

x = MyClass()
x.cuont = x.count + 1
print(x.count)


While in C++ you would get an error
C:\Users\James\Projects\testobj\testclass\main.cpp|13|error: 'class MyClass' has no member named 'cuont'|
||=== Build failed: 1 error(s), 0 warning(s) (0 minute(s), 0 second(s)) ===|

but in Python, a new member called cuont will be created instead.  In a large project, that could mean your program will seem to run correctly and then crash for no reason.

Python has a lot of features that I like, but this is not one of them.
------------------------------------------------
8 rabbits equals 1 rabbyte.

meems

i have a similar sentiment, its more aimed at case sensitivity, but I've spent a lot of time chasing typos in variable names - for some reason I don't mind it as much, likely because its been part of debugging since my 1st program in the 1980s on my C16+4.

Aren't you meaning strict vs non-strict declarations, as opposed to dynamic typing? A static typed language could be just as prone to your example bug.

I'm not a python fan. It propounds itself as an easy to use language with an overlay of neat layout, but its complexity, abstractness and symbolic functions can make it cryptic. Although, just as with any OTT language like Lisp, you can use a subset of its functionality to keep things easier to read.

TomToad

You would not have the same bug in a statically typed language since no variable called cuont has been declared.  There is a possibility in a non-strict language that cuont will automatically be entered into the symbol table with a default type, but that usually happens on a local scope and disallowed on a class scope.  Even then, I still would not like this default behavior and prefer everything explicitly declared, which is the main reason why I use SuperStrict on BMax and one of the things I don't like in AGK.

In a dynamically typed language, such a thing is allowed.  As I learn more about Pythin classes, and its dynamic types, I see even more potential for confusion.  For example.
class MyClass:
    x = 1
    y = 2
    z = 3

#create the class and print out its contents
a = MyClass()
b = MyClass()
c = MyClass()
print("MyClass.x = ",MyClass.x,"MyClass.y = ",MyClass.y,"MyClass.z =",MyClass.z)
print("a.x = ",a.x,"a.y = ",a.y,"a.z = ",a.z)
print("b.x = ",b.x,"b.y = ",b.y,"b.z = ",b.z)
print("c.x = ",c.x,"c.y = ",c.y,"c.z = ",c.z)
print()

print("MyClass.x = 4")
MyClass.x = 4
print("MyClass.x = ",MyClass.x,"MyClass.y = ",MyClass.y,"MyClass.z =",MyClass.z)
print("a.x = ",a.x,"a.y = ",a.y,"a.z = ",a.z)
print("b.x = ",b.x,"b.y = ",b.y,"b.z = ",b.z)
print("c.x = ",c.x,"c.y = ",c.y,"c.z = ",c.z)
print()

print("a.x = 5")
a.x = 5
print("MyClass.x = ",MyClass.x,"MyClass.y = ",MyClass.y,"MyClass.z =",MyClass.z)
print("a.x = ",a.x,"a.y = ",a.y,"a.z = ",a.z)
print("b.x = ",b.x,"b.y = ",b.y,"b.z = ",b.z)
print("c.x = ",c.x,"c.y = ",c.y,"c.z = ",c.z)
print()

print("MyClass.y = 6")
MyClass.y = 6
print("MyClass.x = ",MyClass.x,"MyClass.y = ",MyClass.y,"MyClass.z =",MyClass.z)
print("a.x = ",a.x,"a.y = ",a.y,"a.z = ",a.z)
print("b.x = ",b.x,"b.y = ",b.y,"b.z = ",b.z)
print("c.x = ",c.x,"c.y = ",c.y,"c.z = ",c.z)
print()

print("MyClass.x = 7")
MyClass.x = 7
print("MyClass.x = ",MyClass.x,"MyClass.y = ",MyClass.y,"MyClass.z =",MyClass.z)
print("a.x = ",a.x,"a.y = ",a.y,"a.z = ",a.z)
print("b.x = ",b.x,"b.y = ",b.y,"b.z = ",b.z)
print("c.x = ",c.x,"c.y = ",c.y,"c.z = ",c.z)
print()

print("del a.x")
del a.x
print("MyClass.x = ",MyClass.x,"MyClass.y = ",MyClass.y,"MyClass.z =",MyClass.z)
print("a.x = ",a.x,"a.y = ",a.y,"a.z = ",a.z)
print("b.x = ",b.x,"b.y = ",b.y,"b.z = ",b.z)
print("c.x = ",c.x,"c.y = ",c.y,"c.z = ",c.z)
print()

This outputs
MyClass.x =  1 MyClass.y =  2 MyClass.z = 3
a.x =  1 a.y =  2 a.z =  3
b.x =  1 b.y =  2 b.z =  3
c.x =  1 c.y =  2 c.z =  3

MyClass.x = 4
MyClass.x =  4 MyClass.y =  2 MyClass.z = 3
a.x =  4 a.y =  2 a.z =  3
b.x =  4 b.y =  2 b.z =  3
c.x =  4 c.y =  2 c.z =  3

a.x = 5
MyClass.x =  4 MyClass.y =  2 MyClass.z = 3
a.x =  5 a.y =  2 a.z =  3
b.x =  4 b.y =  2 b.z =  3
c.x =  4 c.y =  2 c.z =  3

MyClass.y = 6
MyClass.x =  4 MyClass.y =  6 MyClass.z = 3
a.x =  5 a.y =  6 a.z =  3
b.x =  4 b.y =  6 b.z =  3
c.x =  4 c.y =  6 c.z =  3

MyClass.x = 7
MyClass.x =  7 MyClass.y =  6 MyClass.z = 3
a.x =  5 a.y =  6 a.z =  3
b.x =  7 b.y =  6 b.z =  3
c.x =  7 c.y =  6 c.z =  3

del a.x
MyClass.x =  7 MyClass.y =  6 MyClass.z = 3
a.x =  7 a.y =  6 a.z =  3
b.x =  7 b.y =  6 b.z =  3
c.x =  7 c.y =  6 c.z =  3

Notice that x, y, and z start out all at the class level.  Similar to Global in a BMax type or static in a C++ class.  Changing the values at the class level will change it for all the instances.  However, when you assign a value from an instance, a new variable with the same name is created and attached to that one instance.  Now any changes to the class level variable will be hidden by the instance version.  Now comes the real question. After creating a.x and deleting a.x a number of times, what will print(a.x) print?  The class level x or the instance level x?  You will need to trace the code or set up debug points to find out.  No worries with a statically typed language like BMax or C++ because a class level variable and an instance level variable cannot coexist with the same name.

Note, there seems to be a bit of confusion with the term "dynamic type."  Do not confuse it with dynamic values.  A variable with a dynamic value can change its value throughout the course of a program.  So z can be 10 one moment and 50 the next.  This is the way most variables behave.  Static values mean that the value never changes, i.e. a constant.  Dynamic types means that the variable can change type throughout the program, so z can be an integer one moment, then a string the next. so
z = 10
print(z)
z = "Hello, World!'
print(z)

is valid Python code, but would produce an error in BlitzMax. "Unable to convert 'String' to 'int'"
------------------------------------------------
8 rabbits equals 1 rabbyte.

Rick Nasher

So from this I get AGK's #option_explicit is not really as strict as SuperStrict, hence the name.

But even though hard to debug, I suspect functionality such as you describe in Python
Quotex.cuont = x.count + 1
might actually have it's uses..
_______________________________________
B3D + physics + shaders + X-platform = AGK!
:D ..ALIENBREED *LIVES* (thanks to Qube).. :D
_______________________________________

TomToad

Quote from: Rick Nasher on March 20, 2018, 17:40:05
So from this I get AGK's #option_explicit is not really as strict as SuperStrict, hence the name.
Didn't know about#option_explicit. I think that will solve one of my biggest complaints about AGK. :)
------------------------------------------------
8 rabbits equals 1 rabbyte.

Rick Nasher

#5
Little while back there was a nice pdf with aan overview of all AGK2 commands on their Facebook page which might be handy. Don't see it now but perhaps cos I'm on my phone. If not I'll see if I can share later on.

[EDIT]
https://www.facebook.com/download/preview/1798659163735837

Or

here the PDF at AGK Generic Info

_______________________________________
B3D + physics + shaders + X-platform = AGK!
:D ..ALIENBREED *LIVES* (thanks to Qube).. :D
_______________________________________

Steve Elliott

#6
Ooo, you should always always define your data type.  I hate languages that give this as an 'option'.  Like the author didn't want to offend anybody, muppet...Therefore people that code software in that language have software that is crashing unexpectedly, simply because the author caved on syntax.

And quite frankly what is this bollocks of adding a command such as 'strict' and 'super strict' and '#option_explicit'?  The language is what it is, rather than a mess of rules that can be used or completely ignored, depending on each individual coder!  #chaos

Rant over lol.
Win11 64Gb 12th Gen Intel i9 12900K 3.2Ghz Nvidia RTX 3070Ti 8Gb
Win11 16Gb 12th Gen Intel i5 12450H 2Ghz Nvidia RTX 2050 8Gb
Win11  Pro 8Gb Celeron Intel UHD Graphics 600
Win10/Linux Mint 16Gb 4th Gen Intel i5 4570 3.2GHz, Nvidia GeForce GTX 1050 2Gb
macOS 32Gb Apple M2Max
pi5 8Gb
Spectrum Next 2Mb

Rick Nasher

But.. where would all that lovely spaghetti code go to? Lets ditch functions, gosub's even and go back to the plain and simple, BASIC goto. You've all spun out of control- you logic obsessed control freaks(just kidding of course..   I can imagine some peoples hair raising right now, just thinking about it. lol).  :P
_______________________________________
B3D + physics + shaders + X-platform = AGK!
:D ..ALIENBREED *LIVES* (thanks to Qube).. :D
_______________________________________

Steve Elliott

Win11 64Gb 12th Gen Intel i9 12900K 3.2Ghz Nvidia RTX 3070Ti 8Gb
Win11 16Gb 12th Gen Intel i5 12450H 2Ghz Nvidia RTX 2050 8Gb
Win11  Pro 8Gb Celeron Intel UHD Graphics 600
Win10/Linux Mint 16Gb 4th Gen Intel i5 4570 3.2GHz, Nvidia GeForce GTX 1050 2Gb
macOS 32Gb Apple M2Max
pi5 8Gb
Spectrum Next 2Mb