in reply to Using functional abstraction in Perl

But somehow, I see too much "plain" code around. Code that accesses these data structures directly, assuming their implementation is fixed.

I'd argue that Perl's powerful standard data structures are a good thing and using them "plainly" is usually the best option. The semantics and syntax are well-known. You can look at someone's code, see $values{one} = "somevalue", and almost always know exactly what that will do (of course things are a bit more complicated with tie in the picture, but let's just ignore that for now).

If everybody always abstracted this kind of thing away in a function, that certainty would rapidly disappear. Sure, you could reasonably assume that store_value(one => "somevalue") is doing something very hash-like. But why should people have to assume, when you can use the direct approach and ensure they will know?

In my opinion, such code will be much more understandable, easier to debug and more fun to write.

Perhaps this would make Perl easier to understand and more fun to write for Lisp programmers, but hashes are fundamental things to Perl programmers. They do not usually need to be abstracted away. When they do, it should only be for a good reason. I have to wonder if you would also rather we avoid using scalars and arrays directly, because they could be abstracted into functions that do the same thing?

Replies are listed 'Best First'.
Re^2: Using functional abstraction in Perl
by spurperl (Priest) on Jul 02, 2005 at 09:16 UTC
    The has is only an example, a demonstration of a broader concept. I tried to make it as simple as possible, but often this approach is used to hide more complex data structures than plain hashes. For example, I was referring to HoAoHs or something like that.

    It's OK to use hashes directly. It's not OK, IMHO to use HoAoHs directly, but better abstract this usage away.

    Even in the small example I presented, the implementer of the binding abstraction may decide that (for some reason) it will be better done with an array or a tree (perhaps the typical data will make it more efficient). The abstraction allows to hide it from the "user code".

      The has is only an example, a demonstration of a broader concept.

      Fair enough, but as you can probably see by the replies, your broader concept got lost in the example.

      It's OK to use hashes directly. It's not OK, IMHO to use HoAoHs directly, but better abstract this usage away.

      That would be more reasonable. I certainly would understand more readily if I saw code that did this. Though, I'm still not buying it 100%. I see a lot of code that handles these type of data structures "raw", and I don't think it's really that bad. For instance, I wouldn't blink twice if I saw something like:

      my %thread = ( title => 'Using functional abstraction in Perl', participants => [ { nickname => 'revdiablo', status => 'replying', replies => 3, }, { nickname => 'spurperl', status => 'unknown', replies => 4, }, ... ], ); do_something(with => %thread);
      the implementer of the binding abstraction may decide that (for some reason) it will be better done with an array or a tree

      As BrowserUk aptly explained, this type of thing can be abstracted in a different way in Perl. Rather than forcing users to make function calls that do hash-like things, we can have hashes that trigger function calls. I'm not saying tie is the right option in every case, but it's certainly a nice alternative.

      A quick side note, related to the other thread about OO. I'd like to point out that -- though you may not be willing to accept the terminology -- what you're doing is very OO-ish. You're passing a chunk of data (an "object") around to various functions ("methods"). This is essentially how OO works in Perl; the object is passed as the first argument to the methods. (Of course, there's no inheritance or polymorphism here, but those are only another aspect of OO, not the defining characteristics.)