Shared publicly  - 
 
A blog post by me: wondering that refactoring by extracting functionality into functions is a sign of poor expressivity in programming languages.
With the obvious definition of displayUserInList() and removeUserFromList() . But the first approach had certain invariants that the second does not. Assuming you don't mess with the UI/DOM directly, and assuming that updateUserStatus() is called when it needs to be called, the user will be in ...
2
Ian Bicking's profile photoDeron Meranda's profile photoMahlaqa Goni's profile photoLaurence Rowe's profile photo
14 comments
 
Something is wrong w/ comments on your site so leaving my comment here:

In Pascal you could define sub-procedures locally to refine functionality in a stepwise fashion. You can do the same here in js if your only concern was locality and pollution of the larger scope/namespace, in order to slightly improve the clarity of intent, although ultimately it's just pushing around the ugliness. Part of the problem here is that these operations (append/remove of dom) are not syntactically symmetrical making any further simplification difficult. An alternate approach would be to use template rendering
 
Just tested comments and they work fine for me...?

I'm guessing you are referring to a technique like:

  (function () {
    ... locally isolated code ...
  })();

(And the equivalent in Pascal, that I assume just requires naming the function, kind of like you'd have to do in Python.)
 
BTW if anyone is still not using CoffeeScript, here's the equivalent

do ->
    ... locally isolated code ...
 
Functions are names for actions. Giving something a name is great, because it makes it easy to understand what's going on. The problem is not having a name, but where the name is visible.

"Namespaces are one honking great idea -- let's do more of those!"
 
I could put function wrappers around all kinds of things, but it wouldn't usually accomplish anything.  Technically variables I set would be isolated to the function.  Access to read outer variables would still be there.  Visually it would provide something, but at best it'd be a wash.

I don't think the code example I give is awesome, and it is sensible to refactor it (and obviously more lines of code would be involved in a real case).  But are there better ways to refactor?

Giving it a name does at least create a minimal contract: the code in this section does what I say it does and not other things.  An anonymous function doesn't say anything about what it does.
 
The not-so-novel way is obviously with private functions/methods. Since those are tightly scoped to a known context (i.e. a single class) the non-locality is limited, and as a reader you know it's abstracted just for better maintainability, not as API design. Looser languages without a concept of private methods are better for unforeseen re-usage, but you lose the ability to separate intentional API design from refactoring except via convention (like functions starting with "_") or tricks like the locally isolated code mentioned above.
 
+Ian Bicking (hmm ok maybe it's my phone) no I meant:

function outer() {
function step1() {}
function step2() {}

step1();
step2();
}

Yeah still ugly. The only simplification win would be modelling more abstractly, such as using a single dom node for both append and remove - may not be possible with jquery syntax not sure.

// node = extract shared setup
if (active) {
node.appendTo(...)
} else {
node.remove()
}
 
+Aaron Hamid  Template rendering is nice, if you have a bunch of changes to make. But you have to consider that every DOM-manipulation comes with a cost. So rendering a complete collection of users, when only one element changed would in my eyes be a bit of overhead.

+Ian Bicking I do not really get your point. Of course, if you programm javascript like your code examples suggest, it is understandable, that you are quite unsatisfied with your code. You are polluting your sourcecode with tons of global functions. But there is much more expressive power in javascript - like the closure example you gave and in combination with  javascript namespacing  ( cf. http://addyosmani.com/blog/essential-js-namespacing/ ) you have a mighty tool. Or if you want to modularize your javascript, take a look at: http://requirejs.org/docs/whyamd.html

But hence your example is from the UI-world, I would suggest to take a look into http://backbonejs.org/

There you would define the list of users as a View and the status of a user would reside in a model. And a collection of user would be handled in a Collection. So freestyle you would implement it straightforward like:

UsersView=Backbone.View.extend({
    el: $("#userlist");
    initialize: function(){
        usersCollection.on("remove", this.removeUser, this);
        usersCollection.on("add", this.adduser, this);
        this.render();
    },
    render:function(){
        // Do initial render stuff here
    },
    removeUser:function(user){
        // remove User from List
    },
    addUser:function(){
        // add User to List
    }
});

What is all the magic about? Besides some Backbone-magic like "el","initialize" etc, we are using a semantic unit encapsuled in an simple object-literal {} Backbone's extend method is nothing other like a special tailored way of inheritance giving the parametric object all it needs to behave like a Backbone-View (in this case). So in the upper ini function we have those simple lines you mentioned in your refactoring example. and we have the functions encapsulated inside our view, which makes it clear, that the function UsersView.removeUser belongs to the UsersView.

And you could go one step further and encapsulate this view in a closure, so there is no way from outside the closure to call this method on your view.

So, as I said, there are mature ways of organizing your code in javascript.
 
I feel like the refactoring in your example is more than just code organization: by encapsulating the behavior for adding and removing users from the list, you're making the statement, "This is how we add and remove users from the list."

Visibility modifiers, on top of that, say, "You are meant to use this to add / remove users" or "You are not meant to use this to add / remove users."

It increases the body of knowledge that has to be learned to modify the software in question, yeah, but as long as human beings are writing the "by hand"  then I don't see many alternatives.
 
+Thomas Junk I agree. I'm not advocating template rendering across the board, just noting it is one possibility for refactoring this code.  In fact the apps I have worked on, which are in Backbone, we typically go with direct dom manipulation because as you mentioned it does not make sense to throw away large views and re-render large lists just for small changes.  I refrained from mentioning Backbone only because the view is changed based on a state change of the "status" attribute (and therefore still needs a conditional check) which is not exactly add/remove on the collection (although I suppose it could be modelled as such).
 
Of course my intention wasn't so much to highlight a specific question of UI/domain-logic separation, but to consider a case where an organically created function might be refactored to something computationally equivalent by extracting a chunk of code into a function.  Of course since it was an example I kept it short, but tried to use a realistic example.  To suggest the frameworkization of the code is... well, yes, some people are drawn in that direction, but I'm more interested in how to avoid that path.  But to avoid that path you have to offer another path.  I'm not sure what that might be, but I have a hunch that separating organizational concerns from reusable abstractions might be part of it.  It's still a pretty vague hunch though.
 
One curious language paradigm is Literate Programming, invented by Donald Knuth back in the early 1980s. Though the mixing of documentation and code is the most obvious feature, it  does provide a novel way to isolate little chunks of code which can be defined and documented elsewhere, but that all get assembled into the correct place when the code is all weaved together at compile time.  I don't think it solves all your issues, but it is certainly a different way of looking at organizing code into little understandable chunks that doesn't involve a function declaration in the typical sense.   See <http://en.wikipedia.org/wiki/Literate_programming>
 
Finding a good balance seems to be a matter of experience. For application code (i.e. when not designing an API used elsewhere) I usually advocate a rule of threes - only extract repeated code into a function/component/class once it's used three times. But that's really to avoid premature generalisation.

When working on a difficult problem, I often find myself using a functional style in order to postpone solving a part of the problem until later. If it ends up being a short single/dual use function then I'll usually inline it when I make another pass over the code. Comments are a better way of conveying intent than function names and when reading code I want to see what the code actually does, not what the programmer thought it did when they wrote it (often me a couple of months before.)
Add a comment...