IWETHEY v. 0.3.0 | TODO
1,095 registered users | 1 active user | 0 LpH | Statistics
Login | Create New User
IWETHEY Banner

Welcome to IWETHEY!

New Reusable components?
Any other regularity in the code is a sign, to me at least, that I'm using abstractions that aren't powerful enough-- often that I'm generating by hand the expansions of some macro that I need to write.

Now this confuses me, as it sounds as if he is heading upstream against the prevailing style of thought about reusable components.
Famous last RPG quotes: "I'll just shoot this fireball down the dungeon passageway..."
New Re: Reusable components?
What Paul Graham means is that a repeated pattern is something you should wrap up in an abstraction and reuse. A common practice when refactoring is to look for sequences of repeated code, and then wrap that up into a method or function, which you call henceforth. "Once and only once", as the XP people say.

This is fine as far as it goes, but common tools for abstraction aren't powerful enough to capture all possible abstractions. For example, suppose that you want to write some Python code that opens a file, processes it, and then closes the file before returning the result, with the caveat that the file must get closed, even if the code that does a computation raises an exception. The code to do this looks like this:


file = open('/usr/dict/words')
try:
process(file)
finally:
file.close()


This little try/finally block is just so much boilerplate -- it has to be written every single time you open a file. This isn't so bad in this particular case, but it gets less and less maintainable the more complex your cleanup protocol is, because you have to repeat the pattern everywhere you use it. The probability of getting it right everywhere rises exponentially with the number of uses.

You could theoretically code it up as a higher-order function, but a) that doesn't work in languages without HOFs, and b) it's generally pretty yucky looking.

The solution, in languages with macros, is to try and wrap these patterns syntactically. For example, Dylan has a macro called with-open-file that is used like this:


with-open-file(file = "/usr/dict/words")
process(file);
end with-open-file;


This is defined with a macro:


define macro with-open-file
{
with-open-file (?stream:variable = ?namestring:expression,
#rest ?parameters:expression)
?:body
end
}
=> {
let stream = #f;
block ()
stream := make(<file-stream>, locator: ?namestring, ?parameters);
let ?stream = stream;
?body;
cleanup
if (stream)
close(stream);
end if;
end block
}
end macro with-open-file;


The reason this is nice is partly because it's marginally more terse, but mostly because the cleanup sequence is defined in only one place. The probability of making an error is constant in the number of uses, and once made it can be easily localized and fixed. But even if your language doesn't have macros, it's WELL worth looking for common patterns and adding them as library functions/new syntax. Eliminating redundancy eliminates errors.
New Macros
Maybe I've had too much experience with m4 and C-style macros, but whenever I think a macro is the best way to do something, it usually comes back and bites me in the butt.
Famous last RPG quotes: "I'll just shoot this fireball down the dungeon passageway..."
New Not just macros!
If you've had experience with C and M4 macros, you've had too much experience with them. :) They just suck. The various branches of the Lisp family tree -- Common Lisp, Dylan, Scheme -- all have macro systems that don't cause crippling spinal trauma. But macros are really besides the point: they came up mostly because I wanted an example of a kind of abstraction that regular procedural abstraction doesn't work all that great at, and not surprisingly the obvious examples come from languages that have non-procedural ways of building abstractions. If I have the tools to capture an abstraction, I'll be more likely to keep an eye out for them.

For example, I really like Perl 6's built-in grammar support. Writing recursive descent parsers by hand isn't actually hard, per se. It's just that the code comes in a very stereotyped form and it's a great idea to sugar away the repetitious bits, so that when you are debugging you don't have to first figure out whether an error happened because you made a conceptual error or just because you mistyped some boilerplate.

Another example is Ocaml's module system. It is, honestly, the closest I have ever seen a language come to making software out of interchangeable parts. The basic idea is to make linking part of the module language: you can write code that is parameterized on the modules it uses. Parameterized modules (called functors) take some modules as arguments, and then build a module. For example, you can build a case-insensitive string map like this:


module CaseFoldCmp =
struct
type t = string
let compare a b =
compare (String.lowercase a) (String.lowercase b)
end
\t
module CaseFoldingMap = Map.Make(CaseFoldCmp)


And just like that, you have a case-folding map module that has all of the operations of the standard library's Map module. This is very cool.
New Re: Not just macros!
To me, that's not clear at all. Where did A and B come from? Vapor? Assumed arguments to functions? Some sort of object-oriented stuff that I haven't wrapped my mind around yet?
New Re: Not just macros!
That's a function definition -- a and b are the arguments. Caml has a funny syntax. Here's an annotated version, with comments (* like this *).

 
module StringCmp =
struct
type t = string (* This is like a C typedef *)

(* This is a function definition. 'let compare a b = <foo>'
declares a function that takes two arguments a and b. The <foo>
expression after the = is the function body. Function calls don't
use the 'f(x, y)' syntax. Instead, Caml uses simple
juxtaposition: 'f x y' instead. *)

let compare a b =
compare (String.lowercase a) (String.lowercase b)

(* This call to compare calls the generic comparison function, and
rebinds it locally in this module. (String.lowercase s) will return
a lowercase version. So what we are doing is lowercasing both args
and then calling the generic compare, to get a case-insensitive
comparison.
*)
end
New What "prevailing style of thought" are you talking about?
The quote in question indicates that the method of last resort for forming a reusable component is a macro - and that making a reusable component is a good thing to do, even if you have to go that far.

That macros are a method of last resort for achieving reusibility seems to me to be common sense. That reusable components are a Good Thing is the prevailing recommendation (if not practice) that I have seen. So the quote follows the prevailing style of thought, it just takes it farther than mainstream languages typically allow.

Did you misinterpret the quote, or am I missing something?

Thanks,
Ben
"... I couldn't see how anyone could be educated by this self-propagating system in which people pass exams, teach others to pass exams, but nobody knows anything."
--Richard Feynman
New Speaking for myself...
I was going to write something along the same lines as he did. I guess it comes down to the words "reflect only the problem":

When I see patterns in my programs, I consider it a sign of trouble. The shape of a program should reflect only the problem it needs to solve. Any other regularity in the code is a sign, to me at least, that I'm using abstractions that aren't powerful enough-- often that I'm generating by hand the expansions of some macro that I need to write.


First, because the statement souds incredibly naive about the development cycle, as if "the problem" were some Ideal outside of time and space which we're supposed to model. Real programs shift while they're being built, and even in pristine environments where they don't, they certainly get pressure to change after they're deployed. When I read Gamma, et al, I certainly get the impression that they see Patterns as a way to prepare for this, much more so than any ideas about application logic problem->solution cookbooks.

Second, it sounds like the quote is not addressing what we call Design Patterns at all (which are commonalities between different programs), but instead vanilla proceduralism, addressing commonalities inside a single program. Substitute "application", "module", whatever for "program", the point is the same. There are tons of programmers who refactor redundant code all day and have no idea what an abstract factory is or where it might be a Good Idea. In other words, I don't see very many of even those few original Patterns in Gamma, et al, being candidates for a Neat New Macro; they don't operate on that level. Yes, we can make Iterators our pattern-whipping-boy, but the fact that certain language designers saw fit to standardize them in syntax does not, to me, diminish its existence as a Pattern. If anything, it encourages me that our industry is "getting somewhere" in the design space, finally.
---------------------------------
Many fears are born of stupidity and ignorance -
Which you should be feeding with rumour and generalisation.
BOfH, 2002 "Episode" 10
New Re: Speaking for myself...
When Paul Graham talks about patterns in his code, he means patterns up to and including "object-oriented programming." This isn't hyperbole, either, as CLOS -- the Common Lisp Object System, and one of the candidates for World's Most Powerful OO System -- was originally implemented as a set of macros on top of Lisp. He wrote a book, On Lisp, which is generally regarded as the reference on the use (and abuse) of the CL macro system. Happily, he has put it online. You can read it at: [link|http://www.paulgraham.com/onlisp.html| [link|http://www.paulgraham.com/onlisp.html|http://www.paulgraham.com/onlisp.html] ].
New Paul Graham on OO
(* When Paul Graham talks about patterns in his code, he means patterns up to and including "object-oriented programming." This isn't hyperbole, either, as CLOS -- the Common Lisp Object System, and one of the candidates for World's Most Powerful OO System *)

Paul Graham is not particularly hip about OO. He is leaving it out of his LISP-remake, ARC:

[link|http://www.paulgraham.com/noop.html|
[link|http://www.paulgraham.com/noop.html|http://www.paulgraham.com/noop.html]]


Stepanov, who worked on STL, is another "respected" person who has bashed OO, BTW, complaining about its IS-A view of a HAS-A world.

________________
oop.ismad.com
New Note his first criticism
A large part of his reason for not needing OO is access to and familiarity with more powerful programming techniques.

Techniques that I suspect would be even less to your liking than OO.

Cheers,
Ben
"... I couldn't see how anyone could be educated by this self-propagating system in which people pass exams, teach others to pass exams, but nobody knows anything."
--Richard Feynman
New Elitist claim?
(* A large part of his reason for not needing OO is access to and familiarity with more powerful programming techniques. Techniques that I suspect would be even less to your liking than OO. *)

"More powerful"?

Such as?

I admit that in the past I have fussed about closures, but agree that they do seem to simplify code by roughly 2 to 5 percent (my rough guestimate). Nothing revolutionary though.

You are also implying that OO is for "middle of the road" programmers.

An odd response it was. (Damned Yoda syntax keeps popping up in my head after seeing "Clones" the other day.)
________________
oop.ismad.com
New Don't guess, measure!
Look at your programs and count the number of times you use higher-order functions. I just looked at the code I wrote today in Ocaml. There's about 450 lines of code, in 29 functions.[*] 20 of those 29 use higher-order functions (ie, functions as values) in some way. 15 of the 20 that use higher-order functions explicitly construct closures. The other 5 simply take functions as arguments. That's way more than 2-5%. One of the reasons the percentage is so high is because I tend to use folds (like map or reduce in Python) instead of explicit recursion or looping. Eliminating explicit loops means I can't get the pattern of iteration wrong -- which makes a whole class of bugs impossible.

Anyway, I think Paul Graham is wrong about the usefullness of OO. But when you write the language, you get to decide what goes in it. That's why I'm writing my own language instead of complaining about Arc. :)

[*] Yeah, I know I should refactor -- 15 lines/function is on the high side. But this is pure throwaway exploratory code. Once I figure out how to do it at all, I'll make the code good.
New Simplify
(* Eliminating explicit loops means I can't get the pattern of iteration wrong -- which makes a whole class of bugs impossible. *)

Yes, but messing up loops may only be a small portion of total errors.

Good API designs can reduce loop complexity. For example, looping thru a DB result set (or cursor) can be as simple as:

rs = openRS([criteria])
while getNext(rs) {
  [loop contents]
}

What is there to screw up here?

Again, I am not hellbent against closures, but I think they are overrated. They confuse newbies and complicate the language, adding only a marginal improvement.

If you have a "killer example" of closures doing something realistic far better than traditional approaches, I would like to see it.

(Perhaps one could argue that closures help clean up or wrap bad API's.)
________________
oop.ismad.com
New Re: Simplify
You wrote:
> Good API designs can reduce loop complexity. For example, looping thru a
> DB result set (or cursor) can be as simple as:
>
> rs = openRS([criteria])
> while getNext(rs) {
>   [loop contents]
> }
>
> What is there to screw up here?

For one thing, you haven't closed the cursor. :)

This is a perfect example of why abstracting common patterns of iteration into a higher-level API is a good idea. Namely, you need to get the fold function correct once, and then every future use of it will be correct. In this case, if you had an iteration function available you would not have accidentally created a resource leak.

People -- all people -- are bad at repetition and detail work. If we have to repeat even a trivial task, then we will screw it up. For a simple example, try quickly counting from 1 to 300 out loud without screwing up. I just tried it, and got up to 114 before stumbling over my words. Now consider that this task is much easier than writing even the simplest computer program.

This is why I am so hell-bent on abstracting the common patterns in my code. I know that I suck at detail work. Closures are a good thing because they let me build my program out of tested, interchangeable parts.
New Depends on the language
In many languages, when the database handle goes out of scope, it closes the cursor for you and cleans up. No leak.

OTOH when you get used to that and then need to work in an environment that doesn't have it, the adjustment is painful. I am even worse at detail work I have gotten out of the habit of doing... :-/

Cheers,
Ben
"... I couldn't see how anyone could be educated by this self-propagating system in which people pass exams, teach others to pass exams, but nobody knows anything."
--Richard Feynman
New This is why I prefer PHP to C... :-)

"Ah. One of the difficult questions."

New You can judge that for yourself
Go [link|http://www.paulgraham.com/onlisptext.html|download] a book of his and let us know when you have read enough of it to decide whether or not you like the way that he uses macros and closures.

Cheers,
Ben
"... I couldn't see how anyone could be educated by this self-propagating system in which people pass exams, teach others to pass exams, but nobody knows anything."
--Richard Feynman
New You can judge that for yourself
Go [link|http://www.paulgraham.com/onlisptext.html|download] a book of his and let us know when you have read enough of it to decide whether or not you like the way that he uses macros and closures.

Cheers,
Ben
"... I couldn't see how anyone could be educated by this self-propagating system in which people pass exams, teach others to pass exams, but nobody knows anything."
--Richard Feynman
New HAS-A is orthogonal to OO
As you have been told repeatedly.
Regards,

-scott anderson

"Welcome to Rivendell, Mr. Anderson..."
New Guess you gotta...
Whip those Shapes thinga-ma-bobs out again.

That one in sed... just kills me.

I wondered why I was tan on my RIGHT side and not my left side after the trip...

greg, curley95@attbi.com -- REMEMBER ED CURRY!!!
New Muah.
Regards,

-scott anderson

"Welcome to Rivendell, Mr. Anderson..."
New It is more common in OO
(* HAS-A is orthogonal to OO, As you have been told repeatedly. *)

More OO newbies over-use IS-A than p/r newbies.

Further, the less IS-A you use in OO designs, the less OO it is. (Of course this gets into what the definition of OO is, which even OO fans cannot agree on.)



________________
oop.ismad.com
New Don't go there. You will regret it.

"Ah. One of the difficult questions."

New What is wrong with a little romp with a cute harmless troll?
________________
oop.ismad.com
New Been down this road before...
and got sucky mileage with the Bryce-mobile.

I repeat: IS-A/HAS-A discussions are orthogonal to OO.

Any claims of suitability, "what everyone does", or resorting to your own definitions are merely hand-waving on your part, and do not change this.
Regards,

-scott anderson

"Welcome to Rivendell, Mr. Anderson..."
New Defining definition
(* Any claims of suitability, "what everyone does", or resorting to your own definitions are merely hand-waving on your part, and do not change this. *)

I hate to tell you this, but "what everyone does" is pretty much how words get defined. You are not the Sole Oracle of Definitions.

If there is no bearing on common opinion, then why should I accept your definition over mine anyhow?

________________
oop.ismad.com
New Mister...
Egads the man instantiated classes in SED for chris-sake...

How much more INANNE can you get than that.

It shows that OO is just a way to classify and flow the program... not the be all, end all you obviously think OTHERS think it is.

We can (given a bit of time and effort from somone other than you) use XBASE in an OO way. Easily you fail to understand the principle of the matter. Just because someone chooses to use OO does not mean thier programming is in anyway shape or form inferior... OR superior either.

What it does mean, there is a frame of work to use, and a framework to construct by, and framework to reference, a framework to work within, a framework to make other frameworks, a framworke to embbed another framework, a framework to be used in the wrong way, a framewaork to be ignored if they so choose.

That last statement, applies to nearly EVERYTHING built in this world, be it digital, analog or physical.

We understand, you believe OO is not the way of the world. I believe you are just a person trying to force us to your way of thinking... as my favorite saying goes...

"YOU DON'T UNDERSTAND!"


greg, curley95@attbi.com -- REMEMBER ED CURRY!!!
New Frameworks and votes

There are frameworks for p/r also. They just tend to look and work differently.

(* We understand, you believe OO is not the way of the world. I believe you are just a person trying to force us to your way of thinking *)

That is exactly what OO has done to the industry, forced everybody into it wether they like it or not. Javatization has ruined the field.

There is no survey that shows most programmers prefer OO. Heck, many "high end OO experts" claim that most production programmers don't even know what OO is.
________________
oop.ismad.com
New Now...
That we understand each other... Bryce leave it at that...

I know that frameworks are in everything that are programmed... It is just a matter of taste in the way you do things...

You can really(technically feasible but not reccomended)) even do assembly in an OO way... just like you can do it the p/r way...

Just because you don;t like OO, doesn't mean NO-ONE should... And just because OO "bigots" Like Scott Anderson (sorry for the dig there Scott), he shouldn;t expect people to forego anything OTHER than OO...

So like I am asking, OO is just as good and just as bad as ANY other way of programming... they all have thier goods and bads... You just learn to deal with them the way you prefer...

That is really what we have been trying to come to the agreement on. You sometimes tend to make this an all or nothing arguement, which of course it cannot be.

Thanks for the millions of keystrokes on this subject... lets wear out the ketboards on something else... Shall we?

greg, curley95@attbi.com -- REMEMBER ED CURRY!!!
New Erect Ape
(* Just because you don;t like OO, doesn't mean NO-ONE should *)

1. I am saying that OOP is currently over-hyped and forced on too many programmers in practice. There are fewer places to get to get away from it.

2. OO fans here still seem to think that OOP is *objectively* better, and that those who don't like it are flawed upstairs not to see that. CRC called OOP "a natural and logical extension to structured programming" (paraphrased) as if it is an upright-walking ape.

If the hype about OO died down and more p/r techniques and API's came into the mix, then I would not be fussing nearly as much.

________________
oop.ismad.com
New Hey.. I feel the *same* way about the tyranny of
Organized Religions\ufffd - and especially re the secondary effects, all so neatly chronicled by now.

But since this mindset leads to the periodic heaped dead burned bodies (in God's Name), I tend to think about the topic as not.. a mere bagatelle. But I don't expect the momentum to cease any time soon - not even as WW-The Last opens. 'We' aren't ready to break this habit, no matter the Next body-count. Or the Next.

Maybe it's ditto re Your fav Windmill? (however a much more trivial ultimate decision, it would seem.) Hell, maybe *none* of this stuff is Real?






Ashton Quixote Productions LLC
Tell us Your Troubles and we'll explain how it was that You Caused Them.. cha cha cha.
New What we need are more DISorganized religions? Hmmm
________________
oop.ismad.com
     TPC slides are coming online - (ben_tilly) - (43)
         Problems with patterns - (JayMehaffey) - (42)
             Re: Problems with patterns - (Dominus) - (7)
                 Fixing existing languages... - (admin)
                 Re: Problems with patterns - (JayMehaffey)
                 Context shouldn't be C++ - (tuberculosis)
                 Re: Problems with patterns - (neelk) - (1)
                     That is what Perl 6 is about :-) - (ben_tilly)
                 Please don't remove the slides - (ben_tilly)
                 Patterns and languages. - (Arkadiy)
             The iterators complaint is truncated, not misguided - (ben_tilly) - (33)
                 Reusable components? - (wharris2) - (32)
                     Re: Reusable components? - (neelk) - (4)
                         Macros - (wharris2) - (3)
                             Not just macros! - (neelk) - (2)
                                 Re: Not just macros! - (wharris2) - (1)
                                     Re: Not just macros! - (neelk)
                     What "prevailing style of thought" are you talking about? - (ben_tilly) - (26)
                         Speaking for myself... - (tseliot) - (25)
                             Re: Speaking for myself... - (neelk) - (24)
                                 Paul Graham on OO - (tablizer) - (23)
                                     Note his first criticism - (ben_tilly) - (8)
                                         Elitist claim? - (tablizer) - (7)
                                             Don't guess, measure! - (neelk) - (4)
                                                 Simplify - (tablizer) - (3)
                                                     Re: Simplify - (neelk) - (2)
                                                         Depends on the language - (ben_tilly) - (1)
                                                             This is why I prefer PHP to C... :-) -NT - (static)
                                             You can judge that for yourself - (ben_tilly)
                                             You can judge that for yourself - (ben_tilly)
                                     HAS-A is orthogonal to OO - (admin) - (13)
                                         Guess you gotta... - (folkert) - (1)
                                             Muah. -NT - (admin)
                                         It is more common in OO - (tablizer) - (10)
                                             Don't go there. You will regret it. -NT - (static) - (1)
                                                 What is wrong with a little romp with a cute harmless troll? -NT - (tablizer)
                                             Been down this road before... - (admin) - (7)
                                                 Defining definition - (tablizer) - (6)
                                                     Mister... - (folkert) - (5)
                                                         Frameworks and votes - (tablizer) - (4)
                                                             Now... - (folkert) - (3)
                                                                 Erect Ape - (tablizer) - (2)
                                                                     Hey.. I feel the *same* way about the tyranny of - (Ashton) - (1)
                                                                         What we need are more DISorganized religions? Hmmm -NT - (tablizer)

Hello, boys and girls, this is your old pal Stinky Wizzleteats!
98 ms