5 ms·
Metaprogramming does not require dynamic types, but this post seems to equate them. As far as I can see all this could be done in e.g. Java (and probably is).
by ImprobableTruth 4y ago
Metaprogramming does not require dynamic types, but this post seems to equate them. As far as I can see all this could be done in e.g. Java (and probably is).
IME this kind of "magic" very quickly loses its appeal when you have to debug it. The author's idea of libraries wrapping this stuff up so users don't have to care about it just doesn't pan out at all in my experience.
- ajuc 4y agoLISPs are the quintessential metaprogramming languages, and they learnt the lesson of "use macros sparingly and only as the last resort" very early on.
- taeric 4y agoI mean, you aren't wrong. But most of what they learned was "step debugging is hard in the presence of macros." And step debugging has largely been tossed out of the window in many modern setups. Just look at Java's "stream" apis. I swear they did what they could to replicate the LOOP macro.
- vkou 4y agoI am very rarely concerned about debugging my usage of Java streams, and step debugging works fine in the context surrounding them.
- taeric 4y agoThat is also the case for macros in lisp, at large. Similarly, any heavy use of lambdas in java will make step debugging confusing. As will any annotations you may use. Which is largely why many people grow to hate annotations. Which is all a fancy way of saying we learn the same lessons again and again. Used smartly, all of these are great tools. Defining what is "smartly" is a place of dragons.
- ajuc 4y agoMy main problem with metaprogramming in Java is that it breaks automatic IDE refactors and static code analysis. At least the metaprogramming we did with java back in the day (using reflections). If you use common java libraries made with metaprogramming - IDEs usually have plugins to work with that.
- posix86 4y agoYeah thought so too... in particular the example where you pass a a generator to a db, the generator isn't actually executed, and instead the expression is parsed & transformed to SQL. This is cool if it works. Good luck when it doesn't due to user error, and more luck if it doesn't due to a bug. You need to develop a whole strategy to tell the user what went wrong and how, and why, basically from scratch; admitting that you didn't, in fact, execute the generator, and that they have to change it. because of that. It's pretty awesome that it's possible. And it would be pretty amazing to write something like that. But... idk if it's a good idea from a developer stand point. I like being able to understand what's happening in a library with a single click.
- sitharus 4y agoAnd C# can do that with static typing via LINQ, which is really nice honestly. It’s a bit different but it would be something like: var result = await (from c in Customer where c.orders.sum(o => o.price) > 1000 select c).ToListAsync();
- jchw 4y agoI also strongly dislike the idea that static type systems are only being added to Python because spoilsports from other languages are forced to use Python and don't want to. Not true. That's especially strange considering Python is one of the only traditionally dynamic languages that has mostly led it's own static typing system, joined mainly by just PHP in that regard. Why does it not support features like kwargs? Dunno. TypeScript has no trouble supporting tons of JavaScript patterns you could never do in other languages, even C# from which it is heavily influenced due to its heritage, and TypeScript is a fully separate effort from JS. On the contrary, static typing in Python is still extremely nice to have. When I was at the peak of my Python career, I had a bug where I changed the return type of a function to be a tuple, and somehow unit tests missed one of the worst possible invocations, leading to an awful failure that occurred after a payment was processed but before actually completing the task, causing it to be retried repeatedly. To be clear, like any failure of this nature, it is one caused by many different problems, and we employed many different solutions; we started paying attention to test coverage, we began using MyPy (it was still quite new; this was also in Python 2 so it needed type erasure compilation among other things) and we made our payment processing logic more robust to prevent processing the same payment twice even in the case of everything else (like retry logic) failing to stop it again. But the thing that sucks is, fairly simple type inference without any additional type annotations could've detected that sort of bug without a potential for false positives. So I feel like it's silly the way that some dynamic language proponents feel like static typing systems on top of dynamic languages is all from outsiders. On the contrary, the relative weakness of MyPy is actually what ultimately made me quit using Python, and if I had to use it today, then yes, of course I would opt for the highest degree of type safety, as a primary concern above being "pythonic." I like pretty code, but I like correct code more. Sometimes this does prevent "better" solutions from working, but in my opinion nearly 100% of the time that this is the case, it's because: - The type system in question is not sufficiently advanced to express the types elegantly. OR - The approach is inherently not safe and probably not a good idea. Like patching the request object inside of middleware in Django, for example. I think TypeScript proves that with a sufficiently advanced type system, even arguably bad ideas can be type safe. For example, the ability to express dotted object paths safely in modern TypeScript is pretty impressive, and lets you map out older JS that does this accurately, but in general that seems like an unnecessary trick that will just make your code slower at runtime for the slightest terseness improvement over alternatives, lacking a language with sufficiently advanced metaprogramming. The thing is though, eventually this thought process comes true. If a given programming language community winds up bleeding members who are moving on due to the lack of better static type checking systems, then the people left will invariably be much more likely to be against static type systems.
- RobotToaster 4y agoIsn't the C preprocessor a type of metaprogramming?
- deleted 4y ago[deleted]
- Jtsummers 4y agoYes since metaprogramming is just programming that generates, modifies, or extends other programs.
- agumonkey 4y agoit's probably discard as being string-based, you could do the same with sed
- Ferret7446 4y agoStrictly speaking, yes. Generally speaking, not really. Metaprogramming implies first class support (i.e., using the language to generate itself)
- nine_k 4y ago> just doesn't pan out at all in my experience. Fine! These things are based on metaprogramming; chances are you've used some of them. * In nearly any language, nearly any ORM, for describing tables / models. * In Rust, serde, and nearly everything you #[derive]. * In Java, Lombok, Hibernate, and most dependency-injection tools. * In Java, most mocking / stubbing libraries. * In Python, tons of stuff, from standard library (dataclasses, namedtuples) to various parts of Django, etc. Judging by the sustained and widespread use of these things, they are not exactly complete failures.