3 ms·
I don't think the type system particularly matters. You can make something work without assigning a type like "int" to variables. Python doesn't let you do th
by jrockway 4y ago
I don't think the type system particularly matters. You can make something work without assigning a type like "int" to variables. Python doesn't let you do things like "foo" + 3 (while Node is happy to), so even though you're not naming your types, the types are still static.
One unexpected downside of static languages are dealing with web services written in dynamic languages. As an example, I was writing a Slack app in Go a couple years ago. Some response gets unmarshalled into an easy-to-use struct, but contrary to the documentation, the server has no interest in returning data that can always be unmarshaled into that struct. Sometimes instead of a list of 1 element, the value will just be that one element. There is no type "[]Foo|Foo" in Go, so now you have to write a custom unmarshaling function (or say "fuck it all!" and use map[string]any, at which point you're just writing Javascript). This doesn't cause problems for people using Python or Javascript because neither of those care what's in a dictionary, but statically typed languages do, and you'll have to write extra code to work around that.
I agree that it's annoying to require the users and tool author to have the same runtime and packages installed, though. Python is an incomprehensibly large can of worms here. A python package's dependencies are architecture/platform dependent. To install C packages, you need the exact same C compiler that was used to build Python. Some popular packages have an indirect dependency on a Fortran compiler. It's a pretty big nightmare. You could bundle the runtime with the application like Go does, but the runtime is pretty big and the language is too dynamic to remove the parts you aren't actually going to use in advance, so it's not as easy as a sell.
An option there is that if you're using Python for internal tooling, you bless a particular version once a year, install it on every workstation, and say "sorry, you can't use a different version of Python". That will alleviate a lot of the author's problems, but obviously it's exceedingly politically unpopular.
Anyway, there probably isn't an objective truth here, just personal and organizational preferences here. I agree with the author in that whenever I write some tooling in Python, I regret it almost immediately. But it's working for people.
- klodolph 4y ago> To install C packages, you need the exact same C compiler that was used to build Python. Is this true? I have never encountered this problem. My experience is that, since CPython is written in C, you only need to have any C compiler for your platform, because the C compilers will be ABI-compatible. I am not sure about Windows, because Windows has some funny issues with C runtime compatibility. But I have upgraded my Python installation and C compiler separately before without issue.
- cassianoleal 4y ago> even though you're not naming your types, the types are still static. Python is strongly typed, but definitely not statically. >>> a = "foo" >>> type(a) <class 'str'> >>> a = 3 >>> type(a) <class 'int'> The variable `a` has different types at different parts of the program. That's not static.
- schmuelio 4y agoYour example doesn't show static typing (declaration/re-declaration is the same syntax as assignment in Python), but I think OP was thinking of Strong/Weak? Python is Dynamically typed because: >>> a = "foo" >>> a / 3 Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: unsupported operand type(s) for /: 'str' and 'int' This isn't a compile error. Edit: Also for the re-declaration thing, you can see this using id(). Python seems do do some fancy value stuff behind the scenes but you can see the variable changing its identifier in the following example: >>> a = "foo" >>> id(a) 140105790230896 >>> a = "foo" >>> id(a) 140105790230896 >>> a = "bar" >>> id(a) 140105790230512 >>> a = 1 >>> id(a) 140105793782000 >>> a = "foo" >>> id(a) 140105790230512 As for strong/weak, I think it's a bit more fluid because I can't seem to find a set definition that everyone agrees on. Some people consider weak typing to be when the language implicitly casts or converts types for you, which Python does not do: >>> a = "1" >>> a / 3 Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: unsupported operand type(s) for /: 'str' and 'int' >>> type(a) <class 'str'> Except sometimes it kind of does? The divide operator converts int into float "implicitly" even when both inputs are int. So type conversion is happening behind the scenes (I don't know if you would class this as "implicit" type conversion, maybe it depends on where it happens?): >>> a = 10 >>> type(a) <class 'int'> >>> b = 1 >>> type(b) <class 'int'> >>> type(a/b) <class 'float'>
- cassianoleal 4y agoThanks for the correction and the comprehensive examples!
- 4y ago
- funklute 4y ago> You could bundle the runtime with the application like Go does, but the runtime is pretty big and the language is too dynamic to remove the parts you aren't actually going to use in advance, so it's not as easy as a sell. It's not so big as to be prohibitive though, especially in a dev environment... if this became the norm, I would be a lot happier with using python-based tooling than I am today.
- falcolas 4y agoContainers work particularly well for python environments. You can get them working locally, but it's easiest when the developers stick with the standard library. Needless to say, virtually nobody does.
- PurpleRamen 4y agoBut are containers portable? Can you take them, send them per mail or put on a USB-stick? And I'm not talking about the recipe for creating them, but the actual container itself.
- falcolas 4y agoYes. The actual image is a tar file, and container runtimes include commands for both exporting and importing. Exceptionally portable. More portable than JAR files and Go binaries, at least.
- PurpleRamen 4y agoWait, which container are we talking about? Docker? AppImage? Kubernetes? What about the runtime?
- jrockway 4y agoOCI Images. You can run them in Docker, Podman, Kubernetes, systemd-nspawn, etc. Nobody is going to use your tool if they have to fetch it from a container registry and have to run it isolated from their filesystem and network, though. OCI images are fine if you have a pet app and you have to ship it to a production server. Not that convenient for interactive tools, though. Consider: $ docker run -v /tmp/foobar:/tmp/foobar debian:stable ls /tmp/foobar a.txt You really just want to type "ls /tmp/foobar".
- falcolas 4y agoThat's something that aliases excel at.
- kaba0 4y ago> the types are still static. Python is a dynamically, but strongly typed language. JS is dynamic, but weakly typed. Java would be an example of a statically and strongly typed language, and C may be a statically and weakly typed language, but I’m not sure this latter is an apt description (you can cast anything in C and it may work, while this will fail in Java if the types are not compatible)
- bborud 4y agoHow big would an application have to be in order to be too big? In fact, if I were to guess how large the binaries of the top 5 custom tools I use from the command line are I probably wouldn't be able to tell you. Is 5Mb big? 10Mb? 100? I was mostly talking about the tooling you find in environments like Zephyr and ESP-IDF. I'd happily accept 500Mb binaries if it meant I never have to spend any time making the tooling work ever again.