?

Log in

No account? Create an account
Previous Entry Share Next Entry
Paradigm shifts as fixing mental bugs
device
jducoeur
[Purely for the serious programmers.]

Amusing. I just realized the following:

The shift from "old-fashioned" programming (BASIC, Fortran, assembly) to modern styles was largely accomplished by internalizing that using "goto" was a design bug. The languages allowed it for a while, but it slowly went away, because it was never really worth the pain imposed by using it.

Likewise, the shift from imperative to functional programming is largely accomplished by internalizing that using "var" is a design bug. Like goto, it's still sometimes useful, especially when working in a hybrid language like Scala. But one of the ways in which I realize that I'm making the mental leap is that little twitch I get every time I type var, which is leading me to go that extra mile to eliminate it.

Yes, there is *vastly* more to functional than simply replacing var with val. But it's surprisingly central, simply because avoiding vars *motivates* a lot of functional techniques. I suspect I am slowly reinventing a lot of functional wheels as I figure out how to avoid vars in various circumstances. (For example, yesterday afternoon's exercise was puzzling out how to efficiently mutate a node buried in a tree.)

It's nothing more than a guideline, but I recommend it to anyone trying to learn functional-programming style: every time you reach for a var, try to figure out how to accomplish your goals with a val instead. It's possible without great pain most of the time, and you learn a lot from the exercise.

At this point, I think I'm only using vars in a few small, localized algorithms, and a few state vars nestled safely inside Actors. I continue to be surprised that I've been able to build something as big and complex as Querki in nearly pure-functional style, without terribly excessive pain. And the payoff is enormous: by combining Actors (in the form of Akka) and functional style, I wind up with a system that is massively scalable and thread-safe more or less automatically. For the most part, I don't even have to *think* about threading, which is a refreshing change of pace...

  • 1
I have to confess, I have a var in a trait that is used for collecting some data; and I know I can fix it, but well, need some time to fix it.

Oh, sure -- I have a few of those myself, especially in initialization code. (As well as the state vars inside the Actors, which are actually deliberate and likely won't change -- although even there, I keep being torn between that and the pure-functional version of Actor state.)

But my point is that that sense, that it's something that ought to be fixed, seems to be the key mental shift. It reminds me of the feeling of shifting from gotos to while/for back in the early 80s. (And the shift from using global variables to objects in the early 90s, and the shift from concrete object pointers to interfaces in the late 90s.) In each case, the old paradigm is still around and available for use, but there comes a point where I get a little "I ought to do something about that" every time I use it...

  • 1