6 ms·
The most important statement in this article is near the beginning, and it's still relevant today: "I've done small woodworking projects before, and I think I
by dools 15y ago
The most important statement in this article is near the beginning, and it's still relevant today:
"I've done small woodworking projects before, and I think I have a pretty good idea of what I need: some wood and a few basic tools: a tape measure, a saw, a level, and a hammer."
The reason I hate frameworks (even things like Django which is very easy to get started with) is that, at some point, I'm asked to re-learn a different way of solving a problem that I've already solved in the past.
I've been doing lots of thinking about this having written the Great American PHP Framework myself, and worked with other people's frameworks, and also worked a lot in the CMS space and the biggest conclusion that I've come to is that the best tools are those that enable you to do things faster or more conveniently but don't actually provide any abstraction.
For example, when deploying a website there are any number of tools to "abstract away" the HTML layer - templating engines, markups, markdowns etc. etc. but the best way to build HTML is using HTML and testing in a web browser, always.
When you need to write some code in whatever web framework you're using to handle a POST request, you want to be as close as possible to the HTTP layer without a bunch of arcane systems in between you and what you and the underlying technology.
Sure it's handy to have tools which automate some repetitive aspects, but if you understand the underlying principles and you know the syntax of the language you're working with, you should at all times be able to just "get it done" however you know how without reading endless documentation and shoehorning your knowledge through a bunch of layers of abstraction.
The same goes for ORM - I want convenience of access to my data, and some automation to handle some of the more boring aspects of writing SQL, but I need to be able to mix and match (yes I know most ORMs allow you to use raw SQL, but it's always one or the other - the ORM or the SQL - I've never used a tool that has a simple method for me to extend the ORM bits halfway through the query building process with some custom SQL).
This is my zeitgeist now and it pervades all the projects I'm working on.
[1] http://www.decalcms.com/ http://www.decalcms.com/
- Spyro7 15y ago"I've never used a tool that has a simple method for me to extend the ORM bits halfway through the query building process with some custom SQL" Well, I am not sure if this is exactly what you're looking for, but Django's ORM allows you to write custom SQL and then collect the resulting rows as objects. You can also circumvent the object layer entirely and deal directly with the SQL. Take a look at this page: https://docs.djangoproject.com/en/dev/topics/db/sql/ https://docs.djangoproject.com/en/dev/topics/db/sql/ I have found this functionality to be incredibly valuable for quite a few of the projects that I have worked on.
- dools 15y agoYeah most ORMs have a "custom SQL" option - what I mean is this (example in some non-existant language): function something(db_obj) print db_obj.getSql() #shows SQL built so far db_obj.having('SOMETHING = SOMETHING ELSE') db_obj.fromClause(this.bizarreCaseStatement() db_obj.order(this.weirdoOrderClauseThatReferencesCaseStatement()); return db_obj When I start working with db_obj, it might come from some other part of the application for which the "basic ORM" was just fine. Now I want to add some weirdo custom stuff in but I can't - I have to go back to the part of the application that produced db_obj in the first place and refactor that to use custom SQL. It's one or the other.
- mnutt 15y agoCheck out ARel. (it's in ActiveRecord 3, part of Rails) It uses relational algebra and is pretty good about letting you mix and match: enabled = User.where(:disabled => false) enabled.group("date(created_at)").having("created_at > ?", 1.month.ago).order(weird_order_clause).limit(5)
- dools 15y agoRight, yeah that's pretty nice!
- eropple 15y agoThe CodeIgniter ActiveRecord library follows the same pattern. Unfortunately, it's pretty kludgey and requires you to use CodeIgniter.
- Xurinos 15y agoDo you have an example that shows how to use ARel to do relational algebra?
- mnutt 15y agoI believe it just uses it under the hood, but I'm not familiar enough with relational algebra (or ARel) to know for sure. Here's a blog post from the author: http://magicscalingsprinkles.wordpress.com/2010/01/28/why-i-wrote-arel/ http://magicscalingsprinkles.wordpress.com/2010/01/28/why-i-...
- leftnode 15y agoI agree 100%. I tried to use and write a nice ORM but they usually get overly complex quickly, or are too simple. Now, I don't mind writing a simple boilerplate parameterized SQL query if it means my database access is lightening quick and I have the option to write as simple or as complex queries as I need.
- dools 15y agoWait'll you see the project I'm about to open source ;)
- rjbond3rd 15y agoGive us a hint.
- dools 15y agoI'll go you one better! I figured I may as well chuck this on github now - I've been stalling for weeks until I got the time to update it to use PDO/parametrized queries by default but I've just put a large warning at the top of the README that it's pre-release: https://github.com/iaindooley/Anorm https://github.com/iaindooley/Anorm The ORM for SQL lovers! That's only half the story: I've done the "query reader". Hopefully we can all come up with the ultimate "query builder" together - but the basic principle is that the query reader and query builder should be kept completely separate with SQL as their interface. I also need to come up with a neat way using closures to "mix-in" functionality to the "query row" objects (that take the place of the normal "boiler plate" DbObject type classes (usually "one per table" kind of deal). What do y'all reckon? Email iain@workingsoftware.com.au or fork the project - would love to hear everyone's opinions.
- eropple 15y agoI hate to be that guy, but Anorm is already the name of the Play! Scala ORM. Might want to consider a rename. =)
- tjpick 15y agoI've come to the conclusion that the only things that matter, in the end, are the SQL going across the wire in one direction, and the HTML going across the wire in the other. The code in between those should be as small as possible and as simple as possible, and as obvious as possible given the point of view of someone who knows nothing about your application architecture, to give you the best chance of fixing the bugs in the places that it matters. A framework tries to occupy the space in between those 2 wires, and unfortunately for frameworks are very rarely small and simple.
- fhars 15y agoOne of the reasons for that may of course be that the framework unlike your simple code knows all the edge cases where strings going in one direction or the other need to be escaped to avoid obvious security errors.
- jamesbritt 15y ago... and unfortunately for frameworks are very rarely small and simple. Quite a few start out that way, but for whatever reason feature-creep sets in and soon your off to J2EE land. If you start seeing more than one or two books covering a framework it's time to find a simpler one.
- antihero 15y agoI think microframeworks like Flask strike a really nice balance with this.
- jamesbritt 15y agoI like the idea of layered frameworks. For Ruby, there's Innate, a light-weight framework, and on top of that is built Ramaze, a more developed framework (though still comparatively light). Likewise there is Sinatra, and on top of that was built Padrino. And both Innate and Sinatra are built on top of Rack. So if you don't care for the direction or feel of a framework you can pop down the layers once or twice and build something you like without having to start completely from scratch.
- wvenable 15y ago> templating engines, markups, markdowns etc. etc. but the best way to build HTML is using HTML and testing in a web browser, always. I disagree with this. Completely abstracting away HTML is a mistake but some level of abstraction like a template engine is highly useful. I can hardly work without some "control" abstraction for form elements to handle setting the attributes and ensuring the form values persist between requests. Template engines can vastly improve the security of your code by making value substitutions safe by default. The problem with most frameworks, in my opinion, isn't the abstraction part at all. It's that they're over-engineered. It seems like many frameworks approach Turing completeness as they attempt to solve more and more problems and you end up writing framework programs from within your program. Sometimes you even get to use XML for this purpose.
- dools 15y ago"handle setting the attributes and ensuring the form values persist between requests" To me this falls under the category of "automation of repetitive tasks" - so long as I'm still fundamentally working with markup in my templates, a bit of automation never goes astray!
- wvenable 15y agoBut something like this: <label>Date:</label><ctl:DateBox id="Date" /> <label>Name:</label><ctl:TextBox id="Name" /> ...is an abstraction. I think your claim that you don't like abstractions isn't right; you just prefer a specific level of abstraction. Abstraction and automating repetitive tasks tends to go together -- you are specifically hiding repetitive details so you don't have to deal with them. Now some people completely abstract away HTML with something like Haml; but I personally prefer something lower level than that.
- dools 15y ago"...is an abstraction" That's the type of abstraction that I'm specifically opposing here. Each node in my template should correlate to one node in the resulting markup. In other words, my "HTML template guy" should be able to construct the interface in it's entirety, with my "developer guy" adding in the functionality. The "HTML Template guy" should not need to know what type of markup he's allowed to use in order to allow the developer guy to deploy his templates with ctl:DateBox.
- danenania 15y agoAdvanced abstractions are challenging to design well and could be harder to debug, but they can also improve efficiency and power by orders of magnitude. There are good abstractions and bad abstractions. If you use and create good ones, you will be a better developer. It´s important not to overdo it or to use the wrong abstraction for the job, but there are alternatives to slogging aroud in html and sql all day. By using a good orm and language abstractions like haml or coffeescript, I produce much, much less code, it´s much easier to read and maintain, and I can produce more quicker for clients as a result. If another developer can´t look at haml or coffeescript and understand it very quickly, I wouldn´t want them working on my code anyway. I can also produce more for clients by building even higher level abstractions so I can do things like generate forms, views, lists etc. for 30 different kinds of objects from a couple configuration files instead of hundreds of individual files for each type. Is the coding harder? Sometimes. But it also makes possible features and data usage that wouldn´t otherwise be realistic and allows for rapid modifications to the whole system without searching for dependencies all over the place. All levels of the web stack are an abstraction of some form right down to the chip. In the future, we will inevitably adopt higher and higher levels of abstraction in our computing, just as we have since computers were invented. Abstraction should be studied, practiced, and used with care, not resisted.
- dasil003 15y ago> The reason I hate frameworks (even things like Django which is very easy to get started with) is that, at some point, I'm asked to re-learn a different way of solving a problem that I've already solved in the past. Yes but it cuts both ways. The reason people hate maintaining your code is because they have to learn the way you did things which is buggier and half-baked compared to the way that any number of battle-tested open source frameworks did it. Not because your way isn't good, but because it just doesn't have the mileage yet. > the biggest conclusion that I've come to is that the best tools are those that enable you to do things faster or more conveniently but don't actually provide any abstraction. An interesting conclusion, but not nuanced enough. There's no escaping the need for abstractions, obviously there are some that you're taking for granted here such as high level programming languages and operating systems. Fair enough to set those aside. But then once you get into serious application-level territory you still have to decide where to abstract. Some abstractions are more leaky than others, some are more restricting than others. The art of it is figuring out which make sense in what scenarios. A really good framework hits the right abstractions for a wide range of applications, but even within your custom application you have decisions to make. For instance, you're one-helper = one-html tag rule of thumb might be a good idea if you have 5 forms on your website. On the other hand if you have 500 CRUD forms all with a bunch of repeated composited HTML structures then it's probably not such a good idea. I think what's underlying your conclusion is that you've seen too many frameworks that are way too complicated for the problem at hand. That's clearly what the OA saw, and that was really the selling point that launched Rails rise to prominence in the J2EE era. Modern web frameworks have really learned this lesson. Granted, Rails has gotten more enterprisey over the years—but not gratuitously—Rails core has demonstrated remarkable restraint over the years, and kept the focus on solving the 80% problems elegantly. But if something like Rails really is too much then you have micro-frameworks like Sinatra that really just give you the barebones structure to wire some code to a web server. Heck, due to the modularization of Rails and the extraction of libraries where applicable (eg. Rack), you can now avoid a formal framework entirely and still utilize a massive amount of code that was originally written in frameworks, now in stand-alone library form. When programmers trot out the old adage "use the right tool for the job", one of the main points is to avoid the human tendency to over-generalize. To be the best programmer you can be, you should be constantly re-evaluating your opinions about the "right" and "wrong" way to do things. Rather than forming concrete opinions, it will serve you better to understand the pros and cons of any approach so that you can effectively apply your knowledge new situations.