- 0 Posts
- 68 Comments
For me, the more relevant adage here is “a bad abstraction is worse than no abstraction”.
IMO many abstractions in Java are terrible in this regard, either via commonly proliferated patterns or via language design issues. Abstractions large and small are all forcibly locked into place very early on in the name of formalism and safety, ultimately leaving us with poor versions of the former and weakened versions of the latter. Where is “encapsulation” when certain classes only work when hooked up in very particular ways to other distant classes? Where is “type safety” when certain methods simply raise “not implemented for this sub/super-type”?
These faults are often hand-waved as “all ecosystems have rough patches”, but my point is that Java’s bad abstractions in particular are supremely more stubborn and persistent in comparison with other ecosystems. I understand many consider this a strength aka stability, but IMO at the extreme being unable to shed the past means negatively hindering progress. I think modern Java versions show a budding shift in mentality, but I’ve already moved on – it’s just not for me.
It’s a container with certain behaviors and guarantees making them easy and reliable to manipulate and compose. A practical example is a generic List, that behaves like:
List[1, 2, 3]
, i.e. (“new”, “unit”, “wrap”) to create, containing obj(s)map(func)
to transform objs inside, List[A] -> List[B]first()
, i.e. (“unwrap”, “value”) to get back the objflat_map(func)
, i.e. (“bind”) to un-nest one level whenfunc(a)
itself produces another List, e.g.[3, 4].flat_map(get_divisors) == flatten_once([[1, 3], [1, 2, 4]]) == [1, 3, 1, 2, 4]
Consider the code to do these things using
for
loops – the “business logic”func()
would be embedded and interlaced with flow control.The same is true of Maybe, a monad to represent something or nothing, i.e. a “list” of at most one, i.e. a way to avoid “null”.
Consider how quickly things get messy when there are multiple functions and multiple edge cases like empty lists or "null"s to deal with. In those cases, monads like List and Maybe really help clean things up.
IMO the composability really can’t be understated. “Composing” ten
for
loops via interlacing andif
checks and nesting sounds like a nightmare, whereas a few LazyList and Maybe monads will be much cleaner.Also, the distinction monads make with what’s “inside” and what’s “outside” make it useful to represent and compartmentalize scope and lifetimes, which makes it useful for monads like IO and Async.
Kache@lemm.eeto Programming@programming.dev•Where can you view package details on PyPI?2·3 months agoPython deps can be dynamic, so it can be necessary to download the package and execute code just to find out.
Would be nice to see a resource that lists out the statically defined ones, though. Perhaps that’d pressure the dynamic ones to change – it’s a cause for some of the notorious pain of Python packaging.
IMO it will “succeed” in the early phase. Pre-seed startups will be able demo and get investors more easily, which I hear is already happening.
However, it’s not sustainable, and either somebody figures out a practical transition/rewrite strategy as they try to go to market, or the startup dies while trying to scale up.
We’ll see a lower success rate from these companies, in a bit of an I-told-you-so-moment, which reduces over-investment in the practice. Under a new equilibrium, vibe coding remains useful for super early demos, hackathons, and throwaway explorations, and people learn to do the transition/rewrite either earlier or not at all for core systems, depending on the resources founders have available at such an early stage.
Kache@lemm.eeto Programming@programming.dev•Do-nothing scripting: the key to gradual automation3·4 months agoHighly recommend having some scripting/interpreted language in your stack – in fact you likely already do (consider how shell scripting makes up a significant part of Dockerfiles)
It’s an incredibly useful intermediate between freeform-but-non-executable text/docs/wikis and “industrial-grade”-but-inflexible tooling
In other words, a great fit for capturing this partial/incomplete/tribal knowledge space the post is talking about. I personally even go a bit further and actively advocate for converting “onboarding/operational docs” from wikis into scripts that print out the equivalent text that can be committed and incrementally automated.
In my experience, LLMs aren’t really that good at summarizing
It’s more like they can “rewrite more concisely” which is a bit different
Also have the option of selectively/strictly enforcing in CI, to get an experience & protections similar to “compile-time type checking”
it lacks clear and enforced type restrictions which help with clear code contracts
Not anymore! Gradual typing is supported by the core language and pyright is a fantastic incremental type checker that you can use both in your editor and in CI.
You cannot, and that’s why that type declaration models a
NonEmpty
that a type checker can enforce
Kache@lemm.eeto Programming@programming.dev•Any data scientists out there? What's your go to programming language and tools for your work?1·7 months agoHm, that’s kind of interesting
But my first reaction is that optimizations only at the “Python processing level” are going to be pretty limited since it’s not going to have metadata/statistics, and it’d depend heavily on the source data layout, e.g. CSV vs parquet
Kache@lemm.eeto Programmer Humor@programming.dev•++++++++++[>+>+++>+++++++>++++++++++<<<<-]>>>>++++++++++++.-----------.+++++++++.-----.++++++++++.1·7 months agoWhat’s hard about vanilla Ruby?
Kache@lemm.eeto Programming@programming.dev•Any data scientists out there? What's your go to programming language and tools for your work?1·7 months agoWhat kind of query optimization can it for scanning data that’s already in memory?
No so much that YAGNI falls short, but more like “When YAGNI means ‘You Are Gonna Need It’”
Kache@lemm.eeto Programmer Humor@lemmy.ml•TIFU by not using objects in my object-oriented programming coursework11·7 months agoBad abstraction is worse than no abstraction
If the code is going to poorly organized, I’d prefer it to just be one single gigantic standalone script than some wrong and misleading arrangement of objects or functions that adds more complexity than they solve
Kache@lemm.eeto Programming@programming.dev•Recommend me a Python book for absolute beginners2·8 months agoabsolute beginner? Start at https://www.hedycode.com/
Which will ultimately lead into vanilla Python. This is the creator explaining why Hedy is uniquely designed for learning: https://www.youtube.com/watch?v=fmF7HpU_-9k
Kache@lemm.eeto Programmer Humor@programming.dev•TIFU by not using objects in my object-oriented programming coursework3·8 months agoinheritance to avoid code duplication
What no, inheritance is not for code sharing
Sound bite aside, inheritance is a higher level concept. That it “shares code” is one of several effects.
The simple, plain, decoupled way to share code is the humble function call, i.e. static method in certain langs.
Kache@lemm.eeto Programmer Humor@programming.dev•TIFU by not using objects in my object-oriented programming coursework23·8 months agoIf you used good objects, you’ll only have to make the change in one place
IMO that’s generally a retroactive statement because in practice have to be lucky for that to be true. An abstraction along one dimension – even a good one, will limit flexibility in some other dimension.
Occasionally, everything comes into alignment and an opportunity appears to reliably-ish predict the correct abstraction the future will need.
Most every other time, you’re better off avoiding the possibility of the really costly bad abstraction by resisting the urge to abstract preemptively.
But IMO that’s one reason weird UX/design is not uncommon and can persist in dev ecosystems. The intended users are more proficient than average and most are able to work around most issues.