Python's proposal for type hinting will dampen the effect of type inconsistency I feel.
Python's proposal for type hinting will dampen the effect of type inconsistency I feel.
If you're looking for a statically typed Python that can be grokked in a matter of minutes, and compiles down to a static binary like Go does, and runs as fast as C in benchmarks, you should definitely check out the Nim compiler [1].
Code example:
import rdstdin, strutils
let
time24 = readLineFromStdin("Enter a 24-hour time: ").split(':').map(parseInt)
hours24 = time24[0]
minutes24 = time24[1]
flights: array[8, tuple[since: int,
depart: string,
arrive: string]] = [(480, "8:00 a.m.", "10:16 a.m."),
(583, "9:43 a.m.", "11:52 a.m."),
(679, "11:19 a.m.", "1:31 p.m."),
(767, "12:47 p.m.", "3:00 p.m."),
(840, "2:00 p.m.", "4:08 p.m."),
(945, "3:45 p.m.", "5:55 p.m."),
(1140, "7:00 p.m.", "9:20 p.m."),
(1305, "9:45 p.m.", "11:58 p.m.")]
proc minutesSinceMidnight(hours: int = hours24, minutes: int = minutes24): int =
hours * 60 + minutes
proc cmpFlights(m = minutesSinceMidnight()): seq[int] =
result = newSeq[int](flights.len)
for i in 0 .. <flights.len:
result[i] = abs(m - flights[i].since)
proc getClosest(): int =
for k,v in cmpFlights():
if v == cmpFlights().min: return k
echo "Closest departure time is ", flights[getClosest()].depart,
", arriving at ", flights[getClosest()].arrive
Statistics (on an x86_64 Intel Core2Quad Q9300): Lang Time [ms] Memory [KB] Compile Time [ms] Compressed Code [B]
Nim 1400 1460 893 486
C++ 1478 2717 774 728
D 1518 2388 1614 669
Rust 1623 2632 6735 934
Java 1874 24428 812 778
OCaml 2384 4496 125 782
Go 3116 1664 596 618
Haskell 3329 5268 3002 1091
LuaJit 3857 2368 - 519
Lisp 8219 15876 1043 1007
Racket 8503 130284 24793 741
This language deserves your attention.If something is compiled to native code, what's the point of writing a library that's not just a binding? In python it makes sense, because you get the pure-python installation of your app - it doesn't depend on the OS, python versions, etc.
But once you're going to compile your app for a target platform... what's the point of not relying on C libraries?
While there are a lot of concurrency options to not get you in trouble with the GIL, it is annoying that there is no canonical way or pythonic way of doing it. I saw people using things like monkey patching, which made my jaw drop. I had to implement Websockets recently and was totally confused as to the right way of doing it. I ended up evaluating NodeJS and Go for this function, and went with Go.
Overall ... I love Python. It is perfect for small projects. For larger codebases (3KLOC+), I am slightly skeptical. It can be done but developers need to have quality code and strong test coverage.
Our codebase at work is.. phew, I don't even know, a couple hundred thousand lines of Python? Still, easy peasy to dig into.
I will 100% agree on the websockets thing. Python is really failing in that area.
The project that I help maintain is a collection of Django apps totalling more than 700k lines. Thankfully I do not maintain all of it, but I am the primary maintainer for several sub-apps, totalling about 180k lines of Python. (This doesn't count the UI code, which is not in Python.)
I'm the sole author for about 12% of the part I maintain (since I wrote some of the individual sub-apps), and am familiar enough to describe probably half of the rest. There are still some parts that I really have to puzzle out ("What happens on the codepath to generate those reports?"), but that part shrinks over time.
The modular design that our original engineers used when they first built this system really helps, and the fantastic tooling in PyCharm is critical to my being able to navigate the codebase. Between grepping the python sources (thank god for shell aliases wrapping grep!) and my base familiarity with the system, I can start tracing with PyCharm's "find definition" to investigate things. Being able to run my own copy of the system, and put debugging breakpoints in (even in libraries!) is __amazing__.
Gets even easier when you use a code linter.
You had to implement Websockets in Python? Instead of using an already-functioning, tested library?
class WebSocketHandler(tornado.websocket.WebSocketHandler):
def on_message(self, message):
self.write_message("Echo: %s" % message)
I think the problem is that you chose a pretty heavyweight / complicated library.Weak typing has its merits but sometimes static typing is very useful for reading and understanding code.
I know we can get picky about the exact characteristics of a languages type-system, but for me they fall into two camps: "Typeful" languages and "(effectively) Typeless" languages.
The former have a "good" typesystem, and expose it as a tool the programmer can use to help themselves solve problems. In the latter case, there may or may not be a type system lurking in the language somewhere, but the language either doesn't expose that system as a tool for the programmer to use, or it does so inconsistently.
Personally I think python is in the later camp, it has types but it doesn't really give the programmer much help when solving problems.
Clojure is another example. The Java type-system is down there somewhere in the murk, but idiomatic Clojure code doesn't use it, and it's not really a tool for the programmer to use, more an accident of the platform.
> type hinting will dampen the effect of type inconsistency I feel
I'm not sure that I see type hinting being that advantageous. I kinda hope that it could allow PyPy and other VMs to make assumptions that would otherwise require heuristics.
Perhaps type hinting could make static checkers/linters for Python more effective, though.
This is why I like dynamic languages that have immutable-by-default data structures, like Clojure.
In python I would suggest wrapping your call in a try / expect block or using "isinstance()".
If you are using a publicly available library or popular piece of code that can return None or an Integer, I would argue that piece of code was written incorrectly. Newbie python users might do this, but I think experienced python devs would see the problem.
Finally, some documentation or justification for the reasoning behind this decision at the top of the function or on a web page somewhere would help as well.
As with most powerful , full featured languages it is pretty easy to shoot yourself in the foot if you are not careful, I don't think this is a python specific problem...
Better to check that the object you've been passed implements the interface you need rather than reasoning about its inheritance chain. Duck typing!
Minor pedantic correction: Python is dynamically typed, and strongly typed. Those are separate concepts.
Strongly-typed vs weakly-typed
Statically-typed vs dynamically-typedE.g. - as opposed to the Java practice of having 3 or more layers of fun to read (NOT!) XML on top of the language's native static typing to glue things together. I'm gonna be sick now...
https://msdn.microsoft.com/en-us/library/vstudio/ee461504%28...
It's not really dynamic typed, but has no requirements of making the types explicit, nor of making your functions work over a defined set of types.