57 karma · joined November 13, 2008
I will say I do think some opinions on how to structure URLs to return snippets might be valuable. Some of these frameworks leverage headers htmx sends to use just part of the page, but I think it is easier to just have individual URLs for many use cases. I've used Go and Templ in a similar fashion and one benefit with Templ is that the snippets are effectively functions, so returning the specific section and passing args is reasonably natural when breaking something out of a page.
Overall though, the goal is to avoid duplicating your data model and abstractions in the UI in favor of relying better networks, faster browsers, and HTML improvements to create interesting interfaces with simpler code.
Iterating on the manual work to better communicate and formalize the debugging process could fit well into the notebook paradigm. You can show the scripts and commands you're running to debug while still composing a quality post-mortem, as the incident is happening where things are fresh.
The other thing to consider is how often you get incidents and how quickly you need to get people up to speed. In a small org, devs can keep most things in their head and use docs, but when things get larger, you need to think about how you can offload systems and operational duties. If a team starts by iterating on operational tasks in Notebooks, you can hand those off to an operations team over time. A quality, small operations team can take on a lot work and free up dev time for optimizations or feature development. The key is that devs have a good workflow to hand off operational tasks that are often fuzzier than code.
The one gotcha with a hosted service IMO is that translating local scripts into hosted ones takes a lot of work. On my laptop, I'm on a VPN and can access things directly, where you need to figure out how to allow a 3rd party to connect to production backend systems. That can be a sticky problem that makes it hard to clarify the value.
The nice thing about this is that you can get a tailwind Go lib to programmatically build into your binary. There are no extra files, one build step, and one binary output. After trying out Fly and Vercel, I went to running things with docker on a VM, and a single binary in a container makes things much simpler IMO.
This looks pretty cool and I look forward to seeing folks do interesting things with it.
I've heard that a lot of vim folks get similar behavior via tmux and leverage other shell tools.
I'm not going to argue you should switch, because it is an investment. It is like owning a house, you have autonomy but you're also on the hook to fix the air conditioner. You also can't just drop it and move to the next editor. Your hands and workflows become tied to your editor. Keybindings may be similar, but it is not the full story. Either way, it is a journey getting good with your tools, so enjoy it!
I'll admit that I'm not a frontend guru so my bias for writing apps like I did 20 years ago likely shows here.
Still, when I consider all the different abstractions and details around using something like Next.js + Typescript, and where the division between server and client becomes mixed, reducing complexity feels advantageous.
Tailwind is another good example where the explicit nature of attaching styles makes sense if you are writing React components. You've encapsulated all that noise behind a simple JSX tag. Using Tailwind with something that returns HTML then requires a similar way to encapsulate the noise. Again, I found using Templ with Go made that feasible, but I still have avoided Tailwind just b/c I don't want to introduce the noise too soon if possible.
It all makes me wonder if we lost the idea of a fullstack engineer, not because the problems became so challenging that we needed the extra complexity, but rather because we organized our applications into frontend and backend organizationally when we should have been more diligent in maintaining teams that could do everything.
The real tl;dr is that Templ for Go is pretty handy for writing components :)
While I agree it may not work with everyone's workflow, maybe it could be a powerful change to folks workflow. I'm going to try it out and see for myself!
I know there are other similar tools out there, but I hope this one might be helpful or interesting to someone!
That said, I can see your point that you are hiding some details from the OS that might be helpful such as what hosts you can talk to.
Fortunately, just because you might configure a firewall with an API rather than some Ansible plays, it doesn't mean that you can't continue to use Ansible to fill in the gaps. For example, if you did use Ansible to previously configure your iptables, you might change the playbook to call the API based on some YAML. You might use the same YAML to write some information on the host that your application can use to understand the firewall rules that are used.
The point being is that it is always good to remember these are not either/or decisions.
Lastly, I'll also speak up for those folks that don't know much about firewalls and iptables. I understand the principles, but I'm far from feeling confident managing that system myself. In my case, I'm really glad to have an option that lets me get the benefits without forcing me to operate a system I'm not well equipped to do.
Many of the applications people think of for node.js end up being "glue", much like python, and can live within this constraint for a very long time, where the I/O optimization is a nice benefit.
As the above comment clearly points out, there are workarounds to make things work. Still, when I think about the amount of time and effort that goes into debugging systems when they hit limits like the author mentioned, I imagine most of the the benefits gained by using a language like Python or JavaScript go away.
You can use Control + [ as an alternative to using ESC in Vim. This solved my reluctance to reach for the ESC key in the far reaching corner of my keyboard.
This thread does remind me of nano. Maybe it is time to give it a try when editing files on servers.
While there is no easy answer, I've found that in these situations, I still try to write a test first. The difference being that I try to write a test that exercises the code at some API level that I don't want to break. These test start off really ugly and require a ton of work, but they ensure that refactoring the lower level code to make it more testable doesn't break things. Eventually, the tests and code at the higher level can be updated safely.
For example, in Python, if I have two functions that implement a "download" operation, but they accept different types of locations, I could use different modules to implement them:
from mypkg.endpoints import ftp
from mypkg.endpoints import http
ftp.download(ftp.info(some_ftp_info))
http.download(http.info(some_http_info))
You can see that we pass the result of `ftp.info` to each, which is essentially defining its type somewhat reliably.In OO, you can simplify things a great deal by encapsulating data in an object, as well as organizing functionality accordingly. I think (in Python at least) the same benefit can be accomplished by using modules for namespaces and grouping, like you would a class.
By using modules in this way, it is then possible to utilize types like you might in haskell as well as enforce immutability, assuming the "types" you create are immutable (like namedtuples).
All that said, I've yet to have the courage to enforce this sort of paradigm in a project. I worry that it would be prohibitively expensive to my fellow developers who may not appreciate the benefits. With that said, I would be interested if the paradigm would be reasonable over time.
I think functional languages have a more healthy appreciation for layering by nature of requiring functions to act on data rather than having mutable data types. I believe if we want to reduce complexity we HAVE to create more layered systems to scope the bounds of our complexity. The problem is many people see this as over-architecting things. With time, a design can evolve such that 10 or 20 layers, as compared to the 3 in MVC we often see, could be manageable with help from our languages and environments (IDE / text editor / etc.).
Also, banging out code is overrated. I've found that when I take time to think, my actual coding becomes closer to what you see in the movies. I can find my flow and quickly materialize my ideas, and most importantly, solve the problems that arise. When I try to just "code" it ends up being poorly designed and written.
The point here is that when you do have the desire to "just code" take a step back and consider taking pride in the code you publish. The tools and systems in place are there to make you a better code publisher. The goal is to write well written code that others (including yourself) can maintain. Rather than being frustrated you have to deal with the intricacies of rebasing or 3-way merges, take a moment to understand these skills will help you publish better code.
Gittip is a great concept and Chad has done an amazing job building community based on the ideals of the community. He has created something that has value. I'm glad Techcrunch doesn't get to leach off his innovation and creativity.
I don't think the decision to use Node.js should be based on the fact it uses Javascript. Currently, Javascript has a much more interesting ecosystem than it has at any other time. Just as Rails took many collective practices and managed to communicate them clearly to a huge group of developers, I think a similar trend is happening in Javascript. From this perspective, Node.js is appealing because it rides atop this Javascript revolution with tools like Coffeescript, Backbone, etc.
Outside of the language decision, I think people are choosing to use Node.js b/c of its programming model. There are many applications that are relatively easy to code for when you can assume a constant connection between two processes. Where Node.js seems to excel is in these service level, socket based servers that may or may not have a web component. Likewise, Node.js also aims to be very nix friendly in that it tries to use simple processes for scaling instead of relying on more complicated application / language specific tools. This adherence to nix patterns is also very advantageous to some people.
Finally, as people start finding use cases where async really is a good idea, Node.js ends up being a decent option. Having done some async programming in Python, it is very difficult because the async assumption needs to be made throughout in order to avoid blocking. My impression is that the experience in other languages is similar, where no library is truly able to make the async paradigm seamless. Node.js has been written from scratch to support this model and many developers understand it via their Javascript experience. It therefore can be a good option when compared to including something like Stackless, EventMachine, etc. in their applications.
I think the key point here is that Node.js has managed to hit something of a sweet spot in that it is async, uses a language that is having something of a renaissance and uses *nix to make its integration obvious.
Again, I don't use Node.js very heavily at all, but that is my impression as to why people would choose it over other technologies.
It is the really simple things like form parsing and cookies/sessions that may not be fully fleshed out in Node.js. Not that it won't be soon, but it is a nightmare to spend time on low level issues when you don't have to. This has always been the issue trying new languages and frameworks for projects. I get part of the way there and realize that some basic aspect of web development hasn't been done. Sometimes I start to handle the issues, but if the project is something I want to finish, it usually ends up with me turning back to Python. This might be a bad reflection on myself, but when you want to get something done that doesn't need the latest/greatest tech, it is nothing but frustrating to hit your head against a wall doing basics.
Just my two cents!
In terms of cost, a VPS usually will cost more as memory usage is something you'll have manage. For example, I would have liked to run MongoDB on my VPS but just didn't have anywhere close to enough memory. Not a big deal, but if you're using it for a business then it is important to understand what you're getting into in terms of memory usage and what services will need to run. You have to allocate resources for not only the web server, but any databases, scripts, etc.
On a more personal preference, my Emacs usage lead to use StumpWM and Conkeror (web browser) which help to keep all my keybindings very cohesive. A tiling window manager is really helpful b/c you never have to slightly move or resize windows. It sounds like Divvy does a similar thing.
That said, I bet if you take some time to commit to something like Vim (or Emacs!) it might eventually be more productive than TextMate. Emacs helps to keep everything within the editor (email, IRC, shells, etc.) while Vim helps to keep you in a terminal and to use standard *nix tools. Both tactics are very helpful IMO.
I'm not trying to belittle your previous work, while at the same time you should realize that your frustration with maintenance is somewhat belittling as well. It is simply a different kind of problem that takes a different set of skills and talents to do well. If you consider maintenance in this way, it can be just as rewarding and help further your learning. Likewise, if you are doing maintenance, you are working on software that had some level of success. No one will ever ask you to change a codebase no one uses. You can learn a ton from a codebase that has been around for a while. You see the parts that were bolted on and how that impacts the future, but also how the tradeoff of a more flexible design was actually not necessary.
I'm not trying to be negative, but rather challenge you to change your mindset. I maintain a huge amount of code and it is a huge pain in the neck at times. That said, I also realize that my ability to continually dive into new parts of the code has become easier through time. Even if I do have to read the 1000 lines of code, I'm finding that the process of reading code and making guesses where to read next has become more efficient. Likewise, I've tooled my environment to help me search for leads when solving problems with the code. My perspective on writing new code is radically different because there is a very clear understanding of how I could do a better job for the developer that looks at the code in the future.
In short it can be really frustrating to maintain code, but at the same time it is something that needs to be done. I also believe it can be something done very well. If you see it as a healthy challenge I think you'll find the feelings of burnout will subside and you can take pride in changing that one line that ended up helping save people massive amounts of time and money.
Tests are effectively the answer, but they are a pain to write and having to document your type information via tests seems a lot more cumbersome from just doing "int my_var".
The party line with Python and dynamic typing is true in many cases, especially when starting a new project. As time goes on though, things get confusing and tests are rarely good enough to offer the same contract static typing offers. To say "you're doing it wrong" is somewhat correct, but no one does it right all the time.
I hope that makes sense since simply stating "there are already those kinds of programs available" does mean that there isn't room for improvement. The evolution of lighttpd, nginx and cherokee all suggest that people found apache limiting in some way.
As for the service it did feel pretty darn fast, so kudos for that. More use cases or a more general caching proxy/load balancer might be something more people could consider worth paying for but that is just my own thought.
Good luck!