forked from malthe/otto
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
5 changed files
with
95 additions
and
89 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,90 +1,17 @@ | ||
================== | ||
Guiding principals | ||
================== | ||
.. _guidelines: | ||
|
||
Fun is important | ||
================ | ||
Guidelines | ||
========== | ||
|
||
I like creating things. Ever since I was a little kid I would spend | ||
days on end building with Legos. For me programming is like having | ||
an endless stream of Lego bricks in any size, shape and color I can | ||
think of. That is why I got into it, I just wanted to play and have | ||
fun! | ||
This section outlines the principles on which this library is built, | ||
which extends to how we'd like to see it evolve. | ||
|
||
You might have a different story. But I bet that, like I, you didn't | ||
start coding for the money. Let's face it, there are probably more | ||
effective ways of doing that. My guess would be that for some reason | ||
or other you got to have fun when programming. | ||
Library vs Framework | ||
|
||
Fun, or lack thereof, is the main driver behind Otto. We wanted | ||
to have a system which made web-development an enjoyable experience | ||
again. Something which puts us in control instead of being | ||
controlled. | ||
We believe it's inherent to frameworks to introduce anti-patterns | ||
and to require a particular development *model*. | ||
|
||
Having fun gives energy, makes you more productive, happy and even | ||
more healthy. So when faced with the choice of doing something, why | ||
not pick the option that's more fun? | ||
|
||
No conceptual baggage | ||
===================== | ||
|
||
Baggage is junk which you have to haul with you wherever you go. It | ||
slows you down when traveling, makes your back hurt and exhausts you | ||
faster. This is also true for conceptual baggage, which is baggage | ||
you have to lug around in your mind. | ||
|
||
That is why systems should try to avoid introducing radically new | ||
concepts. A Python developer should not have to re-learn the | ||
language because someone other than Guido introduced something new. | ||
|
||
An example of conceptual baggage from the zope.interface | ||
package. Can you guess what the `implements` call is going to do?:: | ||
|
||
class Foo(object): | ||
interface.implement(IFoo) # <-- What is this supposed to do? | ||
|
||
Python just does not have a concept like a function call which | ||
modifies something outside of it's normal scoping | ||
rules. "Directives" like these just do not make sense and introduce | ||
new conceptual baggage. | ||
|
||
Frameworks suck, try to avoid them | ||
================================== | ||
|
||
Coding is about solving problems your way. Frameworks are about | ||
requiring you to structure your code in their way. At one point your | ||
way and the frameworks way will collide. What makes perfect sense to | ||
you will be made impossible by the framework. | ||
|
||
You then have to rethink your problem in terms the framework might | ||
support, probably going as far as forgoing the optimal solution. The | ||
force and restrictions a framework imposes on you, telling what you | ||
can and cannot do, just sucks. It drains energy and creativity. It's | ||
just not fun. | ||
|
||
A way to handle this problem is by take note of a few possible (this | ||
list is not exhaustive) guidelines: | ||
|
||
- A framework is anything where you plug your code into | ||
|
||
- Frameworks usually have globals, don't use them. | ||
|
||
- Globals are only to be introduced by the developer of an | ||
application, not by a library or framework. | ||
|
||
- Make it easy to alter behavior by using the object-oriented paradigms: | ||
|
||
- Sub-classing and overriding methods is a fine way to let people | ||
customize your code. | ||
|
||
- Favor delegation over sub-classing. | ||
|
||
- Put code in control by giving it all you can. This means that | ||
plug-ins should receive as much state as you can reasonably give | ||
them. Err on the side of giving to much, it's easier to ignore | ||
state then to make it magically appear when you need it. | ||
|
||
tip:: | ||
|
||
Extend and replace before plugging in place. That which is | ||
passed around does not have to be globally bound. | ||
The primary motivation for writing and using frameworks is to | ||
increase productivity, but it's not clear that this is an actual | ||
outcome. On the other hand, it is evident that there are actual | ||
negative effects of working with or within a framework. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
.. _usersguide: | ||
|
||
User's Guide | ||
============ | ||
|
||
This section is a guide on how to write web applications using this | ||
library. | ||
|
||
Philosophy | ||
---------- | ||
|
||
In not being a framework, but a library, projects begin with an empty | ||
module and a copy-paste of the *hello world* application. The | ||
objective is to embrace the empty module and avoid the pitfalls | ||
inherent to development outside a framework. | ||
|
||
*I like to create things. As a kid I would spend days building | ||
with Lego bricks. Programming is like an endless stream of bricks | ||
of every size, shape and color; that is why I got into it, to play | ||
and have fun!* - Jeroen Vloothuis | ||
|
||
The library was built from the experience of working with various | ||
other libraries and frameworks, or rather, because of it. Many lessons | ||
learned have inspired its design, which adheres to the following | ||
principles: | ||
|
||
**Must be fun** | ||
|
||
It means never having to say you're sorry. | ||
|
||
**It's your code** | ||
|
||
It's inherent to frameworks to take over control. | ||
|
||
Programming is about solving problems. Frameworks are about | ||
spelling the solution in the language of the framework and then | ||
hand over control. Sometimes it's a perfect fit, but often enough | ||
it's a poor fit or an outright bad fit. Everything's a compromise, | ||
but it becomes a compromise more quickly when you're using a | ||
framework that's not an optimal fit. | ||
|
||
Warning signs: | ||
|
||
- Plugins | ||
|
||
- Globals | ||
|
||
**Few dependencies** | ||
|
||
Conceptual baggage wears you out. | ||
|
||
Python has enough concepts of its own. It's tempting to introduce | ||
new playing rules, but in the long term, conceptual baggage incurs | ||
bitrot. | ||
|
||
An example from :mod:`zope.interface`:: | ||
|
||
class Foo(object): | ||
zope.interface.implements(IFoo) | ||
|
||
What is this code supposed to do? It's not obvious from this | ||
snippet. Python does not provide a reference to a class while it's | ||
still being defined. | ||
|
||
We have tried to weed out all dependencies which aren't absolutely | ||
necessary such that you can decide which code to depend on. | ||
|
||
**Use the right abstractions** | ||
|
||
Python is an object-oriented language. With the right abstractions | ||
in place, this paradigm makes it easy to reuse existing code. | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters