Yeah I have long felt that if we think we need gradle, we should consider doing less crazy stuff in our build. Maven is plenty and any time I get back to a repo that has that instead of gradle or sbt I’m much happier.
HN user
blandflakes
Is your disinterest in LiveView because you'd prefer the more common SPA/API separation, or some other reason? I'm curious because as a mostly backend engineer I view LiveView as sort of a killer tool for the sorts of apps or tools I'm likely to build.
This is both a fair response and isn’t! The OP was talking about typical Java stuff you’ll encounter, which is overwhelmingly spring boot. But I also agree that you can do much better than that for resource usage if you’re willing to avoid the common defaults the community has embraced.
This was also true of Amazon's Leadership Principles. They are pretty reasonable guidelines, but in a debate, it really came down to which one you could most reasonably weaponize in favor of your argument, even to the detriment of several others.
Which maybe is also fine, I dunno :)
The trajectories of Go and Scala here tell a much different story (and one that matches my personal experience looking at job postings): https://innovationgraph.github.com/global-metrics/programmin...
Engineers also wrote good code before AI. We don't get to pretend that the speed increase of AI only increases the output of quality code - it also allows engineers to send much more crap!
Ha, I can relate WRT Python. I've been doing more Elixir these days for both a really pleasant web experience and because it has some unique primitives baked into the ecosystem that most JVM projects I work on spend a lot of time approximating through grotesque frameworks.
I pick tools by the problem, not loyalty.
Good advice that I keep trying to adopt myself, but I have to confess a large personal bias for languages that I like, even if it keeps me from certain classes of problem (I like Ruby, though).
What did you move onto for those next things you started building?
It is the best idea. This should be the standard. And nothing prevents you from rolling back an individual service. You can still do that. And you can still do individual deploys too. But these are just for patch ups.
There are a ton of reasons it's not the best idea. This flies in the face of a lot of _better_ ideas.
Keeping changesets small so that it's easier to debug when something goes wrong? Blown out of the water by deploying everything at once.
Bringing every service up at once is a great way to create the coldest version of your entire product.
Requiring a monodeployment turns canarying or A/B testing entire classes of changes into a blocking rollout where any other feature work has to move at the pace of the slowest change.
When you roll back an individual service your entire system is no longer in a valid state. It's in an interim state of repair.
The gold standard is that each version of your service can work with each other version of your service, because in The Real World your service will spend time in those states.
Monodeploy should be the gold standard, and individual deploys and roll backs are reserved for emergencies.
No, because if it's still possible to mix versions in your services, then a monodeploy doesn't actually solve any issues.
I actually am a big fan of fewer services and deploying bigger artifacts, but if you have multiple services, you have to act like you have multiple services.
Yeah, I think you're preaching to the choir about static checking, the only point I was making is that monorepo doesn't solve some classes of errors and that I've actually seen it generate false confidence in that realm.
Simple, although I only mentioned repos should be mono, I should've also said deployment should be mono as well. I thought that was a given.
Deploying your service graph as one atomic unit is not a given, and not necessarily even the best idea - you need to be able to roll back an individual service unless you have very small changes between versions, which means that even if they were rolled out atomically, you still run the risk of mixed versions sets.
Well, no, it doesn't. A monorepo does nothing to prevent you from making breaking changes, it just stops you from making changes that don't compile/test. You still have to understand that services aren't deploying as an atomic unit and make sure that your network calls are forward and backward compatible.
First put all your services in a monorepo have it all build as one under CI. That’s a static check across the entire system.
There are definitely benefits to this approach. My coworkers do fall into the trap of assuming that all the services will be deployed simultaneously, which is not something you can really guarantee (especially if you have to roll one of them back at some point), so the monorepo approach gives them confidence in some breaking changes that it shouldn't (like adding a new required field).
Go seems to have some enduring affection and popularity for new projects and companies. I recently felt like a lot of the recent shift was less about GC and more about runtime characteristics (static binaries, lean resource consumption, lack of an in-your-face virtual machine).
It never felt like Nim, Pony, or Crystal were ever that popular that a diminished hype cycle registered as something thematic to me (not that I really intend to disagree with your perspective here).
If you have to ask an object what its type is, you're probably about to cast it, and these are operations that the language doesn't enforce that you do together (and so the habit of casting can lead to the habit of casting without the check...). There are times when it's appropriate but generally if you have to ask what type an object is, your code is already starting to smell (because typically dispatching on type is handled by polymorphism, not be the programmer manually implementing it).
This isn't a personal website.
It's also pretty insulting to assume that everything is equally easy for all people.
Agreed; I don't actually even care about emulating this particular hardware, but these reports are just interesting reading.
I don't think we have to choose. Naturally finding the "right division of labor" is as infinite as finding the "right level of abstraction", but I think the ideal situation is to strive toward code that is easy to test without having to introduce a lot of mocks or without infinite layers of abstraction.
They also encourage/enable code that is less testable. If you use mockito to get your fake responses/assertions where you need them, you don't have to think about your class's dependencies to make your code testable and therefore better decomposed. I don't even do TDD, but I still find that thinking about how I'd test a class guides me toward better-factored code.
Static typing doesn't have much value if there are proper unit tests
Wasteful unit tests that assert your types are right don't have much value if there is a proper type system.
It's called ratting yourself out.
Quit being childish.
This always feels like a bad faith argument. Nobody says that with static types, you don't need any unit tests.
And your suggestion that people who like static types "don't know how to write unit tests" is further bad faith.
Perhaps it's dynamic typing programmers who don't know how to write sound programs? Except I'm not making that claim, because I'm giving you all some benefit of the doubt, a degree of respect you are not giving others.
Elsewhere in this thread, dynamic typing advocates malign the hassle of maintaining types, and it is always coupled with strong advocacy for an entire class of unit tests I don't have to write in statically typed languages.
I still haven't managed to get around to her scifi (but plan to!); but can wholeheartedly endorse The Raven Tower.
Yes; my only critique is that Elixir is already a niche. You could argue it two ways:
1. A niche within a niche is a bad idea 2. If you're going niche, going further niche hardly makes a difference
This is patronizing. I'm a professional and am constantly hiring and being hired. The JVM has far more jobs and engineers willing to do those jobs, _and_ in terms of your own employment, a better salary market, and this is not only self-evident, but reinforced by even a cursory investigation into the trends. In fact, your claim is so outrageous (that I'm wrong and that somehow Elixir has more to offer on either side of the hiring bar) that I think the onus is on you to somehow prove it.
I think they're pretty different, but there are some places where you can compare them:
1. Hiring and job market - the JVM is simply more employable
2. Ecosystem - in general you can expect the JVM to have library support for most things you're going to need.
3. Typing - if you like static types, you're probably going to miss that in Elixir/Erlang. They're working on a gradual type system for Elixir that looks quite pragmatic, so I'm excited to see how that works out.
The Elixir side of things has some real advantages, though. Runtimes like the JVM are slowly adding threading paradigms that start to look like how the beam works, if you squint enough. Naturally, Elixir already has that, and already has technologies that work very well with it. Virtual threads on the JVM are a smart effort that will take a long time to be complete and will always have to take backwards-compatibility into account, especially if you're in Java itself.
Phoenix is also IMO a best-in-class web framework. I don't think it's universally applicable, but if any JVM language had something like Phoenix I doubt I'd be considering Elixir nearly as strongly (due to my affection for types). So while the JVM ecosystem is broader, it's not uniformly stronger.
I also think that "domain" is much broader for JVM stuff. The web technologies there feel pretty baroque rather than empowering, but you can still do web on the JVM, and Kotlin or Scala in particular IMO serve better for systems where the bulk of the code is internal business logic. I think that even if I adopted Elixir entirely, I'd probably retain some "second language" for deeper systems.
I find that if most of my logic is relatively gluey, then the fields in my API boundaries are heavily optional, at which point types add a lot less than they do when most of my logic is more internal, and in cases where what I'm doing is just getting some JSON and doing something with it, I'd rather just have the dynamic shape of the JSON in a lot of cases than have to declare an entire schema/codec.
We have so much boilerplate and tooling to share request/response types between services and it's just... heavy. The same feeling arises when I'm sitting here trying to share a shape between a web app and the backend service, where FINALLY I just want the types to get out of my way instead of having to go through all this ceremony.
And my domain is relatively precise and typeable - streaming video with a deterministic set of parameters.
Generally though I'm more likely to agree with the value of types than to undersell them; I just can't find a ways to describe the above experiences such that they reflect that perspective.
I think it's not that I don't want types, it's that I want simple types that play slightly more dynamically - maps of <string, heterogeneous values>, for example, and reasonable means of interacting with them (like various "safe traversal" operators that some languages have added).
This has sort of been my issue with Elixir. I've been doing Scala for years but I think Phoenix is really the best web story at the moment for how I want to be building web apps. And while I believe that the benefits of static typing somewhat decrease in the web arena, it's still frustrating to have to manage type relationships in my head.
I'm hopeful that the incoming type system work makes me happier there, though I'd also prefer a nicer editor experience than is currently available.
I always find downvoting on stuff like this perplexing. It still isn't there. I know that a lot of Scala people are doing metals and some kind of text editor experience, but if you've used something as powerful as Intellij, the Scala 3 experience is a serious downgrade, and it still is today, even though it's better than it was a year ago.