News for hackers. Stuff that matters.
Re:On Learning Rust and Go: Migrating Away from Python by LawnboyMax on Sunday March 24, 2019 @07:34AM (#19475741)
Strongly agree with author. I really like Python and at one point thought that it makes sense to write almost any project in it, since it's so versatile and I know it pretty well.

After working on a quite large application and having to use lots of assert(isinstance(arg, type) at the beginning of almost every function, I began to think that a strong type system is very much needed for large projects. I believe this was one of the reasons why Twitter moved from Ruby to Scala.

I still love to use Python for hacking something quick for myself. But I also look at some popular strongly-typed languages now and hope to get better at one of them soon.

Re:On Learning Rust and Go: Migrating Away from Python by jsjohnst on Sunday March 24, 2019 @08:19AM (#19475905)
> I began to think that a strong type system

You’re confusing static/dynamic and strong/weak. Python is a strongly typed language, but also is dynamicly typed language.

Need proof? Try doing this:

a = 3

b = “3”

c = a + b

> having to use lots of assert(isinstance(arg, type))

Python has type hinting now, try using a current version of Python and this isn’t needed.

Re:On Learning Rust and Go: Migrating Away from Python by mjw1007 on Sunday March 24, 2019 @08:54AM (#19476062)
I think that example shows that Python's type system isn't the weakest out there, but it's still pretty weak.

For example, it doesn't have a built-in way to make a dictionary-whose-keys-must-be-integers (so with your example above if you wrote thedictionary.get(b) rather than thedictionary.get(a) you'd get an error rather than None).

I've often seen learners have trouble with this sort of thing (you read a number from a file, neglect to call int(), and get mysterious lookup failures).

Re:On Learning Rust and Go: Migrating Away from Python by UncleEntity on Sunday March 24, 2019 @09:23AM (#19476195)
> so with your example above if you wrote thedictionary.get(b) rather than thedictionary.get(a) you'd get an error rather than None

Technically, dict.get() returns None if the item isn't found and you don't provide a different value for its default.

thedictionary[b] would throw a KeyError on the other hand.

One could always subclass dict if they wanted to ensure the keys were always integers or whatever.

> I've often seen learners have trouble with this sort of thing (you read a number from a file, neglect to call int(), and get mysterious lookup failures).

Not sure if you're arguing for a stronger type system or having the language promote the string to an int as (I've heard) other scripting languages do.

Though, once you figure out the language doesn't automagically parse files for you you're well on the way to finding more fun and exciting ways to get python to throw error messages at you.

Re:On Learning Rust and Go: Migrating Away from Python by bill1124 on Sunday March 24, 2019 @08:34AM (#19475967)
strong type system != strongly typed.

Type hinting does not guarantee to catch everything, but for Python proponents 95% is apparently "good enough".

Re:On Learning Rust and Go: Migrating Away from Python by LawnboyMax on Sunday March 24, 2019 @10:14AM (#19476437)
I am using the current Python version and tried type hinting. I don't see how it can help much, since types are not enforced;especially when interfacing with not-so-well-tested modules that don't use type hinting and can sometimes return values of unexpected type.

It's definitely a neat feature when writing an application from scratch that interfaces with few other modules or only the well-tested ones.

Re:On Learning Rust and Go: Migrating Away from Python by flyinglizard on Sunday March 24, 2019 @08:26AM (#19475932)
The point is that your example will not break anything until run time, unless some static analysis tools are deployed (which are much more limited compared to what a compiler can achieve).
Re:On Learning Rust and Go: Migrating Away from Python by vonseel on Sunday March 24, 2019 @06:36PM (#19479169)
> having to use lots of assert(isinstance(arg, type) at the beginning of almost every function

Python should not be written like this; assertions can be ignored at runtime: https://docs.python.org/3/using/cmdline.html#cmdoption-o

A much better solution is to use qualified try/except blocks to handle potential errors.

Re:On Learning Rust and Go: Migrating Away from Python by joshvm on Sunday March 24, 2019 @09:04AM (#19476100)
> assert(isinstance(arg, type))

The most irritating thing I've found is trying to write a function that accepts either a path or the raw contents of a file.

Python 3 makes this easy, you can check against string. Python 2 of course treats everything as a byte string.

In the end I just check the length of the input if the interpret identifies as python 2. If it's a short byte string, I assume it's a file name. Otherwise the minimum expected file size is almost certainly larger than the maximum path length.

Re:On Learning Rust and Go: Migrating Away from Python by newen on Sunday March 24, 2019 @09:16AM (#19476158)
Why would you ever do that? Why would you even want a function that accepts either a file name or file contents when both are strings? What's so hard about defining a new function?
Re:On Learning Rust and Go: Migrating Away from Python by mjw1007 on Sunday March 24, 2019 @09:42AM (#19476283)
One common case where this is attractive is where you have a bunch of "public" functions built on top of each other, with the higher ones passing that parameter on and not otherwise caring what it is:

  high_level_function(src, ...)
      ...
      mid_level_function(src, ...)
      ...

  mid_level_function(src, ...)
      low_level_function(src, ...)
      ...

  low_level_function(src, ...)
      ...
If you can make the low-level function generic one way or another, you avoid having to duplicate the higher-level functions.

Another case is where there are two or more parameters that you want to be generic in this sense: if your only option is duplicating the function you can end up having to define inconveniently many variants.

Re:On Learning Rust and Go: Migrating Away from Python by newen on Sunday March 24, 2019 @10:45AM (#19476619)
Yeah, that is convenient and I do that often. But I try to wrap the variables in different types depending on their source (e.g. whether it's a filename or file content) so that functions further down can disambiguate between variables explicitly.
Re:On Learning Rust and Go: Migrating Away from Python by guidopallemans on Sunday March 24, 2019 @09:52AM (#19476327)
Re:On Learning Rust and Go: Migrating Away from Python by makapuf on Sunday March 24, 2019 @10:34AM (#19476555)
Why not have clearer file, filename or data keyword arguments ? Or just file and call open or stringio if you have the file name or data ? Plenty of more explicit solutions.
Re:On Learning Rust and Go: Migrating Away from Python by joshvm on Tuesday March 26, 2019 @01:10PM (#19493808)
Lots of public APIs support this behaviour, it's convenient for users. For example numpy.fromfile will accept a file object or a string.
Re:On Learning Rust and Go: Migrating Away from Python by ris on Sunday March 24, 2019 @08:07AM (#19475866)
You're confusing static typing with strong typing. Python is strongly-typed, but not statically typed.

Python's optional typing could also be used to get rid of a lot of your assertions.

Re:On Learning Rust and Go: Migrating Away from Python by yawaramin on Sunday March 24, 2019 @02:16PM (#19477809)
You are confusing optional typing with optional static typechecking. Python has the latter, not the former. In other words, everything is typed in Python and it will always check types at runtime.