7 ms·
With dynamically typed languages I feel it's better to wait until you've tried to maintain the code for a while before you consider the languages effectiveness.
by mabster 1y ago
With dynamically typed languages I feel it's better to wait until you've tried to maintain the code for a while before you consider the languages effectiveness.
I had to maintain a very large Lua codebase that has been active for several years. One big problem with Lua was how it will happily take more or less parameters to functions and continue to execute compared to something like Python where it is an error to pass the wrong parameters. This meant when we update a function signature we would often incorrectly update call sites, etc.
I can't remember the specifics but we had a few issues with tables being both dictionaries and lists. IIRC, if you delete a list index and there are later list indices, they will turn into dictionary keys. We had a few bugs to do with not traversing the entire array portion of a Lua table because of this.
I also implemented a few classic algorithms, e.g. bisect in Lua and you have to be very careful with 1-based indices. You also have to be very careful when interfacing between C and Lua. I prefer 0-based indices and [start, stop) style ranges for everything nowadays.
I much prefer statically typed code during maintenance. But dynamically typed languages like Python or Typescript where you can bolt on types, later if you wish, are not too bad.
Also using named parameters as much as possible is great for maintenance.
- nine_k 1y ago> dynamically typed languages like Python or Typescript You likely mean JavaScript. Typescript is very much statically typed, unless you allow everything to be `any` and `unknown`. Typescript is mentioned in TFA as a desired (but not available) option, because of the great static typechecking support.
- LoganDark 1y agoTypeScript is sort of "dynamically typed but statically verified".
- nine_k 1y agoMuch like C++ then — the machine code to which it translates lacks types! A TS compiler will reject an ill-typed program. You of course can just strip the type syntax and get a valid (though buggy) JavaScript code.
- LoganDark 1y ago> Much like C++ then — the machine code to which it translates lacks types! Ehh, not exactly. Most C++ compilers won't output machine code for inputs they don't understand. Though of course, you could simply translate some C++ code yourself into machine code and then say C++ is just like TypeScript in that way. "If you turn C++ into machine code, the machine code lacks types!" "If you turn TypeScript into JavaScript, the JavaScript lacks types!" The main difference is the C++ compiler won't generate machine code for you if the code you provided it doesn't compile, but the TypeScript compiler essentially treats types as a lint (unless extended by compiler plugins such as `typescript-is`, which I greatly enjoyed back in the day). Also, CHERI begs to differ. And even other than that, machine code isn't dynamically typed because it's not typed at all. Usually, everything is data (usually even the machine code itself, except on Harvard architectures), aside from any architecture-specific memory protections (and other protections), if applicable. I could probably go on about this for days. > A TS compiler will reject an ill-typed program. You of course can just strip the type syntax and get a valid (though buggy) JavaScript code. Can't Deno execute TypeScript directly? Last I checked, it didn't do typechecking itself because [the size and complexity of tsc]. For what that's worth, cling also exists, so try tricking that into executing compiler errors. I don't think it would.
- mabster 1y agoI would argue that machine code is typed, but this will be up to interpretation. I.e. you can add two 32 but floating point numbers or two 16 bit integers or store an 8 bit value. It's just doesn't require you to purposefully type pun in some circumstances (e.g. where floating point and integer registers are shared).
- jerf 1y agoA "typed" machine code would imply that you can say "Add these two 32-bit floating points" and the CPU will say "No, I can't, those are 4 8-bit unsigned integers". I don't believe the CPU will ever say that, so it is not typed by any sensible measure. Best you can do is that there may be some registers that can only be used by floating point units and others that can only be used by ints, but even that is really just hardware limitations for performance and not any sort of type assertion; the CPU will happily bit-slam them back and forth without anything like an "exception".
- mabster 1y agoI guess I mean both. In that you can take something dynamically typed and add type definitions to make it more typed over time. JavaScript would not be what I'm talking about without the existence of Typescript.
- arp242 1y ago> With dynamically typed languages I feel it's better to wait until you've tried to maintain the code for a while before you consider the languages effectiveness. True for any language really. There's an entire category of blog posts: "I used language X for 2 weeks and here's my hot take". Okay, great. But what do you really know? For every language I've used for a serious amount of time I've changed opinion over time. Some things that seemed like neat ideas at the start turned out to be not so neat ideas down the line. Or things I considered pointless or even stupid at the start turned out to be very useful once I better understood the nuances and/or got used to working with it. And of course it's double hard to judge will come back to haunt you a year down the line. Even as an experienced programmer I find it hard to properly judge any of that from just a few weeks.
- mabster 1y agoTo extend on this: There was always this implied impression that the original developers were hot because they got stuff up and running really quickly and that all the newer developers were lukewarm because they weren't getting stuff happening quickly at all, all as a result of the original language choice!
- szundi 1y agoThis is what makes Java underrated these years. Some annoying stuff pays off over a decade several times. You can make insane complexity with ease.
- ecshafer 1y agoJava is a great language, and the JVM a great platform. I think that the thing which makes Java underrated isn't the language, but rather Java Developers. There are tons of great Java developers, but they are probably great developers in any language. But Java being the language of choice at so many enterprises results in a large number of very low skilled and inadequate Java programmers, who would be bad developers in any language, but specialize in Java.
- kmbfjr 1y ago
- kristopolous 1y agoyou might like this one: https://github.com/ast-grep/ast-grep https://github.com/ast-grep/ast-grep ... it sounds like you'd get some mileage out of it.
- kgeist 1y ago>This meant when we update a function signature we would often incorrectly update call sites, etc. The same thing happened with our huge legacy PHP monolith, which was written before type hints were a thing. Developers were reluctant to refactor large chunks of code when the time came, because it was just too easy to introduce bugs - you couldn’t be confident about anything without manually digging through tons of code. So, when business requirements changed, they’d just bolt on some hacks to avoid touching the existing, tested code, and call it a day. It became a self-reinforcing loop: fear of refactoring → more hacks to avoid refactoring → more brittle code → even more fear of refactoring. Eventually, they added type hints and a linter to analyze them, but by that point you start to wonder - why are we even using a dynamic language and fighting its quirks?
- z3t4 1y agoIt can be solved with static analysis and type inference. Inference can be tricky though, as you have to backtrack and figure out what type of values functions return etc, so type hints/annotations make the job easier for the IDE/tooling developer, but they are not necessary!
- shermantanktop 1y agoThis is something I watch out for: teams which fear their own code and operate defensively, typically with cargo-cult practices that accumulate even though they themselves aren’t well understood.
- mabster 1y agoWhen I started, the culture was already engineered to prevent this reluctance. You would hear "the code is fragile, it's going to break. Noone will shout at you for that." This was great. But I would prefer to just not have to "run in eggshells" haha!
- drysine 1y ago>when interfacing between C and Lua Except for the indexing mismatch, I've found calling Lua from C and vise-verse very easy.
- TinkersW 1y agoYeah I had a pretty high opinion of Lua when I first used it, then I came back to code I'd written years earlier, and the lack of types just made it a nightmare. It really could use a fully statically typed layer that compiles down to Lua, and also fixes some of the stupid stuff such as 1 based indexing and lack of increment ops etc.
- discreteevent 1y ago> It really could use a fully statically typed layer that compiles down to Lua. That's Teal: https://github.com/teal-language/tl https://github.com/teal-language/tl
- teamonkey 1y agoThey mention Luau near the end, and my opinion is that Luau is a significant improvement. Mainly because of the optional typing, but the other features too are each small but impactful quality of life improvements.
- aomix 1y agoI saw someone describe python as “stressful” for this reason and I couldn’t agree more. It’s difficult to have confidence in any change I make or review. I need to sit down and manually exercise codepaths because I don’t get the guarantees I crave from the language or tooling. While with the small amount of Rust code I’ve written lately I could yolo changes into production with no stress.
- pnathan 1y agoAgreed. I had to work in a larger Python codebase after spending a few years with Go and Rust and the drop in logical confidence around the language was remarkable. I have, roughly, sworn off dynamic languages at this point. Although I have dreams of implementing a firm typed system over Common Lisp.
- -__---____-ZXyw 1y agoFirm like: https://coalton-lang.github.io/20211010-introducing-coalton/ ?
- pnathan 1y agoI need to spend some quality time with Coalton. I don't think it's _quite_ what I want, but its in the same key.
- shermantanktop 1y agoSame, though my trauma was Ruby. Those Rubyists who were apparently born with the language spec in their heads can do amazing things, but I am a mere mortal who needs to be told I wrote bad code right when I wrote it, not told at 2am on a production server.
- stinkbutt 1y agodo you not test your code?
- packetlost 1y agoOne of my coworkers described Python (specifically in reference to a niche framework, but I think it applies generally) as "a bucket of play-doh filled with broken glass"
- greenavocado 1y agoDoes said coworker use mypy?
- packetlost 1y agoYes. Mypy helps but isn't nearly enough, especially for a gradually typed codebase.
- jhatemyjob 1y agoI understand your frustrations since you are forced to work within a codebase that is shared with other developers with varying levels of experience. Lua was from the get-go never supposed to be a standalone language, it is more of a complimentary language and if you fail to respect that then it becomes unwieldy, quick. It is extremely easy to shoot yourself in the foot with the language and once bad design decisions creep in it is hurts a LOT. However once you get enough experience with the language you manage stay within the "happy path" (which is EXTREMELY difficult when you are on a team with salaried software engineers with different and often misaligned incentives) it is actually one of the best languages available. One of the things I suspect your team is doing wrong is you are using the PUC Lua C API instead of the LuaJIT FFI. That is one of those things which just completely destroys the "happy path". The PUC Lua C api is effectively a deprecated feature at this point. A few years ago you could have made the argument that the PUC Lua C API is more portable than LuaJIT which is absolutely true. But q66's (from Chimera Linux fame) cffi-lua project nullifies that argument since you can now use the luajit-style FFI in PUC Lua, which works on every platform that libffi supports. Again I understand your frustrations with the language since you are working within a fundamentally adversarial environment. Perverse incentives can easily destroy any good patterns you can establish since the language is so flexible. I implore you to explore the language outside of your day job.
- mabster 1y agoWe were using Luajit with our own extensions with our own binding mechanisms that included automatic translation of indices. And we had A LOT of bindings. There was some "fun" there. Luajit C functions uses space indentation that becomes tabs every 8 spaces, i.e. mixed tabs and spaces. And his custom assembler for the assembly portions. I personally spent a lot of time "refactoring code to generate less garbage" as we had purposeful garbage collection in our idle time. One of the advantages with Lua was that everyone could code in it. I.e. for our games all the artists, sound engineers and producers were developing Lua which was super productive. But the function signature one in particular - that would have saved me a lot of stress on release nights!
- jhatemyjob 1y ago
- TJSomething 1y agoI think that much of game development is unlike a lot of other kinds of programming, where there's often more ad hoc game mechanic prototyping than maintenance. This is where dynamic programming excels. But of course, that consideration needs to be balanced against others.
- mabster 1y agoMy big Lua codebase was a gamedev codebase, haha!