
Write More Classes - someone13
http://lucumr.pocoo.org/2013/2/13/moar-classes/
======
haberman
I think the real point the author is trying to make is: use modular, layered
designs of composable components, instead of monolithic APIs that only have a
single entry point. The single-entry-point model imposes costs and decisions
onto the application that are hard to work around.

I think this is a good point. I think that it's hard to get from there to
"more classes are always better" though. More classes don't always make a
design more flexible. You have to consciously design for flexibility and
reusability, and even then it takes a lot of deep thought and hard work to get
your interfaces right, such that they are truly reusable in practice.

~~~
bhntr3
Quoting from the end of the article: "And our solution to monolithic code in
Python are classes."

So, I guess the question I ask as someone who doesn't write a ton of python
code is: Is that true? And if so, why? Is it not possible to compose a layered
API that doesn't rely on inheritance / classes in Python?

~~~
nnq
...indeed, the one thing I "hate" about Python is that somehow it pushes your
mind away from functional solutions. You end up writing either OO or
procedural code, although in a language with first class functions and
immutable strings you's expect to slip more to the functional side.

Anyone else had the feeling that although Python allows functional style, it
somehow pushes your mind away from it?

~~~
vaughan0
Personally I find myself avoiding writing in a functional style in Python
because of it's lack of good anonymous function literals and poor handling of
closures in nested functions.

Edit: when I say "poor handling of closures in nested functions" I'm referring
to having to use nonlocal in order to modify variables in the parent
function's scope.

~~~
nnq
yeah, I think lack of real anonymous functions is a small annoyance that can
get quite "big" from the yucky feeling you get when defining functions just to
pass them on. But... what do you mean by "poor handling of closures in nested
functions"?

Edit: ok, I get what you mean now :) ...though I consider this "poor handling"
a feature of Python - mutating outer scope variables is a side-effect and what
it encourages is what I like to call "callback hell functions with data
Javascript-style nightmare" :) (true, some people know to keep their sanity
and write readable code even in this style, and if you enjoy it you're
probably one of them few, but most don't...). By "functional style", I and
some people refer to "functional as in mathematical functions", so only using
side-effects when actually needed (yeah, some "extremist" languages like
Haskell try to never do them, but...) and you get this by having immutable
values and passing around anonymous functions (that don't modify their outer
scope).

...and this is another part of the paradox: this "feature" of Python should
encourage what I call functional style, but why oh why it doesn't? ...maybe
Rich Hickey is on to something with Clojure and it's actually more about the
data-structures than the language syntax or semantics?

------
contingencies
Write no classes!

Joe Armstrong: "I think the lack of reusability comes in object-oriented
languages, not in functional languages. Because the problem with object-
oriented languages is they've got all this implicit environment that they
carry around with them. _You wanted a banana but what you got was a gorilla
holding the banana and the entire jungle_. If you have referentially
transparent code, if you have pure functions-all the data comes in its input
arguments and everything goes out and leaves no state behind-it's incredibly
reusable. You can just reuse it here, there, and everywhere. When you want to
use it in a different project, you just cut and paste this code into your new
project. Programmers have been conned into using all these different
programming languages and they've been conned into not using easy ways to
connect programs together. The Unix pipe mechanism-A pipe B pipe C-is
trivially easy to connect things together. Is that how programmers connect
things together? No. They use APIs and they link them into the same memory
space, which is appallingly difficult and isn't cross-language. If the
language is in the same family it's OK-if they're imperative languages, that's
fine. But suppose one is Prolog and the other is C. They have a completely
different view of the world, how you handle memory. So you can't just link
them together like that. You can't reuse things. There must be big commercial
interests for whom it is very desirable that stuff won't work together."

\- Peter Seibel, _Coders at Work: Reflections on the Craft of Programming_

~~~
skrebbel
Nice quote, but did you read the article at all?

 _Something else I want to mention: what's written above will most likely
result in some sort of warmed up discussion in regards to object oriented
programming versus something else. Or inheritance versus strategies. Or
virtual methods versus method passing. Or whatever else hackernews finds
worthy of a discussion this time around.

All of that is entirely irrelevant to the point I'm making which is that
monolithic pieces of code are a bad idea. And our solution to monolithic code
in Python are classes. If your hammer of choice is Haskell then use whatever
the equivalent in Haskell looks like. Just don't force me to fork your library
because you decided a layered API is not something you want to expose to your
user._

~~~
contingencies
Aha! Good point. TL;DR! Only skimmed, as others have commented, it was far too
long. Perhaps the title should have been _Python rant: Write More Classes!_.
The point is, the themes touched upon in the article are greater. The author's
wish not to raise them is .. hereby noted, but not understood, really, when
appealing to a larger audience. You can't have it both ways.

------
10098
No. Don't write classes. Write useful abstractions. It doesn't matter what the
abstraction is (a class, a function, or something else you programming
language supports)as long as it fits your current architecture and can be
easily modified for possible future extensions.(I will agree with the author
that one giant monolithic function is probably a bad abstraction).

~~~
ankitml
+1, one of the best points in the discussion so far. :)

------
Locke1689
This is a bad article.

First, write nothing. If you can solve your problem without writing code (or
even better, by deleting code), that is the best solution.

Next, write code which fits your architecture. Sometimes functional
composition is the best system for representing your computational structure.
Tree operations, for example, are especially amenable to recursive function-
based computation.

Sometimes, when you are writing a state machine, for example, an object is the
best possible representation. Objects are entirely focused around hidden-
implementation finite state machines, and thus mirror your computation almost
exactly.

Funny how most people who have only practical training in a handful of
languages and no programming language theory at all tend to advocate for the
one style of programming that they know well. When all you have is a hammer...

Note: The small paragraph at the end of this article seems to hedge by
agreeing with me and essentially calling the reader to disregard what he
previously wrote. If he had followed my step one he could have avoided writing
the entire article. Think of the complexity saved!

~~~
barrkel
From what you wrote, I'm not sure you read the article. It's not about objects
vs functions; it's about hiding a lot of functionality behind an overly-simple
interface, with particular attention paid to an example of a parser that takes
a whole string rather than a streaming interface.

What annoyed me most was his constant apparent conflation between bytes and
characters. But I didn't really see much evidence of treating all the world
like a nail.

~~~
lucian1900
I saw no conflation. Everything there is a byte.

~~~
barrkel
Quote:

 _For instance while I have not yet reached the end of the string I would feed
my characters into a buffer until I found the end of the string_

 _The point however is that instead of reading characters step by step some
lexers will instead have a look at a buffer of a certain size and move a
pointer around in that buffer and modify some bytes in place (in-situ)._

He talks about this buffer, at one moment in terms of bytes, another moment in
terms of characters.

It's a pedantic quibble, but an easy source of errors, especially if you're
using a language that doesn't distinguish strongly between the two concepts,
and e.g. you encode your characters as UTF8 with a weak alias to unsigned char
just like bytes.

------
Uchikoma
As Java was mentioned. The Java API is very nice, but there is a layer missing
on top. The Java API was written with a early 90s mindset and got most users
after 2000. This goes for most Java APIs. IO, Swing, ... The idea is to have
LEGO building blocks (BufferedReader) you can plug together. But you need to
plug them together all the time. The missing layer e.g. is
IO.readIntoString(file). Apache IOUtils, StringUtils etc. fill in this layer
for many Java APIs.

The one API that is not powerful enough is Collection. There you have the top
layer without the LEGO building blocks. Compare this to the Scala collection
API which has the top layers and the building blocks.

For a good API you need both, building blocks to tailer to your specific need
(20% of the time) and an easy top layer (80%) to prevent writing the same
stuff all the time.

~~~
dm3
To be fair, they have mostly fixed the IO API with Java 7 (NIO2). This covers
various Files# helpers as well as a proper Path abstraction.

~~~
Uchikoma
15 (?) years late ;-)

~~~
RyanZAG
Why does that matter? If version 1 is bad, we should never use any newer
versions because version 1 was bad? The iPhone didn't support 3g in the first
version, so we shouldn't use current iPhones?

~~~
icebraining
In some ways, yes. Plenty of people moved to other languages because of those
handicaps, and they have no good reason to come back.

~~~
RyanZAG
You make it sound like it's some kind of popularity contest, where people not
choosing the language means it 'loses'. I disagree pretty heavily there - your
hammer doesn't lose if you use your saw. The language's user loses if he is
such a fanboy of hammers he refuses to use the saw. If Java improves to become
the best tool (not saying it has/will), then choosing not use use Java because
you 'moved on', is a failure on your part, not the tool.

~~~
icebraining
The thing with analogies is that you have to know when they break down.

Sure the language loses. An hammer is self-sufficient; a language needs
libraries, community support, job/project candidates that can replace an
absent developer, etc. Do you think having NumPy isn't a win for Python?

Of course, if the language is sufficiently better than the others, maybe
you're willing to write your own e.g. Websockets library to use it. But
there's still a large handicap there.

For example, Plan9 is in many ways a better OS than GNU/Linux. But I still use
the latter, because I rather have the support and thousands of binary packages
that a larger community brings.

------
viraptor
I really don't like the way this was presented, even if I may agree with the
idea underneath. It's not about classes at all. It's about better design, but
even the examples are strange.

Just from the JSON example:

\- Why do I need a class for streaming JSON - Python's got a perfectly good
`yield` for returning tokens in such situations.

\- Why would I ever design the JSON library to be extendable at the tokenizer
level? If you need serialiser / deserialiser, why not just provide a map of
types to callbacks / callback as a parameter? Do you really want to extend
JSON format itself?

\- The 2GB JSON example is just weird. If you care about such use cases, you
a) most likely have a limit on data size at webserver level, b) use proper
formats for handling that size of data (I really doubt there's no better data
representation once you get to GB sizes).

I see his point of view, but he's arguing for one single "hammer" solution,
rather than arguing against the monolithic design. His story seems to present
some weird back-story really: "I needed to make my data easier to handle, so I
started automatically serialising objects into JSON, then they became huge so
I have to start streaming them otherwise just parsing of them takes way too
long".

~~~
the_mitsuhiko
> \- Why do I need a class for streaming JSON - Python's got a perfectly good
> `yield` for returning tokens in such situations.

See the msgpack-cli example at the bottom. Say you have a function that
returns a generator for tokens in Python. You would need another function that
builds objects out of them. How do you customize how objects are being built?
A class makes that simpler because each of the methods are extension points
you can override.

But yeah, a token stream would be much appreciated.

> \- Why would I ever design the JSON library to be extendable at the
> tokenizer level?

For instance if you want to skip past objects. That's what we're doing for
instance for unwanted input data. That implicitly also prevents hash collision
DOS attacks because we never build hash tables for things that we don't want.
It also gets rid of the suspension of execution when a garbage collector runs
and cleans up a nested structure. I can make you tons of examples where the
"build a tree, reject a tree" approach destroys an evented Python server.

> \- The 2GB JSON example is just weird. If you care about such use cases, you
> a) most likely have a limit on data size at webserver level, b) use proper
> formats for handling that size of data (I really doubt there's no better
> data representation once you get to GB sizes).

Try using a streaming JSON API like Twitter's firehose. Most people just give
up and use XML because there is SAX or if they go with JSON they newline
delimit it because most libraries are horrible or useless for parsing streamed
JSON.

~~~
timruffles
I think

> A class makes that simpler because each of the methods are extension points
> you can override.

is a strong argument in favour of classes. They're more extensible even if the
author doesn't consider it. However - as soon as your class has an
implementation like

    
    
      def to_json(str)
        JSONParser.parse(str) # JSONParser is not streamed
      end
    

then you're in trouble. Unless your language supports dynamic lookup of
constants, class names feel very much like a global variable that's a pain to
change. In Ruby, as of 1.9.3, lookup is lexical so you can't simply define a
class-local value for the JSONParser constant.

I don't know the story in other languages - I assume Java has it as you see a
great emphasis on dependency injection. If dynamic lookup of constants was
present I think classes would be more unintentionally extensible however they
were written - as it is, you have to be as careful writing classes for
extension as for functional code where you have to manually provide extension
points.

~~~
hythloday
In Java, you often see a class JsonClass with a toJson method like you
presented and then a StreamingJsonClass with an overriden toJson that streams
- this can cause problems with types (because the most obvious return type for
toJson when it's written is JsonObject, but you really want an
Iterator<JsonObject>), but Ruby/Python have the same problem (only hidden).

It's quite idiomatic Java, though, to remove all static calls from methods,
even if you have to use anonymous classes (i.e. extensible method
dependencies) to do so, for exactly the reasons you outline.

------
fab13n
There's a fairly effective rule of thumb: classes--or more accurately objects
--are a way to cleanly encapsulate state. If you rely on a mutating state, you
probably want an object/class. If not, a function is often better.

Now you can bundle related functions together in a structure, but this
structure is morally a module, not an object, let alone a class. Some
languages will force you to encode those modules as classes / prototypes /
singletons, but that's just a design pattern to circumvent a limitation of the
language.

------
chewxy
You can do the same with python's msgpack as the C# version

Try this:

    
    
        packer = msgpack.Packer()
        serialized = packer.pack('stuff you wanna pack')
          
        unpacker = msgpack.Unpacker()
        unpacker.feed(serialized)
        print unpacker.unpack()
    
    

I had originally used this, but then as my API scope extended to more than
just using msgpack, having a common API interface for json (i.e. the .loads()
and .dumps() method) was found to be more useful.

And while I agree with most of the article, I don't think writing more classes
is a one-size-fits-all solution. Classes IMO, only makes sense from a heavily
OOP point of view.

~~~
niggler
I dont think the OP was pointing to OOP when talking about classes. You can
have classes without a meaningful class hierarchy that still conforms to the
OP's desired programming style using _protocols_ like the iterator protocol.

A better way to phrase the OP's salient point while sidestepping the polemic
of OOP is "Standardize and use protocols".

------
notallama
if classes didn't have such a terribly verbose syntax in basically every
language that has them, i'd be less opposed to using them.

in java, c++, or c#, to add a variable to a class, you have to repeat its name
4 times. once to declare, once in the constructor parameters, and once on each
side of the assignment. why am i writing the same thing 4 times for what
should be a core part of the language?

in haskell, you write it once (i'm not saying haskell's records are nice, but
they got that part right). same with rust.

and with a function, you write it once.

~~~
dougk16
I get what you're saying, but good OO for me usually suggests nullary
constructors, letting a class know when something happens as opposed to
setting internal state directly, and the class saying let me do something for
you using my state instead of giving you my state directly.

Providing a getter at least is sometimes practically unavoidable, so there's 1
repetition, but with a good IDE that's just a quick key combination over the
variable name.

~~~
epidemian
> good OO for me usually suggests nullary constructors

I'm curious, could you please elaborate on this point? If a class has any
dependency, i usually find it better to require that dependency to be passed
in the constructor, so the constructed instance can always be in a valid
initialized state. Why do you find nullary constructors to be good OO?

~~~
dougk16
I came off too heavy-handed there. My intention was more to just say that
variables shouldn't be put in constructors if they don't have to be. So, just
railing more against the pattern that Java seems to have popularized where
every private variable automatically has a getter/setter and can be set
through the constructor. Certainly if an object requires some initial state
that can never change, passing the value in through the constructor is usually
most appropriate. Even then, I sometimes like to have a nullary constructor
with an init() method. Just makes certain design patterns utilizing e.g.
reflection or pooling a bit easier to manage in some languages.

~~~
epidemian
Ok, i didn't get your point then. Well, i definitely agree on that the
pattern/trend of auto-generating getters, setters and constructor parameters
for every attribute in a class without considering if those attributes should
be visible (or, worse, mutable) from the outside is pretty hideous.

About the nullary constructor + init() method for deserializing purposes, i
don't have any strong opinion really, as long as consistency is kept
throughout the code base/module that relies on that. Using Java's reflection
API though, you _can_ extract all necessary type information from non-nullary
constructors in order to call them with the required dependencies, which is
not essentially more complicated than instantiating the class and then setting
its properties thought setter methods.

------
wyuenho
People don't talk about this anymore for some reason, but I think both Jack
and Armin are really just approaching API design in 2 different ways - top-
down and bottom-up. The problem is, most people stick with the same approach
through out and end up ignoring that programmers are mere mortals too, and
they have human needs.

Expanding on Armin's dichotomy, top-down designs like Python's open() or
jquery plugins start with giving 70-80% of users APIs that are as simple as
possible for their most frequent use cases while shielding them from the
sausages underneath.

Bottom-up designs like Java's standard library or POSIX start with LEGO
building blocks that solve the most fundamental pieces of largely academic
computer science problems and just give them out to their end users and expect
them to be able to assemble Tower Defense by solving this LEGO puzzle first.

The problem with sticking entirely to their 2 approaches is that you end up
either ignoring power users or making healthy adults with normal IQs feel
stupid. There is no reason you can't serve 100% of your user base by
incrementally evolving your API approaches and provide 2 sets of APIs within
the same library, with the top-down easy one shielding the bottom-up sausage
factory that takes care of the meat grinding for you. Most API designers don't
realize this and won't ever go there. Extremists and egoists with lots of
opinions will spending hundreds of man years to promote their One True Way of
doing things. They'll say things like "no leaky abstractions!" or "these
enterprise people are just making things too complicated to create jobs!",
when the simple truth is probably just that they don't understand how people
think.

Make your libraries easy to do things that are easy, but make hard things
possible too.

~~~
jessaustin
_Make your libraries easy to do things that are easy, but make hard things
possible too._

IME Ronacher follows this dictum very well. I'd suggest that anyone who wants
to see this try his Flask and Werkzeug packages.

As for storing extra state, about which many here have complained, I've found
it really helpful that I can set werkzeug.http._accept_re to my own RE when I
want to do something weird with media types. That is state that the vast
number of users won't need to touch, yet the fact that it exists makes life
better for someone who does need it. I'm sure there are numerous other
examples I haven't had to bother with yet. Would we really be better off if
this RE had to be passed in every time we handled a request? (Although I would
understand if you argued this value should be stored in an object not in a
module. I haven't needed that yet.)

On the other hand, routing to and handling resources with these packages is
typically done with functions and decorators only, although the route
decorators are methods of the application object. So Ronacher is not any sort
of hardass about classes; he just does what works.

------
splicer
Personally, I find it more natural to use closures when parsing in Python, not
classes. BTW, my day job frequently involves writing parser in C.

------
comex
IMO, the Flask example is pushing it - considering how large a job rendering a
template is, the number of customization points is probably appropriate, but
at some point you're going to get lost in a rabbit hole of wrapper functions
that call wrapper functions and end up with three equally appropriate levels
you might hook into because the code was written to keep you from having to
duplicate a single line of code from the library in your alternative
implementation-- never mind how confusing that makes things to the casual
debugger (who wants to get to the actual meaty code to see what's wrong with
it). Flexibility is useful, but it must justify the loss of simplicity.

But yes, in the JSON cases, having more flexibility than a single 'loads' is
clearly justified.

~~~
DeepDuh
Some note: When it comes to debugging I've rarely seen a better stacktrace
output than the one Flask presents you in debug mode (provided by Werkzeug).
It actually lets you _open the damn sourcefile_ right there. Right now I'm
(mis?)using Flask together with CouchDB to build a db application where you
can dynamically define your entities, fields, code hooks and so on at runtime
and using Flask for this has been great so far. Ronacher's attitude clearly
shows through in how easy I could get Flask to behave in ways it was possibly
never meant to (dynamically add view definitions, document mappings and so
on).

So Armin, if you read this, thank you, it was a joy spending time with your
framework (and source code) over the weekend ;)!

------
cgopalan
By default, I go with the inclination to put code in functions when I tackle a
project, because most of my projects are just products and applications
without a public API and testing or debugging the flow in a functional
paradigm is much simpler. I can take a function and plug it in the interactive
interpreter (in Python) and run it without needing to instantiate other state
that's needed for the test.

However, in certain cases, like where I need to write a public API, I have
found that having classes as wrappers to the functionality helps it a bit. So
really, the "stop-writing-classes-unless-you- absolutely-need-to" guideline
still holds true for me.

------
ankitml
The discussion on the thread has rotten to much extent, the article doesnt
address different languages or paradigms, he just mentions about classes being
better than block codes in python. Something more rudimentary, a valuable
piece for quick-fix programmers, for hobby programmers. Classes are one way of
abstractions.

So he asks for using abstractions instead on no abstraction (block code) but
if you have other ways of abstracting code, please go ahead. THis article is
good for people with few / no tools, people who are still learning

------
redangstrom
Seems like he's asking for modularization so we can make special-case
adjustments to libraries without completely monkey patching or rewriting them.
Seems like a reasonable ask of a mature library.

On the streaming verus resident working set argument... Most of what most
programmers deal with doesn't have to scale to deal with huge streaming
datasets, so it doesn't get the attention.

------
jakejake
I must be way out of touch because I had no idea there was an anti-class
movement for which the OP has to argue for more classes?

~~~
xentronium
He mentions _stop writing classes_ talk in the very beginning.

~~~
mhd
Which he doesn't really address, nor do the two opinions necessarily clash (at
least not totally). Diederich's talk is mostly about avoiding to write
_superfluous_ classes. Quite often a simple module with one or two function
suffices. His examples look quite different from those in the blog post.

(Although I have to admit that I skimmed most of them, as I'm in serious
eyeroll territory whenever I see the old Java IO API used as a bad example
again.)

~~~
xentronium
Good point. I think author doesn't actually care as much about classes per se
as he does about _interfaces_ and _extension points_. Complexity might get out
of hand incredibly quickly, though.

------
pyeek
I think there is an aspect to this article that won't be understood unless
you're really part of the Python community. For a while now, one of Python's
selling points to users from other languages has been "you don't need to write
all that code" (most likely directed at Java), more specifically you can
simply use a function rather than having to define a class just to define
static methods etc. Over time, this has grown into the mantra of "You don't
need a class just use a function/module". A lot of people seem to follow this
viewpoint blindly, so much so that they consider it to be "Pythonic"; the way
you "should" write python.

I think Armin's post is somewhat in line with the following post from the
google testing blog. [http://googletesting.blogspot.com/2008/12/static-
methods-are...](http://googletesting.blogspot.com/2008/12/static-methods-are-
death-to-testability.html)

------
Offler
Could not agree more with the idea that people should write more well
designed, OO code. This exact same issue is prevalent in JS land and it leads
to people saying JS can't be used for real development, when in fact the
problem is that the code they write is a mess and that's what's holding them
back.

------
cwp
Is there anything to this debate that doesn't boil down to style? Python has a
pretty decent object system. It also has first-class, nested functions with
closures. You could write good OO code or good functional code according to
your taste, and python libraries don't seem to strongly prefer one style over
the other. I'm not terribly interested debating OO vs. functional in the
general case, but I _am_ interested in the pros and cons of each style in
specific contexts.

For example, Python's lack of variable declarations sometimes leads to bugs
involving scoping. (I've run into this a couple of times myself). Does this
quirk become more of an issue in heavily functional code? Are there other
language quirks that become troublesome in heavily OO code? In what
circumstances might one style be preferred over another?

------
jerf
In Python, the distinction is less strong than it is in some other languages.
Since a class can implement __call__, allowing instances to be directly called
like a function, even if an API specifies a function, you can pass a class
instance in with a suitable __call__. So using functions doesn't have to tie
to to it being a function forever and ever in the future (or breaking reverse
compatibility, the way it does in most other languages. This isn't a perfect
answer to the objections, but the objection is at its most weak in Python.

------
INTPenis
A good example of classes in Python is the dnspython library.

It's tasked with returning records from parsed zones and every single record
is a class. I like it and I don't understand the first sentence of this blog
post.

Try not to put too much weight on what others tell you, make up your own mind.
It's a classic human issue.

------
benatkin
I find that I like it when classes store configuration that's known at load
time, rather than state. That way it's a lot like a Common Lisp program,
except multiple programs can run in the same process, have different
configurations, and communicate with each other.

------
mafro
Can anyone explain the statement about simplejson for me please?

    
    
      Some libraries manage to skip the token part. (I'm looking at you 
      simplejson, a library that even with the best intentions in mind 
      is impossible to teach stream processing)

~~~
SoftwareMaven
When you are trying to parse extremely large documents or you only care about
a small subset of a document, needing to load the entire parsed file into
memory is problematic. Simplejson doesn't provide an API that allows for any
other option.

This is in contrast to something like an XML sax parser, that allows you to
register for events like "a foobar element was loaded". You get the foobar
element while all the other tokens are thrown out the window as soon as they
are parsed.

The complaint is that, somewhere, under the hood, simplejson is doing that
token parsing, but because of their API, a user can't plug into it.

~~~
masklinn
> The complaint is that, somewhere, under the hood, simplejson is doing that
> token parsing, but because of their API, a user can't plug into it.

I read it exactly the other way around: simplejson skips an internal
tokenization step, so even if you fork the library it is pretty much
impossible to make it streaming, because there's no token stream to handle
stream state.

~~~
hyperpape
That's more or less right, masklinn. To the above writers, look at the Python
source (I can't vouch for how the C implementation does things). It's not
beautiful, but it's also not hard to understand.

The effective work is all done inside a big function. To customize it, you'd
have to split that function into pieces and then glue it back together using a
class or your own function coordinating the parts.

------
Ingaz
I could not understand how classes can help with JSON-example.

It looks the same as XML SAX vs DOM: you feed NN-Mb to DOM-parser (SQLServer
xml-datatype for example) and you have problems. No matter: classes or
functions.

------
quasque
I must have missed something in my reading of the article - what is the
relevance of " _Condoms for Onions_ " to the essay?

------
ehutch79
I think the original video this is a response to, was really just saying 'A
class should not be one method, that's a function'

~~~
pekk
That was only one of the things the video said. Overall, it was pointing out
how overuse of classes was resulting in lots of extra complexity and
additional lines of code, making programs harder to understand and maintain

------
iso-8859-1
The Java would have been prettier if he had used the new try-with-resources
from Java 7.

------
dakimov
The programming industry walks around in circles and there is no beacon in
this darkness of ignorance.

There is no professional culture and new generations of developers
successfully forget all the experience previous generations have accumulated.

Also, some piece of advice from a seasoned programmer to the web-programming-
children: if you are not really a serious developer, if you write your
freaking websitee on Django, or whatever a framework there is, you don't
really need a methodology, because you are doing an easy task, you can write
in whatever language/style/paradigm you like, even on Brainfuck. But please
don't extrapolate your humble experience to the entire industry and don't tell
people working on large complicated _(real)_ projects how they must write
code, because they have some experience you don't have.

~~~
klibertp
Because programmers who happen to implement complex, huge, real systems that
happen to interface users via a browser are of course less of a "real"
programmers then the ones who happen to implement rather straightforward, but
native, CRUD interfaces to some legacy DB.

Wait, what?

"Domain pissing match"? Or just inexperience in and misconceptions about
writing web apps on your part?

Anyway, that's irrelevant - the advice here is not specific to web programming
at all and is a sound one, no matter how experienced you are or what you work
on at the moment. Writing modular, reusable and easily customisable code is
just a good idea.

Heh, what am I doing. It's still early for me and I'm responding to an obvious
trolling attempt from frustrated Java programmer who uses the word "humble"
without a shred of humility in his own writing. I should just stop and try
porting this "freaking website on Django" that my team has been working on for
the last three years to Brainfuck - I'd be more productive that way and I
guess it would be more fun, too.

------
leppie
So in Java, a parameter named 'filename' is automatically aliased to 'path'?
Doh...

static String readFirstLine(String filename) { try { BufferedReader br = new
BufferedReader(new FileReader(path)); ....

So people writes this everyday, yet still fail to do it correctly...

Also, this article was written 1 day in the future. The future looks bleak to
me...

------
akaru
Jesus, learn how to write before, you know, writing so much.

~~~
Myrmornis
Can you translate those 11 words into German?

