Beefy Boxes and Bandwidth Generously Provided by pair Networks
go ahead... be a heretic
 
PerlMonks  

Re: Pronoun Programming

by fergal (Chaplain)
on Feb 04, 2008 at 23:49 UTC ( [id://666151]=note: print w/replies, xml ) Need Help??


in reply to Pronoun Programming

Something close to what you want exists but not in Perl. Before that though, there are problems with what you want. Consider

delete $log_count{$a--} if it=0;
should $a get decremented? Decremented twice? Only decremented when the condition is true?. The later is what you'd really want but is basically impossible because you have to undo side-effects. That's not so bad for decrement but what about
delete $hash{some_destructive_function()} if it==0

That said, what you're asking for is very close to something that already exists, called "anaphoric if". It can be achieved with macros in a language like lisp and it's implementation is described in the book "On Lisp" by Paul Graham. Even if you have no intention of every writing a line of Lisp, that book is well worth reading and available for free (it is not however an introduction to Lisp and you'll need to know a certain amount before it makes any sense).

Let's imagine we had macros in Perl - real ones, like Lisp macros (or maybe Perl6, I haven't really looked), not the nasty hackish macros of the C preprocessors that are basically just text-mungers. Real macros allow us to pull code apart and join it back together again safely.

I'm going to pretend that the syntax allows for code quotes - so

$code = c{ $a = 1; $b=2; print $a + $b}
assigns into $code a piece of parsed code. I'm also going to imagine that $$name gets replaced with the code contained in $name. So I can do something like
sub printer { my $expr = shift; return c{ sub { my $x = shift; my $y = shift; print $$expr; } } }

printer takes as an argument an expression and returns a subroutine that applies that expression to its 2 arguments and prints them out. So

$adder_code = printer( c{ $x + $y } } $adder_sub = compile($adder_code) &{$adder_sub}(1, 2) # prints 3 $pythago_code = printer( c{ sqrt($x**2 + $y**2) } } $pythago_sub = compile($pythago_code) &{$pythago_sub}(3, 4) # prints 5

So that's code quotes. For real macros, you need them to blend in, you don't want to have to insert code quotes all over the place when you're using them. So we'll say that if something is declared a macro it gets passed it's arguments as code, they do not get evaluated. Also we don't have to call compile, the resulting code gets compiled right there and replaces the macro (much like C macros but far more powerful because we can do lots more than just cutting and pasting text). So if we change the above to be

macro printer { my $expr = shift; return c{ sub { my $x = shift; my $y = shift; print $$expr; } } }
then we can drop the c{} stuff and just say
# printer is a macro, so $x + $y is not evaluated $adder_sub = printer( $x + $y } &{$adder_sub}(1, 2) # prints 3

So what's this got to do with anaphoric ifs? Well,

macro aif { my $condition = shift; my $body = shift; return c{ { my $it = $$condition; if ($it) { $$body; } } } }
and now I can write something like
aif(number_of_widgets(), { print "there are $it widgets\n"; } )

You could go on to implement what you are looking for originally too but it would have all the pitfalls of double evaluation of the expression.

aif could actually be implemented with just C-style macros but the more interesting macros in On Lisp cannot.

You can also define awhile and some other useful anaphorisms

Finally, I suppose you could write something that examines the expression more closely and understands hashes and deletes and does exactly what you want and does it correctly but that's a lot of understanding to build in

Replies are listed 'Best First'.
Re^2: Pronoun Programming
by dragonchild (Archbishop) on Feb 05, 2008 at 04:35 UTC
    aif could actually be implemented with just C-style macros but the more interesting macros in On Lisp cannot.

    This implies that a source filter could be used here to create aif().


    My criteria for good software:
    1. Does it work?
    2. Can someone else come in, make a change, and be reasonably certain no bugs were introduced?

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://666151]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others chanting in the Monastery: (6)
As of 2024-04-25 08:04 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found