TomDLux has asked for the wisdom of the Perl Monks concerning the following question:

On page 7 of Exegesis 6, Damian describes how currying can rescue legacy code when subroutines are updated.The idea is that an existing routine:

sub part (Selector $is_sheep, *@data ) returns List of Pair

is modified by the addition of optional parameter in the middle of the signature.

sub part (Selector $is_sheep, Str ?@labels is dim(2) = <<sheep goats>>, *@data ) returns List of Pair

If you have existing code which invokes the routine with a selector and with data which does not satisfy the description, "array of two strings", you're fine. But otherwise, or if you have code which uses a dynamic data set, your data will be mistaken for a set of labels, and the function will be invokes with no data.

Damian suggests using currying to provide backward compatability. Currying, for those who don't know, has nothing to do with the star of Rocky Horror, but involves supplying one parameter to a routine, generating a routine which takes fewer parameters. A simple example, multiplication takes two arguments; currying multiplication with the argument '2' generates a function double. Instead of taking two parameters and multiplying them together, it takes one parameter and retuns 2 times that value.

So now for my question:

Damian suggests using currying:

my &part ::= &List::Part::part.assuming(labels => <<sheep goats>>)
to make the existing code compatible with the new structure of the routine. If you change the name of the routine, the curry provides a backwards compatible path, and new code can use the new name. But a ,em>realroutine invoking the new routine could achieve the same result.

On the other hand, putting my in the main script will not have any effect in the package, will it?

Awaiting instant translation ...

--
TTTATCGGTCGTTATATAGATGTTTGCA

Replies are listed 'Best First'.
Re: Perl 6 Exegesis 6 pg 7
by adrianh (Chancellor) on Aug 07, 2003 at 06:30 UTC
    But a real routine invoking the new routine could achieve the same result.

    Of course. Currying is just a shortcut.

    On the other hand, putting my in the main script will not have any effect in the package, will it?

    I think that's the point :-)

    In Damian's example the List::Part::part() function is non-upwardly compatable with earlier versions because of the addition of the parameter.

    The problem is - how do we make legacy code that calls the old-style part() use the new-style part()?

    One option would be to go through them by hand and alter the calls to part() appropriately.

    Instead, we can add a single line that creates a lexically scoped subroutine that curries in the old default label arguments - so the calls to the old-style part() will continue to work.

    Make sense?

      And that's precisely my question, where does that one line go?

      If you put it in the module, you would disable the new version for all scripts that access the module, new or old. ( Besides, you wouldn't need that List::Part::part.assuming magic, ,you could just write a wrapper routine. )

      If you modify the main() of each old script: it's a lot of work; how do you know you got them all?; since you're using my, the currying will be active in the file where you put the currying, which is fine for a one-file program, but what about more complex things?

      --
      TTTATCGGTCGTTATATAGATGTTTGCA

        And that's precisely my question, where does that one line go?

        In the modules/scripts that use the old API.

        Besides, you wouldn't need that List::Part::part.assuming magic, ,you could just write a wrapper routine.

        You don't have to use a curried subroutine - but it would seem a very natural idiom to me. You're taking an existing subroutine and freezing one of its arguments. Exactly what currying does.

        Yes you could write a wrapper subroutine but currying seems more natural to me (perhaps because I've used languages before where currying is common).

        If you modify the main() of each old script: it's a lot of work; how do you know you got them all?; since you're using my, the currying will be active in the file where you put the currying, which is fine for a one-file program, but what about more complex things?

        There isn't an easy way of doing it ;-) It was just (IMO) a way for TheDamian to demo currying in a vaguely sane context.

        You are searching for something that isn't there.

        This is just example code to show what currying is able to do, but maybe not the "proper" way to write code. My reading is that the curry goes into each old script. Let's assume there is only one or two. In real life code, you would not want to change the way a library function gets called, you would instead add a new library function that is separate from the older one, so that old code will not require changes. But then the Exegesis would not explain how currying works, and that was the whole point of talking about it in the first place.

Re: Perl 6 Exegesis 6 pg 7
by bobn (Chaplain) on Aug 07, 2003 at 06:12 UTC

    (bye-bye, XP) But every time I see explanations of Perl 6, all I can think is:

    1. If I was that into B&D I'd use Java or C++
    2. I'm going to use Perl 5 for a looong time.
    Someday maybe I'll find myself in the problem domain where all this is needed or cool, but it just looks like overkill to me right now.

    --Bob Niederman, http://bob-n.com

      All of these things are optional, just like everything in Perl 5 you don't use or understand right now. If you want Perl 6 to spank you, you'll have to ask for it. Try getting the same consideration from Java or C++.

      If I was that into B&D I'd use Java or C++

      Remember folks. All Perl6 B&D is optional. You only need to use it if you find it useful.

      I'm going to use Perl 5 for a looong time.

      Me to. But only because its going to be a long time before Perl6 hits the streets and becomes adopted in any major way :-)

      You'll get over it. I felt the same way at first but I'm getting used to it. After reading the last Exegesis explaining the integration of junctions into the language, I'd say Perl6's B&D will be of the playful variety, not the hardcore S&M imposed by Certain Other Languages. I'm excitedly looking forward to an expansion of my, uhm, practices.

      Makeshifts last the longest.

      which java !? :")
      U didnt read the Exegis then... all this is optional.. i.e. it is for us not for U :")
      One of the ideas behind the curring and <==, ==> is to extend the usage of already working code... they will be a real timesaver..
      Think a liitle bit !!! What happen when U have to extend other programmers code, which u havent seen till now.. I think this is the best way to start reworking the code and preseve it working.. until u figure out what happens..