On Mon, 12 Jul 2010 23:45:59 Bruce & Breeanna Rennie wrote:
>   To all interested,
> 
> The problem lies in using the conjunction & directly between the if
> expression and the following expression.
> 
> If the If expression is surrounded by {} then the following
>  expression is evaluated when the if does not produce &fail
> 
> Hence
> 
> if test then { expression1} else { &fail } & expression2
> 
> doesn't evaluate the expression2 if test produces a result
> 
> however
> 
> {if test then { expression1} else {&fail}} & expression2
> 
> does evaluate expression2 when test succeeds
> 

If that's the source of your problem then it's merely a precedence 
issue. if/then/else is lower than & so your 1st sample is like

if test then { expression1} else ( { &fail } & expression2 )

As a finer point, your assertion "does evaluate expression2 when test 
succeeds" should actually be: "does evaluate expression2 when test AND 
expression1 succeeds."

The point I'm making is, the value of if/then/else is the value of 
whatever expression is evaluated - ie the { expression1 } or the { &fail 
}

since { &fail } yields no value the IF yields no value and so 
expression2 won't be executed.

A further simplification:

    if test then expr

is identical to

    if test then expr else &fail

since the missing else part implicitly means a failure.

So ................

many of us would probably write (for your sample here)

test & expression1 & expression2

Looking at your original sample, I have the following comments:

wrapping in { } is not necessary - for example

             {
# this is not
                 write("In MatchComment()")
             } &

although it is a good way to "place-hold" a block if you want to slip in 
debugging statements as you've done a few lines earlier.
wrapping. Plain old parentheses are fine for this duty; unlike most 
languages, even things that look like control structures are actually 
just expressions, so you can wrap if, case, break, every, etc etc in 
parentheses just to control the precedence.

Similarly, I don't see the point of

                 {
                     found.Pop()
                 }

a few lines into the code

The do-clause is optional on while, so your

    do { } could be removed

Now that I see where you're coming from, the following

                         if found.Push(not MatchEndOfLine()) then {
                             {
                                 found.Pop()
                             }
                         } else {
&fail
                         } &
                         if found.Push(MatchDOT()) then {
                             {
                                 found.Pop()
                             }
                         } else {
&fail
                         }

would reduce (in steps) to

                         ( if found.Push(not MatchEndOfLine()) then {
                                 found.Pop()
                         } ) &
                         if found.Push(MatchDOT()) then {
                                 found.Pop()
                         }

and finally

    found.Push(not MatchEndOfLine()) &
    found.Pop() &
    found.Push(MatchDOT()) &
    found.Pop()

So I guess the entire procedure would reduce to

procedure MatchComment()
    return (
        found.Push(tab(match("#"))) &
        found.Pop() &
        write("First Part of MatchComment()") &
        write("In MatchComment()") &
        while write(
            found.Push(not MatchEndOfLine()) &
            found.Pop() &
            found.Push(MatchDOT()) &
            found.Pop()
        ) | 1&    # related to my guess below

        # not sure what this is for - to yield a success
        # after WHILE finally fails?
        &pos  &
        found.Push(MatchEndOfLine()) & found.Pop()
    )
end

Sooooo !

my guess at a rewrite:

procedure MatchComment()
    # I like to short-circuit the flow and leave
    # when it's clean like this
    if not found.Push(tab(match("#"))) then
        fail
    # pop the matched bit to keep the stack clean
    found.Pop()

    write("First Part of MatchComment()")
    write("In MatchComment()")

    # I'm guessing a consumer loop so let it run
    while write(
        found.Push(not MatchEndOfLine()) &
        found.Pop() &
        found.Push(MatchDOT()) &
        found.Pop()
    )

    return found.Push(MatchEndOfLine()) & found.Pop()
end

Since you seem to be discarding the matched bits because it's a comment, 
I guess this specific procedure could be simplified again:

procedure MatchComment()
    # I like to short-circuit the flow and leave
    # when it's clean like this
    if not ="#" then    # =X is a synonym for tab(match(X))
        fail

    write("First Part of MatchComment()")
    write("In MatchComment()")

    while not MatchEndOfLine() do
        write(MatchDOT())

    return MatchEndOfLine()
end

which reads quite succinctly even with the debugging writes.



------------------------------------------------------------------------------
This SF.net email is sponsored by Sprint
What will you do first with EVO, the first 4G phone?
Visit sprint.com/first -- http://p.sf.net/sfu/sprint-com-first
_______________________________________________
Unicon-group mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/unicon-group

Reply via email to