4 ms·
I've been doing enterprise backend development (java/spring, scala, akka) for a while and occasionally miss the practice of sitting down and creating a fullstac
by tunesmith 11y ago
I've been doing enterprise backend development (java/spring, scala, akka) for a while and occasionally miss the practice of sitting down and creating a fullstack app myself, which I used to do with php and crappy html. But then I sit down and try to work with existing Ruby/Rails codebases and hit a mental block.
I guess example #1 is method_missing. I get it, it's a huge time-saver and lets you do all kinds of cool things like specify a default behavior for an API if someone sends a random command, or, define the behavior of a method dynamically by the name of the phantom method. But then the rest of me is reflexively saying, "Seriously??" And I get that Spring Data does sort of the same thing, but at least there it's limited by domain. If I'm in a Ruby codebase that is taking regular advantage of that, my first instinct would be find calls that eventually go to method_missing, and then just define the damn method somewhere so that my IDE's "Find Usage" will work again. How the heck do you explore a codebase quickly if your IDE doesn't work?
I guess for me it just reinforces the same rules of thumb. Dynamic languages are fine if you're prototyping or doing an MVP. But as soon as you find that your codebase is being read/maintained more often than it's being written (which will happen sooner than you think), or as soon as you start finding weird production runtime bugs that don't happen in your local environment, you're better off with something strong or static or compiled.
As for how to get that safety full-stack these days, I'm still poking around. Scalajs seems interesting, or Angular2 with Typescript, or something that uses RxJs...
- abc_lisper 11y agoHow about writing tests that enforce invariants? I have been doing clojure dev for a little bit, and here's what I do - - Run tests in the background continuously (lein expectations will give you that. or you can write your own shell script) - Do small checkins, frequently to git - Write tests that enforce invariants. Haven't gotten to test check yet - but I guess that would be even better. The trouble with types is they push you into a corner early, and after a while people will be coding to zombie constraints - the constraints that were there before, but not true anymore. They are also verbose, and need tooling to get you out of the corner. If the requirements change a little bit, it could be that, your old solution goes against the grain of the new problem, which is very hard to get rid of without rewriting the code. With dynamic languages, I find that I think more about the problem, than trying to do constraint satisfaction with other entities in the code, not to mention the language itself.
- tunesmith 11y agoI've honestly never felt like types have gotten in the way. I also write plenty of tests with plenty of mocking, it's just that the type system means we don't have to write tests for the things the type checker checks for. I'm having trouble thinking of a time when I felt something akin to what you describe with zombie constraints. If anything, having a good type system makes it easier to rip out code that isn't used anymore. And Generics can help with keeping your solution from getting too specific.
- bcbrown 11y agoI've run into a case where we model an ID as a number, then added a partner that uses alphanumeric IDs. But I'm still pro-types, and think they solve way more problems than they cause.
- abc_lisper 11y agoThe only dynamic language I used in production code is Clojure, hence my perspective is probably skewed by it. > I'm having trouble thinking of a time when I felt something akin to what you describe with zombie constraints Think of deprecated methods in a class, unneeded methods in an interface that are stubbed etc. > I also write plenty of tests with plenty of mocking This is good. But what happens to mock objects when the underlying class changes its implementation - It needs a large number of changes in tests. If you are writing micro-services, the guarantees that typed system gives you are more trouble than they are worth. If your average microservice is less than 10k lines of code, it probably reduces to 1000 lines of code in Clojure, and for the codebase of that size, typed systems provide little value for the cost(atleast for me).
- smrtinsert 11y agoThe funny thing is with tooling you get the power of being able to instantly refactor your way out of a "zombie constraint" and seeing if you like it. There is no textual or design pattern alternative to that - ides simply get you there faster and safer.