A question on joy syntax.
Rahul — 2007-03-01 20:17:00
I have been looking through the joy papers, and have
this confusion:
The help on ifte says:
ifte [B] [T] [F] -> ...
Executes B. If that yields true, then executes T
else executes F.
Now the help on = says:
= X Y -> B
Either both X and Y are numeric or both are strings
or symbols. Tests whether X equal to Y. Also supports
float.
I assumed that '=' will consume two arguments off the stack,
and leave the true or false on top.
the joy interp seems to support this.
1 2 = .
false
.
Now, if I use the same inside an ifte
1 5 [1 =] [dup *] [dup +] ifte .
10
The doubt I have is this:
as soon as [1 =] is executed, I would expect '5' off the stack,
so the [dup +] should have actually found '1' on the stack and given
me 2.
I checked this too: which seems to do fine.
5 [true] [dup *] [dup +] ifte .
25
Is there a reason for this? Is for some reason the stack
invariant when executing ifte condition?
The below seems to verify it.
5 6 [pop 1 =] [dup *] [dup +] ifte .
12
.
5
But I cant find any info on this.
The other quoted programs does not seem to share the invariant stack
behavior:
================================
i [P] -> ...
Executes P. So, [P] i == P.
1 2 [1 +] i .
3
.
1
Could some one please explain why this is so? or guide me to the
docs that explains it?
rahul.
William Tanksley, Jr — 2007-03-02 05:15:55
Rahul <
blufox@...> wrote:
> I have been looking through the joy papers, and have
> this confusion:
> 1 5 [1 =] [dup *] [dup +] ifte .
> 10
> The doubt I have is this:
> as soon as [1 =] is executed, I would expect '5' off the stack,
> so the [dup +] should have actually found '1' on the stack and given
> me 2.
Yup. Me too. But that's not what Joy does; some of Joy's combinators
save the stack's state when they're performing certain types of
actions. You simply have to learn which ones do it and which ones
don't.
Sometimes this is very handy. Sometimes it's annoying.
> rahul.
-Billy
Taoufik Dachraoui — 2007-03-03 10:59:01
I tried to define ifte as it is implemented in joy1 and I found this:
[T] [A] [B]
ifte == [[[stack] dip] dip
[dip swap] dip] dip #save stack and run T
choice [unstack] dip i; # restore stack and choose
between A and B
The stack is saved before the execution of [T] and restored before the
execution of [A] or [B]. The test in this case is non destructive;
the stack
is unchanged before choosing between A and B.
The way you implmented ifte is as follows:
[T] [A] [B]
ifte == [[i] dip] dip #run T
choice i; # choose between A and B
Obviously your implementation is faster, but the test in this case
is destructive; the stack can be modified greatly depending on T.
Is it more difficult or easier to reason with destructive tests?
Taoufik
On Mar 1, 2007, at 9:17 PM, Rahul wrote:
> I have been looking through the joy papers, and have
> this confusion:
>
> The help on ifte says:
>
> ifte [B] [T] [F] -> ...
> Executes B. If that yields true, then executes T
> else executes F.
>
> Now the help on = says:
> = X Y -> B
> Either both X and Y are numeric or both are strings
> or symbols. Tests whether X equal to Y. Also supports
> float.
>
> I assumed that '=' will consume two arguments off the stack,
> and leave the true or false on top.
>
> the joy interp seems to support this.
>
> 1 2 = .
> false
> .
>
> Now, if I use the same inside an ifte
> 1 5 [1 =] [dup *] [dup +] ifte .
> 10
>
> The doubt I have is this:
> as soon as [1 =] is executed, I would expect '5' off the stack,
> so the [dup +] should have actually found '1' on the stack and given
> me 2.
>
> I checked this too: which seems to do fine.
> 5 [true] [dup *] [dup +] ifte .
> 25
>
> Is there a reason for this? Is for some reason the stack
> invariant when executing ifte condition?
> The below seems to verify it.
>
> 5 6 [pop 1 =] [dup *] [dup +] ifte .
> 12
> .
> 5
>
> But I cant find any info on this.
> The other quoted programs does not seem to share the invariant stack
> behavior:
> ================================
> i [P] -> ...
> Executes P. So, [P] i == P.
>
> 1 2 [1 +] i .
> 3
> .
> 1
>
> Could some one please explain why this is so? or guide me to the
> docs that explains it?
>
> rahul.
>
>
>
[Non-text portions of this message have been removed]
Taoufik Dachraoui — 2007-03-03 11:37:08
looking at the defintion of factorial:
in Joy:
fact == [0 =] [pop 1] [dup 1 - fact *] ifte
in v:
[fact
[dup 0 =]
[pop 1]
[dup 1 - fact *]
ifte].
In the second definition we explicitly manipulate the stack (dup) so
that the remaining code finds the stack in the expected state. In
this case dup is certainly faster than saving and restoring the
stack, but in other situations this may not be true.
Taoufik
On Mar 3, 2007, at 11:59 AM, Taoufik Dachraoui wrote:
> I tried to define ifte as it is implemented in joy1 and I found this:
>
> [T] [A] [B]
> ifte == [[[stack] dip] dip
> [dip swap] dip] dip #save stack and run T
> choice [unstack] dip i; # restore stack and choose
> between A and B
>
> The stack is saved before the execution of [T] and restored before the
> execution of [A] or [B]. The test in this case is non destructive;
> the stack
> is unchanged before choosing between A and B.
>
> The way you implmented ifte is as follows:
>
> [T] [A] [B]
> ifte == [[i] dip] dip #run T
> choice i; # choose between A and B
>
> Obviously your implementation is faster, but the test in this case
> is destructive; the stack can be modified greatly depending on T.
>
> Is it more difficult or easier to reason with destructive tests?
>
> Taoufik
>
> On Mar 1, 2007, at 9:17 PM, Rahul wrote:
>
> > I have been looking through the joy papers, and have
> > this confusion:
> >
> > The help on ifte says:
> >
> > ifte [B] [T] [F] -> ...
> > Executes B. If that yields true, then executes T
> > else executes F.
> >
> > Now the help on = says:
> > = X Y -> B
> > Either both X and Y are numeric or both are strings
> > or symbols. Tests whether X equal to Y. Also supports
> > float.
> >
> > I assumed that '=' will consume two arguments off the stack,
> > and leave the true or false on top.
> >
> > the joy interp seems to support this.
> >
> > 1 2 = .
> > false
> > .
> >
> > Now, if I use the same inside an ifte
> > 1 5 [1 =] [dup *] [dup +] ifte .
> > 10
> >
> > The doubt I have is this:
> > as soon as [1 =] is executed, I would expect '5' off the stack,
> > so the [dup +] should have actually found '1' on the stack and given
> > me 2.
> >
> > I checked this too: which seems to do fine.
> > 5 [true] [dup *] [dup +] ifte .
> > 25
> >
> > Is there a reason for this? Is for some reason the stack
> > invariant when executing ifte condition?
> > The below seems to verify it.
> >
> > 5 6 [pop 1 =] [dup *] [dup +] ifte .
> > 12
> > .
> > 5
> >
> > But I cant find any info on this.
> > The other quoted programs does not seem to share the invariant stack
> > behavior:
> > ================================
> > i [P] -> ...
> > Executes P. So, [P] i == P.
> >
> > 1 2 [1 +] i .
> > 3
> > .
> > 1
> >
> > Could some one please explain why this is so? or guide me to the
> > docs that explains it?
> >
> > rahul.
> >
> >
> >
>
> [Non-text portions of this message have been removed]
>
>
>
[Non-text portions of this message have been removed]
Rahul — 2007-03-03 12:18:17
Taoufik Dachraoui <taoufik.dachraoui@...> wrote:
> I tried to define ifte as it is implemented in joy1 and I found this:
>
> [T] [A] [B]
> ifte == [[[stack] dip] dip
> [dip swap] dip] dip #save stack and run T
> choice [unstack] dip i; # restore stack and choose
> between A and B
>
> The stack is saved before the execution of [T] and restored before the
> execution of [A] or [B]. The test in this case is non destructive;
> the stack
> is unchanged before choosing between A and B.
>
> The way you implmented ifte is as follows:
>
> [T] [A] [B]
> ifte == [[i] dip] dip #run T
> choice i; # choose between A and B
>
> Obviously your implementation is faster, but the test in this case
> is destructive; the stack can be modified greatly depending on T.
The speed is probably not important in this case. I had not
expected a change in behavior for a quote when it is inside an 'ifte'
and when it is evaluted outside by an 'i'. This behavior gives the
last param to 'ifte' a kind of special status (The stack and unstack
are quite meta compared to the rest of the words).
> Is it more difficult or easier to reason with destructive tests?
You are right here. My contention was that it did not seem to fit
nicely with the rest of joy.
Looking at it again, I like the way the Cat language has taken.
It expects a boolean rather than a quote at the top of the stack,
The result is not different from what we get in joy, though it avoids
the meta operations.
[snip..]
> > The help on ifte says:
> >
> > ifte [B] [T] [F] -> ...
> > Executes B. If that yields true, then executes T
> > else executes F.
[snip..]
> > I assumed that '=' will consume two arguments off the stack,
> > and leave the true or false on top.
[snip..]
> > Now, if I use the same inside an ifte
> > 1 5 [1 =] [dup *] [dup +] ifte .
> > 10
> > The doubt I have is this:
> > as soon as [1 =] is executed, I would expect '5' off the stack,
> > so the [dup +] should have actually found '1' on the stack and given
> > me 2.
Rahul — 2007-03-03 13:20:22
Taoufik Dachraoui <taoufik.dachraoui@...> wrote:
> in Joy:
> fact == [0 =] [pop 1] [dup 1 - fact *] ifte
> in v:
> [fact
> [dup 0 =]
> [pop 1]
> [dup 1 - fact *]
> ifte].
> In the second definition we explicitly manipulate the stack (dup) so
> that the remaining code finds the stack in the expected state. In
> this case dup is certainly faster than saving and restoring the
---
> stack, but in other situations this may not be true.
Would there be situations when this is less efficient?
If we are modifying n members in the stack in the condition, then
we may need to save only that n members rather than the entire
stack. This we can do any way because the programmer is aware of
the changes in stack. so that instead of above it might look like
[dup_last_5
do_stuff_on_these
pop_these_out
] ... ifte
But in case of ifte in joy, the interp has to reason about the
quotation and figure out the amount of stack effect, if it has
to do the same. I am not sure if it is possible.
John Cowan — 2007-03-03 16:10:19
Rahul scripsit:
> Looking at it again, I like the way the Cat language has taken.
> It expects a boolean rather than a quote at the top of the stack,
Joy also provides that operator, under the name of "choice".
--
John Cowan
cowan@... http://ccil.org/~cowan
Half the lies they tell about me are true.
-- Tallulah Bankhead, American actress
John Cowan — 2007-03-03 16:08:36
Taoufik Dachraoui scripsit:
> In the second definition we explicitly manipulate the stack (dup) so
> that the remaining code finds the stack in the expected state. In
> this case dup is certainly faster than saving and restoring the
> stack, but in other situations this may not be true.
In fact, for Joy the stack is just another linked list in the heap,
so saving and restoring it is just a matter of storing the stack pointer
in a local variable. So both operations are approximately O(1).
--
Andrew Watt on Microsoft: John Cowan
Never in the field of human computing
cowan@...
has so much been paid by so many
http://www.ccil.org/~cowan
to so few! (pace Winston Churchill)
rahul — 2007-03-03 19:43:00
> In fact, for Joy the stack is just another linked list in the heap,
> so saving and restoring it is just a matter of storing the stack pointer
> in a local variable. So both operations are approximately O(1).
Thanks,
I should have looked at the source first :).