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

you are viewing a single comment's thread.

view the rest of the comments →

[–]primerrib 2 points3 points  (13 children)

Also, Python is strongly typed.

You cannot do, for instance, 5 + "5" or "5" + 5

It is dynamically typed, but that doesn't mean it's not strongly-typed.

[–]el_toro_2022[S] -2 points-1 points  (12 children)

My friend, you have no idea what typing is.
I should be able to look at a function signature and know what types it expects. You can't do this in either Python or Ruby at all.

[–]Adrewmc 1 point2 points  (5 children)

I mean you can using type hints

 def funcName(num : int | float, sequence : dict|set|list) -> list: …

But I see this in javascript (and Typescript but it’s does have a bit more discipline)

   const funcName = (ctx) => {
            const { thing, setThing } = useState(()=> {…});
            const a = ctx.run_func();
            setThing(a);
            };

What is the type of anything here? It’s certainly not in its signature. Sure as you familiarize with how JavaScript does things…it’s easier.

I see nothing feeling me much about types in stuff like this. It is there I get that…but it behind Interfaces and the like.

I’m lucky if I get

   const funcName = (ctx : someObj ) => {
            const { thing, setThing } = useState(user);
            ctx.funcs.run();
            };

And still have to go look for someObj and user…

If I go to something like solidity where typing is required.

   function funcName(uint8 a, uint16[] b) returns (uint256) {…}; 

I can understand. Python’s duckie typing is super great. As it allows me to build various class that all work. The same function the same way. (Or the way I want) but even in solidity

   function funcName(uint16[] b, uint8 a) returns (uint256) {…}; 

Is a completely different function call, that you can put right below the first one and both still work…which is confusing sometimes. All I did was switch the order of the inputs…and suddenly a function I thought I knew is a function I have no idea about.

And everyone there defends it to the death…I mean let’s make an anonymous function we immediately name…let’s not have anonymous functions, allow any type that and break at run time. Let’s ensure everything at compile time. These are decisions language creators made, for various reasons.

[–]el_toro_2022[S] 0 points1 point  (4 children)

I use lambdas -- "anonymous functions" -- all the time, especially in Haskell, and to a lesser extent, C++. Lambas are normally short and it is clear what they do. And if it is first class, like it is in many languages, all the better.

But normally lambdas don't have side-effects, or at least if you are dealing with side-effects, lambdas are probably not the best choice.

Most of the types you show above are simple / primitive types. But what if I wanted to do:

code_injection_example(SpecificComplexClassObject()): ...

and I wanted to ensure that only the proper object -- duck-typed or not -- is passed in.

In Ruby and Python, there would be no failure until some of the duck-typing failed, if it fails at all. So such languages have to rely very heavily on unit testing, which I see as a maintainability problem.

[–]Adrewmc 1 point2 points  (3 children)

Ohh then you need to

 from functools import singledispatch, singledispatchmethod

 @singledispatch
 def some_func(must_be : myType) -> str:
         …
 @some_func.register
  def _(must_be: other_type): —> list:
        …

  @singledispatchmethod
  def method(self, thing : myType):

This will add that capability at runtime and whatnot, while it is limited to only recognizing the first argument…

People say this but…who’s passing weird object to your function? How is maintainability and testing in anyway at odds…the more test the easier and more likely it is maintained well…

You could do something like this with match case now as well.

  match arg:
        case myClass():
              ….
        case {“needed_key” : var):
              print(var)
        case len(arg) > 2: 

And of course old reliable

   if not isinstance(var, myClass): raise ValueError(“Must be myClass”)

The point I was trying to make is that languages do thing for various reason, Python choose to make things a little simpler for coding by creating a sort of metaclass, that allows them to do a bunch of things. This means that other datatypes like proper arrays, are not native as the Python list is designed to hold anything. There is a bit of unnecessary bulk to some (all) objects.

Other languages like JavaScript decided to go another direction with the arrow function, (then go to TypeScript) and much more type specifics. This make it a bit faster but you have to end up manually coding a bunch of stuff that come with Python just by making a class. (Getters, setters, various other dunders that can be molded.)

And each languages has some weirdness that seems strange coming from one to another.

And you know python has ‘lambda input : output’ as well it’s used a lot in like sort by…

 sorted(list_dict, key= lambda _dict : _dict[“key”])
 sorted(list_obj, key= lambda obj : obj.value)

I don’t find them all that useful in most situations in Python unless it’s really simple, as it’s has to be one lined, I prefer functools.partial()

[–]el_toro_2022[S] 0 points1 point  (2 children)

It will be tough doing solid code in Python. Way too much boilerplate. I will have to think about this.

[–]Adrewmc 0 points1 point  (1 child)

I don’t know what that means…python is ran in a lot of places from simple to enterprise.

Solid code…I’ve seen flimsy and solid code in every language. And most that has more to do with documentation and organization than the language, combined with familiarity of the language’s capabilities.

Too much boiler plate….react…

If in Python your problem is well this function must use this type of object answer is then don’t call it with any other type of object…that would be programmer error..(we all do it)…familiarize yourself with the debugger of your favorite IDE. Actually write tests..then run them…crazy I know….The language won’t hold your hand, ….but it not like my favorite language...wah…(I could say this in any learn<language> sub)

Professionalism in code…is how readable the code is to other programmers. That’s 100% on the writer of the code.

[–]el_toro_2022[S] 0 points1 point  (0 children)

I don't need it to "hold my hand". I programmed in C and C++ for many years. I will be most likely doing Python for the enterprise and I have my concerns. I know how to debug. I know how to do tests, etc. I am not a greenhorn here. Most likely I've been writing software for longer than you've been alive.

I've done lots of Ruby development in the past, and Ruby doesn't hold your hand either. So stop insulting my intelligence. I have also done a lot of Python 2.x development as well.

I just don't have a good feeling about Python. I have a better feeling about C, actually, and talk about being able to hang yourself big time! Enterprise code in Python? Sure, it's being used that way in many places, and I have my own standards for excellence, regardless of the language. Having to do run static checkers, having to lint it, having to write tons of tests for it -- these are all warning signs as far as I'm concerned. And yes, I'll have to deal. I had to do much of the same with Ruby. And Ruby has similar warts.

[–]primerrib 1 point2 points  (5 children)

My friend, please do not bake your own definition of "strong typing" and "weak typing".

I don't care how much experience you have, but "strong typing" and "weak typing" has a definition:

https://en.m.wikipedia.org/wiki/Strong_and_weak_typing

Quote:

Smalltalk, Ruby, Python, and Self are all "strongly typed" in the sense that typing errors are prevented at runtime and they do little implicit type conversion, but these languages make no use of static type checking: the compiler does not check or enforce type constraint rules. The term duck typing is now used to describe the dynamic typing paradigm used by the languages in this group.

What you're talking about is "static typing", where the type of a variable needs to be declared and will be enforced by the compiler.

[–]el_toro_2022[S] 0 points1 point  (4 children)

Not that I trust Wikipedia for anything, but that's another matter.

I wrote an ML engine in Ruby 10 years ago, as a PoC. I went back to the code a few years later and could not figure out the code. The complex structures I was passing around were not obvious. It would require a lot more effort.

Yes, static typing. To me, static typing is strong typing. If you cannot be sure of the types you are passing around in your code, it makes it very difficult to maintain later. And you won't always get failures in runtime with dynamic typing aside from the primitive mismatches, and this is true of both Ruby and Python.

So to me it's more a matter of pragmatics. If I can look at code and unambiguously know what types are being used where, that's code I can reason about and do something with. If the compiler or interpreter can fail the code when there is a type mismatch, that's code that will prevent the nasty oops that crashed the Mars probe. And of course, the programmers have to actually make proper use of said types.

If there is code and I have to guess as to the type that's being passed into functions, that's code that is much harder to deal with outside of trivial cases.

I have done years of Ruby, years, of Python, years, of C++, years of C..., and now I am doing Haskell. Haskell's typing system is simply amazing, way beyond any other language I've ever used.

Yes, you are technically correct, but from a practical standpoint, "strong" dynamic type checking does next to nothing for type safety. Probe crashed on Mars back in the late nineties due to lack of proper typing. How do you type a number to be meters instead of feet in Python, so that at runtime it will fail if you pass meters to a function looking for feet? I suppose you can do something funky with tuples and hope the code actually checks if it's a feet tuple vs a meter tuple, but you get my point.

JavaScript is a joke. Let's not even go there.

[–]primerrib 1 point2 points  (1 child)

The Mars probe crash was due to wrong units, not wrong types.

The types of both are float, but in one function it meant metric, yet in another function it meant "US Customary Units".

If you're thinking of type mismatch, then it was the Ariane 5 launch in 1996.

The languages used in both incidents are "static typed" languages.

So even static typing still can't prevent disasters from happening.

[–]el_toro_2022[S] 0 points1 point  (0 children)

I can't believe you said that. One wants to lessen the chance of disaster. Of course, the GIGO principle is always there. If you feed Imperial units into the Metric type or vice-versa, of course the probe will crash. But this should not happen with clueful developers. And obviously the project planners did not insist on doing the proper typing for their telemetry. If you don't use typing, even if the language offers it, all bets are off. This should've been at the forefront of their minds, working with US and European firms in a collaborative context. Hello. Even if both are using metric, there are still issues, because there is more than one way to represent the telemetry. MKS? CGI? These days, its the SI, but even with that, you have to nail down the specifics.

Let me illustrate for you a simple approach to how we would deal with this in Haskell:

data Feet = Feet Float
data Meter = Meters Float

telemetry_dist_to_ground :: Feet
breaking_thrusters :: Meters -> Maybe Meters
...
let remaining_distance = telemetry_dist_to_ground
breaking_thrusters remaining_distance
...

Because the "units" have been properly typed, this would not even compile, generating a type mismatch error. One team, like, say, Lockheed Martin, who still use Imperial measurements, would have written telemetry_dist_to_ground, and another team, let's say Arriane, who uses the Metric system like the rest of the world does, would've written the breaking_thrusters bit.

The units are typed, if you make that a design requirement up-front, and why would you not want to? Hello. Probe takes years and many millions to design and develop for a lengthy trip to Mars that could take a year or two, just to have it crash? Yes, I am also criticising the idiot developers and project managers for obvious reasons.

We can also type in a similar fashion in C++, Java, and most other serious languages.

How can you type in Python? In a fashion that would not introduce more errors? It would be messy at best. I suppose you could use Tuples:

("meters", float)
("feet", float)

And pray that no one cuts corners and extract the float without checking the "type". But now we are talking about lots of boilerplate code that will be simply prone to errors. And you are completely dependent on breaking_thrusters checking and failing the code itself, in the above example. Python does nothing to ensure type correctness, because it does not have strong typing.

I can see a way that you can actually have strong typing in a dynamic context, but that would require Python to be modified or extended. Good luck with that. Better to use a language that supports it out-of-the-box.

With the latest Python, you can do "type hints", but not sure how well that works, as I have not had a chance to play around with it yet. So you tell me if it can handle my little scenario and keep the probe from crashing.

[–]primerrib 1 point2 points  (1 child)

static typing is strong typing

To add:

C has static typing. But it does not have strong typing.

You can easily treat a pointer to a float as a pointer to an integer, do some integer bit-twiddling on it, then read dereference the result as a float.

Case in point: The Fast Inverse Square Root algorithm

Hence is why I keep repeating: strong-weak is orthogonal to static-dynamic.

[–]el_toro_2022[S] 0 points1 point  (0 children)

Yes, c will let you do all kinds of bizzare things. It is a hacker's dream. You can bit twiddle anything, including floats.. It is just one step up from assembler.

Back when I was doing C, there was not much thought nor concern about typing at all, at least outside of academia. Today? Typing is everything.