For Programmers: Free Programming Magazines  


Home > Archive > APL > June 2004 > Indexing into each element of a nested vector









You are viewing an archived Text-only version of the thread. To view this thread in it's original format and/or if you want to reply to this thread please [click here]

 

Author Indexing into each element of a nested vector
Don Wiss

2004-06-14, 8:55 pm

I am using APL+Win. I have a vector and each element is a vector of the
same length. For this example let's assume each has three scalars. I'd like
to index into each nest and make each have four scalars in a different
order. If it was a simple vector of three, with no nesting, I would index
using: [3 3 2 1]. How would I do the same, but have it work on each vector
in the nested vector?

Thanks, Don <donwiss at panix.com>.
Todd Marshall

2004-06-14, 8:55 pm

In GLEE:

:@&(1..5){10*->3?}=>v;
"Original V:"$;v,,\$;
"Each V Indexed:"$;
v@&([3 3 2 1]),,\$;

Result:
Original V:
5 3 7
2 2 4
4 8 4
4 7 1
9 8 1
Each V Indexed:
7 7 3 5
4 4 2 2
4 4 8 4
1 1 7 4
1 1 8 9

/Todd



Don Wiss wrote:
> I am using APL+Win. I have a vector and each element is a vector of the
> same length. For this example let's assume each has three scalars. I'd like
> to index into each nest and make each have four scalars in a different
> order. If it was a simple vector of three, with no nesting, I would index
> using: [3 3 2 1]. How would I do the same, but have it work on each vector
> in the nested vector?
>
> Thanks, Don <donwiss at panix.com>.


LatLong

2004-06-15, 3:55 am


a{<-}?{each}5{rho}{enclose}3/10 & a & #split ({disclose}a)[;3 3 2 1]
10 1 8 8 9 2 1 7 9 7 8 8 10 9 3
8 8 1 10 2 2 9 8 9 9 7 1 8 8 8 7 3 3 9 10





"Don Wiss" <donwiss@no_spam.com> wrote in message
news:qhesc09uvrtdd6d74ojnfjjns2qtjjrl35@
4ax.com...
> I am using APL+Win. I have a vector and each element is a vector of the
> same length. For this example let's assume each has three scalars. I'd

like
> to index into each nest and make each have four scalars in a different
> order. If it was a simple vector of three, with no nesting, I would index
> using: [3 3 2 1]. How would I do the same, but have it work on each vector
> in the nested vector?
>
> Thanks, Don <donwiss at panix.com>.



David Liebtag

2004-06-15, 3:55 am

({enclose} 3 3 2 1){squad}{each}{each}{enclose}{each} 'ABC' 'DEF'
'GHI'
CCBA FFED IIHG

David Liebtag
IBM APL Products and Services


LatLong

2004-06-15, 3:55 am

10000 EXT 'z{<-}#split ({disclose}a)[;3 3 2 1]'
0.0000104038115
10000 EXT 'z{<-}({enclose}3 3 2 1){squad}{each}{each}{enclose}{each}a'
0.0001212158547

The former is 12 times faster than the latter in APL+Win where a is 20
element vector of 3 element vectores.





"LatLong" <lat.long@earthlink.net> wrote in message news:...
>
> a{<-}?{each}5{rho}{enclose}3/10 & a & #split ({disclose}a)[;3 3 2 1]
> 10 1 8 8 9 2 1 7 9 7 8 8 10 9 3
> 8 8 1 10 2 2 9 8 9 9 7 1 8 8 8 7 3 3 9 10
>
>
>
>
>
> "Don Wiss" <donwiss@no_spam.com> wrote in message
> news:qhesc09uvrtdd6d74ojnfjjns2qtjjrl35@
4ax.com...
> like
index[color=darkred]
vector[color=darkred]
>
>



Don Wiss

2004-06-15, 3:55 am

On Mon, 14 Jun 2004 19:29:55 -0700, LatLong <lat.long@earthlink.net> wrote:

>10000 EXT 'z{<-}#split ({disclose}a)[;3 3 2 1]'
> 0.0000104038115


Yes, of course. Though instead of #split I tend to use {enclose}[2].

Thanks, Don <donwiss at panix.com>.
David Liebtag

2004-06-15, 3:55 am

And probably takes less intermediate storage too.


LatLong

2004-06-15, 3:55 am

#split is not #io dependant.

#split vs {enclose}[#io+1]

Of course, if every thing you do has a fixed #io, great...


"Don Wiss" <donwiss@no_spam.com> wrote in message
news:hppsc01ut9dd62bagbp59ggt8t2gvircka@
4ax.com...
> On Mon, 14 Jun 2004 19:29:55 -0700, LatLong <lat.long@earthlink.net>

wrote:
>
>
> Yes, of course. Though instead of #split I tend to use {enclose}[2].
>
> Thanks, Don <donwiss at panix.com>.



LatLong

2004-06-15, 3:55 am

10000 EXT 'z{<-}#split({disclose}a)[;3 3 2 1]'
0.00001039529421
10000 EXT 'z{<-}{enclose}[2]({disclose}a)[;3 3 2 1]'
0.00001197368133
0.00001197368133{divide}0.00001039529421
1.15183669500000
#split is about 15% faster than {enclose}[2]




"Don Wiss" <donwiss@no_spam.com> wrote in message
news:hppsc01ut9dd62bagbp59ggt8t2gvircka@
4ax.com...
> On Mon, 14 Jun 2004 19:29:55 -0700, LatLong <lat.long@earthlink.net>

wrote:
>
>
> Yes, of course. Though instead of #split I tend to use {enclose}[2].
>
> Thanks, Don <donwiss at panix.com>.



LatLong

2004-06-15, 3:55 am

I don't read Gr. OH WAIT!



"Todd Marshall" <Todd@WithGLEE.com> wrote in message
news:40CE3F7B.1060309@WithGLEE.com...
> In GLEE:
>
> :@&(1..5){10*->3?}=>v;
> "Original V:"$;v,,\$;
> "Each V Indexed:"$;
> v@&([3 3 2 1]),,\$;
>
> Result:
> Original V:
> 5 3 7
> 2 2 4
> 4 8 4
> 4 7 1
> 9 8 1
> Each V Indexed:
> 7 7 3 5
> 4 4 2 2
> 4 4 8 4
> 1 1 7 4
> 1 1 8 9
>
> /Todd
>
>
>
> Don Wiss wrote:
like[color=darkred]
index[color=darkred]
vector[color=darkred]
>



Todd Marshall

2004-06-15, 3:56 pm

GLEE Translation:

$$ Is end of line comment

$* is block comment *$

$$ First statement:

:@&(1..5){10*->3?}=>v;

$$ Taking it apart left to right as parsed

@& $$ Means "at each"

:@& $$ is GLEE's "for" statement

:@&(1..5) $$ Means "at each of 1 to 5 (or "for 1 to 5")

10*->3

$$ "->3" means take 3 from the right of the vector
$$ "*->3" means the same but fill with the left.

? $$ means random number in range of left

$$ The body of the "for" statement

{ ... } => v

$* { ... } is an anonymous block ... stuff created inside
$$ is local. ";" is the statement separator (not used here).
$$ If a statement doesn't end with ";", contents
$$ are returned. Thus, doing at-each "@&" on
$$ this block from 1 to 5 (1..5), produces 5
$$ results which are 3 element vectors of random
$$ numbers between 1 and 10. Each of these
$$ individual results is collected as a "sequence"
$$ of items or elements (e.g. heterogeneous array).
$$ That result is assigned " => " to a variable "v"*$

$$ The raw sequence display (notice no separators):
5 3 72 2 44 8 44 7 19 8 1

$$ Displaying the result:
"Original V:"$;v,,\$;

"Original V:"$;
$$ Just a statement displaying ($) a character string
$$ The "$" may be used to force display anytime while
$$ parsing.

v,,\$ $$ A statement displaying the sequence

$* The ",," is a glyph for replicating sequence
$$ insertion. The " \ " in this context is the
$$ glyph for newline. So it is inserting newlines
$$ between the elements of the sequence ... (i.e
$$ it is displaying sequence elements a line at
$$ a time. *$

$$ The result:

Original V:
5 3 7
2 2 4
4 8 4
4 7 1
9 8 1

$$ Now the second statement:

v@&([3 3 2 1])

$* "@&" at each item of the sequence "v" we "index"
$$ elements out. The result is another sequence
$$ of the new items *$

$$ Displaying the results as before
"Each V Indexed:"$;
v@&([3 3 2 1]),,\$;

$$ We have:

Each V Indexed:
7 7 3 5
4 4 2 2
4 4 8 4
1 1 7 4
1 1 8 9

GLEE does not read Gr ... it reads ASCII.

GLEE is not limited to 2 character glyphs. The glyphs are made up of a
more rudimentary language using ASCII glyphs (e.g. _at_ "@" and _each_
"&" is _at-each_ "@&")

GLEE reads left to right, not right to left.

If you download the GLEE interpreter

http://withglee.com/Bases/GBDownloads.htm

you can execute these examples directly just by cutting them out of the
email; pasting them into GLEE source pane; and pressing the go button.


/Todd




LatLong wrote:
> I don't read Gr. OH WAIT!
>
>
>
> "Todd Marshall" <Todd@WithGLEE.com> wrote in message
> news:40CE3F7B.1060309@WithGLEE.com...
>
>
> like
>
>
> index
>
>
> vector
>
>
>


LatLong

2004-06-15, 3:56 pm

AH! I got it! GLEE is not limited to 2 character "glyphs", it is a
higher form! Hieroglyphs! NOT GREEK.


"Todd Marshall" <Todd@WithGLEE.com> wrote in message
news:40CEEEC1.9080204@WithGLEE.com...

GLEE does not read Gr ... it reads ASCII.

GLEE is not limited to 2 character glyphs. The glyphs are made up of a
more rudimentary language using ASCII glyphs (e.g. _at_ "@" and _each_
"&" is _at-each_ "@&")

GLEE reads left to right, not right to left.



John Sullivan

2004-06-15, 3:56 pm

In message <zIudnU1aJ9H7ZlPdRVn-uA@adelphia.com>, LatLong
<lat.long@earthlink.net> writes
>AH! I got it! GLEE is not limited to 2 character "glyphs", it is a
>higher form! Hieroglyphs! NOT GREEK.


Shouldn't that be hierogleephics?

>
>
>"Todd Marshall" <Todd@WithGLEE.com> wrote in message
>news:40CEEEC1.9080204@WithGLEE.com...
>
>GLEE does not read Gr ... it reads ASCII.
>
>GLEE is not limited to 2 character glyphs. The glyphs are made up of a
>more rudimentary language using ASCII glyphs (e.g. _at_ "@" and _each_
>"&" is _at-each_ "@&")
>
>GLEE reads left to right, not right to left.


It is a common misconception that APL reads from right to left. In fact
it is all to do with binding strength. It is better to talk about left
and right scope. Functions have short left scope and long right scope.
Operators have long left scope and short right scope.


--
John Sullivan
Ted Edwards

2004-06-15, 3:56 pm

Todd Marshall wrote:

> GLEE reads left to right, not right to left.


Hmmm. "The right argument of a function is the entire expression to its
right except as delimited by parenthesis <or square brackets>." Just
like
Sin Arctan x

Where have you been all these years?

Any interpreter/compiler that _reads_ left to right (such as APL) would
logically _execute_ right to left.

What would you do with
3+x÷7

Ted

Todd Marshall

2004-06-15, 3:56 pm

Perhaps.

But APL returns its result to the left. That becomes the right argument
to subsequent operators which in turn return their result to their left.
It may be a misconception but it sure appears to be processing right to
left.

GLEE, on the other hand, returns results to the right which becomes the
left argument to subsequent operators which also return their results to
the right. This gives the appearance of left to right processing.

It is particularly convenient when you consider that GLEE gives the
intuitive _2 result for 1-2+3-4.

APL resorts to (((1-2)+3)-4) to produce this intuitive _2 result. The
parenthesis are necessary to obviate the "misconception" of APL reading
right to left.

Talking about left to right scope, GLEE has short left and short right
scope.

1 2 3 4 + 5 gives 6 7 8 9

this is really processed as:
1 2 giving (1 2)
(1 2) 3 giving (1 2 3)
(1 2 3) 4 giving (1 2 3 4)
(1 2 3 4) + 5 giving (6 7 8 9)

With the same length of scope:
5 + 1 2 3 4 gives 6 2 3 4

this is really processed as:
5 + 1 giving (6)
(6) 2 giving (6 2)
(6 2) 3 giving (6 2 3)
(6 2 3) 4 giving (6 2 3 4)

To force longer right scope, GLEE relies on parenthesis:

5 + (1 2 3 4) gives 6 7 8 9.


John Sullivan wrote:
>
>
> It is a common misconception that APL reads from right to left. In fact
> it is all to do with binding strength. It is better to talk about left
> and right scope. Functions have short left scope and long right scope.
> Operators have long left scope and short right scope.
>
>


James L. Ryan

2004-06-15, 3:56 pm

On Tue, 15 Jun 2004 11:00:12 -0500, John Sullivan wrote
(in article <GjIpq+gM0xzAFAAk@yddraiggoch.demon.co.uk> ):

> It is a common misconception that APL reads from right to left. In fact it
> is all to do with binding strength. It is better to talk about left and
> right scope. Functions have short left scope and long right scope. Operators
> have long left scope and short right scope.


But side effects do occur from right to left

x is 5
(x is 10) + x
15

In a straight left to right processing order one would expect the answer to
be 20.




-- James L. Ryan -- TaliesinSoft

RAV

2004-06-15, 3:56 pm

On Tue, 15 Jun 2004 17:17:42 GMT, James L. Ryan <taliesinsoft@mac.com>
wrote:

>On Tue, 15 Jun 2004 11:00:12 -0500, John Sullivan wrote
>(in article <GjIpq+gM0xzAFAAk@yddraiggoch.demon.co.uk> ):
>
>
>But side effects do occur from right to left
>
> x is 5
> (x is 10) + x
>15
>
>In a straight left to right processing order one would expect the answer to
>be 20.
>
>
>-- James L. Ryan -- TaliesinSoft


Not directed at you, but that's what we used to call pornographic
code, in which the implementation details determine the result. I'm
pretty sure that some early APL systems (the old MVT-based one at
STSC, perhaps) returned 20. We were always warned to stay away from
such coding style, and I suspect you would agree with me.
James J. Weinkam

2004-06-15, 3:56 pm

Don Wiss wrote:
> I am using APL+Win. I have a vector and each element is a vector of the
> same length. For this example let's assume each has three scalars. I'd like
> to index into each nest and make each have four scalars in a different
> order. If it was a simple vector of three, with no nesting, I would index
> using: [3 3 2 1]. How would I do the same, but have it work on each vector
> in the nested vector?


I don't know if this will work in APL+Win, but in APL2

a{is}{enclose}[2]7 3{rho}{iota}21
a
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
({enclose}{enclose}3 3 2 1){squad}{each}a
3 3 2 1 6 6 5 4 9 9 8 7 12 12 11 10 15 15 14 13 18 18 17 16 21 21 20 19
Todd Marshall

2004-06-15, 3:56 pm


3+x/7 => result;

Ted Edwards wrote:

> Todd Marshall wrote:
>
>
>
>
> Hmmm. "The right argument of a function is the entire expression to its
> right except as delimited by parenthesis <or square brackets>."

Half true for GLEE.

It is not the "entire expression to its right". It is the next element
to the right.

-----------------------------------------
(1)The contents of parenthesis " ( ... ) "are computed to discover this
element. Scoping is global. The result becomes the right argument.

1 2 3 + (4 5 6) $**;

Result:
Num[R1C3:I]5 7 9

-----------------------------------------
(2)The contents of curly braces " { ... } " are computed to discover
this element, but braces close off the earlier interpretation. Scoping
is constrained within the braces. Objects created within are local.
Objects above "depth" one outside the braces (i.e outside the "block")
are read only. Arguments are passed into the "block" as a namespace. The
result becomes the right argument.

1 2 3 + {4 5 6} $**;

Result:
Seq[R1C2:K]
[1]Num[R1C3:I]1 1 1
[2]Num[R1C3:I]4 5 6

In this case, the interpretation is cut off at the "{". The "+" is thus
taken as the monadic "signum" operator. A new interpretation is started
for the contents of the braces. The result is stranded to what is on the
left. A two item sequence results.

1 2 3 [.x]{4 5 6 + x} $**;
Result:
Num[R1C3:I]5 7 9

Here we have an "anonymous" block. A namespace containing the variable
"x" which refers to "1 2 3" is passed into the block. The vector
operation is performed and the result is returned to the right. The "x"
is local to the block.

Alternatively:
1 2 3 + ({4 5 6}) $**;
Result:
Num[R1C3:I]5 7 9

Here, the parenthesis cause a new interpretation to discover the right
argument. The braces cause a new interpretation to execute in a local
namespace and return the result to the parenthesis enclosed
interpretation. It in turn returns the result becoming the right
argument of the "+".

-----------------------------------------
(3)The contents of square brackets " [ ... ] " are computed to discover
this element, but brackets close off the earlier interpretation and
invoke an implicit "index of" operation. Scoping is global. The result
becomes the right argument of an implicit "take index of" operator.

1 2 3 4 5 => x;
x[2 3 4]=>[4 3 2]x;
x

Result:
1 4 3 2 5

In this case, the first "[" can be taken as an "index of" operator. At
the second "[", we don't have the assignment operator ( => ); we have
the indexed assignment operator ( =>[ ). GLEE makes this implicit
interpretation and then essentially treats the " [ ... ] " as " ( ... ) ".

-----------------------------------------
Just
> like
> Sin Arctan x


1=>x #atan #sin

Interpreted as:
(1=>x) $$ 1 is assigned to variable "x"
((1=>x) #atan) $$ the arc tangent of "x" radians is computed
(((1=>x) #atan) #sin) $$ the sine is computed from the result

Result:
0.707107

3+x/7

Interpreted as:
((3+x)/7)

Result:
0.571429


....the way I was taught in grade school. The only adult switch I am
making is substituting slash for the divide sign.

I think it was much later that school imposed operator precedence on me
(algebra class maybe?).

As in APL, operator precedence is untenable in GLEE.



>
> Where have you been all these years?
>
> Any interpreter/compiler that _reads_ left to right (such as APL) would
> logically _execute_ right to left.
>
> What would you do with
> 3+x÷7
>
> Ted
>


Todd Marshall

2004-06-15, 3:56 pm

James L. Ryan wrote:

> On Tue, 15 Jun 2004 11:00:12 -0500, John Sullivan wrote
> (in article <GjIpq+gM0xzAFAAk@yddraiggoch.demon.co.uk> ):
>
>
>
>
> But side effects do occur from right to left
>
> x is 5
> (x is 10) + x
> 15
>
> In a straight left to right processing order one would expect the answer to
> be 20.


And GLEE gets that answer:

5=>x; (10=>x)+x
Result:
20

Also in GLEE (note braces, not parenthesis):

5=>x; {10=>x}+x
Result:
20

But peculiar to GLEE (double and deeper braces force total localization):

5=>x; {{10=>x}}+x
Result:
15

In the first example, "x" is at scope 0 and is read/write.

In the second example, "x" is at scope 1 and is read/write.

In the third example, "x" is at scope 2 and is read only.

GLEE can report the scope of variables (monadic "*"):

5=>x;
{{
'Scope of x is '(x*) $;
10=>x;
'New scope of x is '(x*) $;
x
}}+x

Scope of x is 2
New scope of x is 0
Result:
15

In the last case, within the braces, GLEE now has two "x's". One at
scope 2 which becomes shadowed by a new one at scope 0. Until the
assignment, the scope 2 "x" is visible and can be used in the
computation. Afterwords (but still inside the braces), the "x" is at
scope 0 and the scope 2 "x" is unaffected and invisible.



>
>
>
>
> -- James L. Ryan -- TaliesinSoft
>


James L. Ryan

2004-06-15, 3:56 pm

On Tue, 15 Jun 2004 12:45:46 -0500, RAV wrote
(in article <53duc0hq07qv581dkthef638otod9o24t5@4ax.com> ):

[commenting on the expression (x is 10) + x in which the value of the
right hand x retains the value it had prior to the expression]

> Not directed at you, but that's what we used to call pornographic code, in
> which the implementation details determine the result. I'm pretty sure that
> some early APL systems (the old MVT-based one at STSC, perhaps) returned 20.
> We were always warned to stay away from such coding style, and I suspect
> you would agree with me.


That anomalous behaviour was indeed part of the "original" IBM APLs, and
there was even an "official" justification for it. I believe that IBM changed
that behaviour as a result of a decision of the standards committee.

And, I fully agree that such a construct is "pornographic" and is something I
will avoid.

-- James L. Ryan -- TaliesinSoft

James J. Weinkam

2004-06-15, 8:55 pm

Todd Marshall wrote:
> And GLEE gets that answer:
>
> 5=>x; (10=>x)+x
> Result:
> 20
>

Ah, but since GLEE seems to be more or less the mirror image of APL, what you
sould be looking at is

5=>x; x+(10=>x)

I don't know GLEE, so you tell me; but my guess is that the answer is now 15!
James J. Weinkam

2004-06-15, 8:55 pm

James L. Ryan wrote:
> On Tue, 15 Jun 2004 12:45:46 -0500, RAV wrote
> (in article <53duc0hq07qv581dkthef638otod9o24t5@4ax.com> ):
>
> [commenting on the expression (x is 10) + x in which the value of the
> right hand x retains the value it had prior to the expression]
>
> That anomalous behaviour was indeed part of the "original" IBM APLs, and
> there was even an "official" justification for it. I believe that IBM changed
> that behaviour as a result of a decision of the standards committee.
>

Nonsense. It's the essence of APL: functions have no precedence and are right
associative.

I just ran the example below 30 seconds ago on APL2 for OS/2:

x{is}5
(x{is}10)+x
15

Moreover, the value of x+(x{is}10)+x would be 25; and the value of x(x{is}10)+x
would be 15 15.

Although this is drifting off topic, let me use this as an occasion to clear up
confusion over associativity, left associativity, and right associativity that I
see from time to time on this and other newsgroups.

Associativity is a mathematical property of a binary operation (in APLese read
dyadic function) on some domain D, #:DxD->D. It means that for any x,y,z in D

((x#y)#z)=(x#(y#z))

That's exact equality in all cases, no exceptions, no if's, and's, or but's.

This means that x#y#z is unambiguous because you get the same answer no matter
how you put the parentheses in.

In mathematics, addition and multiplication are associative for the integers,
rationals, reals, and complex, and many other algebraic systems. Subtraction,
division, and exponentiation are not.

On the other hand, right and left associativity are syntactic conventions, not
mathematical properties. They can be neither proved nor disproved. They are in
essence an agreement on the interpretation of an expression which is not fully
parenthesized.

These conventions are needed because, unlike addition and multiplication on the
mathematical domains mentioned above, addition and multiplication of computer
integers and computer floating point numbers are not associative. Consequently,
in an unparenthesized expression, it is important to have a clear understanding
on the order in which operations will be performed.

If # is deemed to be left associative, x#y#z is disambiguated by interpreting it
as ((x#y)#z). On the other hand, if # is deemed to be right associative x#y#z
is interpreted as (x#(y#z)).
Todd Marshall

2004-06-15, 8:55 pm

5=>x; x+(10=>x)
Result:
15

Your guess is correct. GLEE completely forms its left argument before
discovery of an operator interrupts the interpretation.

Seeing an operator, in your example "+", the "x" is dereferenced
yielding the "5" as the left argument. GLEE then looks to the right of
the operator.

If it finds another operator, or a left bracket, brace, statement
separator, etc., it invokes the glyph monadically passing that result on
to the right.

Otherwise it goes to work on the right argument using a short scoping
rule (which can be extended indefinitely using parenthesis).

Now having obtained both the left and right arguments, GLEE invokes the
glyph dyadically delivering the result to the right.

GLEE doesn't make this form of coding any less pornographic, but the
forming of the left and right arguments is not arbitrary, The left is
always formed completely before the right.

With this simple left to right rule, the processing is not ambiguous.

I too remember that APL made no guarantee which argument was evaluated
first.

GLEE guarantees the left is evaluated first.

James J. Weinkam wrote:
> Todd Marshall wrote:
>
> Ah, but since GLEE seems to be more or less the mirror image of APL,
> what you sould be looking at is
>
> 5=>x; x+(10=>x)
>
> I don't know GLEE, so you tell me; but my guess is that the answer is
> now 15!


Todd Marshall

2004-06-15, 8:55 pm


James J. Weinkam wrote:

> James L. Ryan wrote:
>
> Nonsense. It's the essence of APL: functions have no precedence and are
> right associative.
>
> I just ran the example below 30 seconds ago on APL2 for OS/2:
>
> x{is}5
> (x{is}10)+x
> 15
>
> Moreover, the value of x+(x{is}10)+x would be 25;


In GLEE:

5=>x; x+(10=>x)+x
Result:
25


> and the value of
> x(x{is}10)+x would be 15 15.


Well, not in GLEE:

5=>x;x(10=>x)+x
^
Value error
Type:C:\CPPProjs\Interpreter\KOps.cpp[1119]

Using the GLEE inline verbose discloser ( $** ) to troubleshoot:

5=>x;x(10=>x)$** +x

Seq[R1C2:K]
[1]Num[R1C1:I]5
[2]Num[R3C1:I]10
[0^1:19]
5=>x;x(10=>x)$** +x
^
Value error
Type:C:\CPPProjs\Interpreter\KOps.cpp[1119]

Reveals the left argument of "+" to be a sequence and therefore an
invalid value for the "+" operation.

In GLEE, the disclose "<" operator can reduce a homogenous sequence to a
vector so the following resolves this issue:

5=>x;x(10=>x)< $** +x

Num[R1C2:I]5 10
Result:
Num[R2C2:I]15 20

Now, the left argument is a numeric vector and the operation proceeds
using GLEE's normal extension of the right argument(i.e. 10*->2).

Alternately, we could have used catenation in forming the left and
avoided creation of the sequence:

5=>x;x,(10=>x) $** +x

Num[R1C2:I]5 10
Result:
Num[R2C2:I]15 20

To get the 15 15 answer you propose, GLEE would have to back assign to
the first "x" in the expression " x,(10=>x) ". It doesn't normally do
this. GLEE has already moved beyond that first "x".

To get what you propose would require that we are working with a
reference to "x" rather than a copy of "x".

GLEE has such a referencing capability:
x@ => y; $$ makes "y" a reference to "x")

5=>x;x@ =>y;y,(10=>y) $** +x

Num[R1C2:I]10 10
Result:
Num[R2C2:I]20 20

This still doesn't get the effect you propose because the right argument
"x" is affected as well.

However, by doing it within a localized block as follows we can get the
result you propose.

5=>x;{{x@ =>y;y,(10=>y)}} $** +x

Num[R1C2:I]10 10
Result:
Num[R2C2:I]15 15

This works because the "x" being referenced in forming the left argument
is out of the scope of the original "x" which is read only. Thus, GLEE
makes a copy and references the copy within the block. The "x" outside
the block is unaffected.

>
> Although this is drifting off topic, let me use this as an occasion to
> clear up confusion over associativity, left associativity, and right
> associativity that I see from time to time on this and other newsgroups.
>
> Associativity is a mathematical property of a binary operation (in
> APLese read dyadic function) on some domain D, #:DxD->D. It means that
> for any x,y,z in D
>
> ((x#y)#z)=(x#(y#z))
>
> That's exact equality in all cases, no exceptions, no if's, and's, or
> but's.
>
> This means that x#y#z is unambiguous because you get the same answer no
> matter how you put the parentheses in.
>
> In mathematics, addition and multiplication are associative for the
> integers, rationals, reals, and complex, and many other algebraic
> systems. Subtraction, division, and exponentiation are not.
>
> On the other hand, right and left associativity are syntactic
> conventions, not mathematical properties. They can be neither proved
> nor disproved. They are in essence an agreement on the interpretation
> of an expression which is not fully parenthesized.
>
> These conventions are needed because, unlike addition and multiplication
> on the mathematical domains mentioned above, addition and multiplication
> of computer integers and computer floating point numbers are not
> associative. Consequently, in an unparenthesized expression, it is
> important to have a clear understanding on the order in which operations
> will be performed.
>
> If # is deemed to be left associative, x#y#z is disambiguated by
> interpreting it as ((x#y)#z). On the other hand, if # is deemed to be
> right associative x#y#z is interpreted as (x#(y#z)).


GLEE exhibits left associative behavior.

James J. Weinkam

2004-06-16, 3:55 am

Todd Marshall wrote:
> With this simple left to right rule, the processing is not ambiguous.
>

The same is true for APL's right to left rule.

> I too remember that APL made no guarantee which argument was evaluated
> first.
>

I think you're mistaken. At least APL dereferences variables and performs
assignments consistent with right to left evaluation. It may choose to do some
operations in another order when it doesn't matter. I'll let others more
familiar with the innards settle that.
Todd Marshall

2004-06-16, 3:55 am



James J. Weinkam wrote:

> I think you're mistaken. At least APL dereferences variables and
> performs assignments consistent with right to left evaluation. It may
> choose to do some operations in another order when it doesn't matter.
> I'll let others more familiar with the innards settle that.


Perhaps I am mistaken. It was never an issue for me. I do vaguely
remember the issue being mentioned. A lot has changed since 1970.

James J. Weinkam

2004-06-16, 3:55 am

Todd Marshall wrote:
>
> James J. Weinkam wrote:
>
>
>
>
> Well, not in GLEE:
>
> 5=>x;x(10=>x)+x
> ^

Again because of the left to right nature of GLEE vs the right to left nature of
APL, I would think the corresponding expression would be

5=>x; x+(10=>x)x

On the other hand
x{is}5
(x{is}10)+x x

also gives 15 15 in APL.

> To get the 15 15 answer you propose, GLEE would have to back assign to
> the first "x" in the expression " x,(10=>x) ". It doesn't normally do
> this. GLEE has already moved beyond that first "x".
>

I am not proposing anything; I'm stating a fact. In either case a scalar is
being added to a vector and the scalar is extended to a vector and the two
vactors are added.

Is there an OS/2 implementation of GLEE?
Todd Marshall

2004-06-16, 3:55 am

> Again because of the left to right nature of GLEE vs the right to left
> nature of APL, I would think the corresponding expression would be
>
> 5=>x; x+(10=>x)x


In GLEE:
5=>x; x+(10=>x)x $**;
Result:
Seq[R1C2:K]
[1]Num[R1C1:I]15
[2]Num[R3C1:I]10

GLEE does not do implicit catenation.

In GLEE:
5=>x; x x $**;
Result:
Seq[R1C2:K]
[1]Num[R4C1:I]5
[2]Num[R4C1:I]5

A two item sequence of 1 element numeric vectors

5=>x; x,x $**;
Result:
Num[R1C2:I]5 5

A two element numeric vector

In GLEE;
5=>x; x,x+(10=>x) $**;
Result:
Num[R1C2:I]15 15

>
> On the other hand
> x{is}5
> (x{is}10)+x x
>
> also gives 15 15 in APL.


In GLEE (notice explicit catenation):

5=>x; x,x+(10=>x) $**;
Result:
Num[R1C2:I]15 15

>
> I am not proposing anything; I'm stating a fact. In either case a
> scalar is being added to a vector and the scalar is extended to a vector
> and the two vactors are added.


My poor choice of phrasing.

The issue actually is " x x " in your example implicitly catenating the
"x's".

GLEE doesn't do this because implicit catenation of character strings is
not generally usefull and GLEE tries to be consistent.

For example:

"John Hancock" =>name;
"New York, NY" =>city;
name city $**

Result:
Seq[R1C2:K]
[1]String[R2C12:C]John Hancock
[2]String[R3C12:C]New York, NY

>
> Is there an OS/2 implementation of GLEE?


No.

James J. Weinkam

2004-06-16, 3:55 am

Todd Marshall wrote:
>
> The issue actually is " x x " in your example implicitly catenating the
> "x's".
>
> GLEE doesn't do this because implicit catenation of character strings is
> not generally usefull and GLEE tries to be consistent.


x is a numeric scalar. I don't see where character strings enter into this example.

I would argue that APL doesn't do implicit concatenation either. If APL were
doing implicit concatenation, the result in each instance should be the same as
what would be obtained it the , were explicitly inserted.

x x is vector notation. Here is what the on line reference has to say on vector
notation:


A series of value expressions separated from each other by nothing but spaces
is treated as a vector. Here are
some examples:

2 3 4
'A' 'B' 'C'
1 (2 3) 4

In that last example, (2 3) is a value expression which is then combined with
the remainder of the expression
to form a three-item nested array. Here are some additional examples which
extend that concept:

2 'ABC'
1 (2+3) 4
AA{is}2 3
1 AA 4

Note that the last example has exactly the same value as the last example in
the previous group.

Order of Evaluation

Like other APL expressions, the items within a vector notation are evaluated
from right to left:

A{is}1
A (A{is}2) A
2 2 1

But forming a vector using vector notation takes precedence over applying an
array to the function or operator
on its right.

1 2 3 + 4 5 6
5 7 9

A{is}1
3 A + 1 1
4 2

Vector notation does not take precedence over assignment.

A{is}1
A B{is}2 3
1 2 3
A
1
B
2 3
(A B){is}2 3
A
2
B
3

Nor does it take precedence over bracket indexing.

A{is}1 2 3
A A[2]
1 2 3 2

So if APL were really doing implicit concatenation, then
1 2,3+4 5 6
would be the same as
1 2 3+4 5 6

but

1 2,3+4 5 6
yields 1 2 7 8 9

whereas

1 2 3+4 5 6
yields 5 7 9

QED.


>
> For example:
>
> "John Hancock" =>name;
> "New York, NY" =>city;
> name city $**
>
> Result:
> Seq[R1C2:K]
> [1]String[R2C12:C]John Hancock
> [2]String[R3C12:C]New York, NY
>
>
>
> No.
>

Too bad. If there were I would try it out.
Todd Marshall

2004-06-16, 8:55 am



James J. Weinkam wrote:

> Todd Marshall wrote:
>
>
>
> x is a numeric scalar. I don't see where character strings enter into
> this example.

GLEE really doesn't have the concept of a scalar. Everything is a
vector. So 'a' is really a one element character vector (string) rather
than a scalar.

'a' 'b' is not 'ab' in GLEE.

'a' 'b' $**
Seq[R1C2:K]
[1]String[R1C1:C]a
[2]String[R2C1:C]b

'a' 'bc' 'd'$**
Seq[R1C3:K]
[1]String[R1C1:C]a
[2]String[R1C2:C]bc
[3]String[R2C1:C]d

'a'('bc')'d' $**
Seq[R1C3:K]
[1]String[R1C1:C]a
[2]String[R1C2:C]bc
[3]String[R2C1:C]d

'a' =>A; 'bc'=>B; 'd'=>C;
A B C $**;
Seq[R1C3:K]
[1]String[R2C1:C]a
[2]String[R2C2:C]bc
[3]String[R3C1:C]d

1 2 3 4 $**;
Num[R1C4:I]1 2 3 4

1 (2 3) 4 $**
Seq[R1C3:K]
[1]Num[R1C1:I]1
[2]Num[R1C2:I]2 3
[3]Num[R2C1:I]4

1=>A;2 3=>B;4=>C;
A B C $**;
Seq[R1C3:K]
[1]Num[R2C1:I]1
[2]Num[R2C2:I]2 3
[3]Num[R3C1:I]4

A B C < $**;
Num[R1C4:I]1 2 3 4

1 (2 3) 4 < $**
Num[R1C4:I]1 2 3 4

>
> I would argue that APL doesn't do implicit concatenation either. If APL
> were doing implicit concatenation, the result in each instance should be
> the same as what would be obtained it the , were explicitly inserted.
>
> x x is vector notation. Here is what the on line reference has to say
> on vector notation:
>
>
> A series of value expressions separated from each other by nothing but
> spaces is treated as a vector. Here are
> some examples:
>
> 2 3 4

2 3 4 $**;
Num[R1C3:I]2 3 4

> 'A' 'B' 'C'

'A' 'B' 'C' $**
Seq[R1C3:K]
[1]String[R1C1:C]A
[2]String[R1C1:C]B
[3]String[R2C1:C]C

> 1 (2 3) 4

1 (2 3) 4 $**
Seq[R1C3:K]
[1]Num[R1C1:I]1
[2]Num[R1C2:I]2 3
[3]Num[R2C1:I]4

>
> In that last example, (2 3) is a value expression which is then
> combined with the remainder of the expression
> to form a three-item nested array. Here are some additional examples
> which extend that concept:
>
> 2 'ABC'

2 'ABC' $**
Seq[R1C2:K]
[1]Num[R1C1:I]2
[2]String[R2C3:C]ABC

> 1 (2+3) 4

1 (2+3) 4 $**
Seq[R1C3:K]
[1]Num[R1C1:I]1
[2]Num[R1C1:I]5
[3]Num[R2C1:I]4


> AA{is}2 3
> 1 AA 4

2 3 =>AA;
1 AA 4 $**
Seq[R1C3:K]
[1]Num[R1C1:I]1
[2]Num[R2C2:I]2 3
[3]Num[R2C1:I]4

>
> Note that the last example has exactly the same value as the last
> example in the previous group.
>
> Order of Evaluation
>
> Like other APL expressions, the items within a vector notation are
> evaluated from right to left:
>
> A{is}1
> A (A{is}2) A
> 2 2 1

1=>A;
A (2=>A) A $**
Seq[R1C3:K]
[1]Num[R1C1:I]1
[2]Num[R4C1:I]2
[3]Num[R4C1:I]2

>
> But forming a vector using vector notation takes precedence over
> applying an array to the function or operator
> on its right.
>
> 1 2 3 + 4 5 6
> 5 7 9

1 2 3 + 4 5 6 $**
Num[R1C5:I]5 6 7 5 6

1 2 3 + (4 5 6) $**
Num[R1C3:I]5 7 9

>
> A{is}1
> 3 A + 1 1
> 4 2

1=>A;
1 1 + 3 A $**
Seq[R1C2:K]
[1]Num[R1C2:I]4 4
[2]Num[R3C1:I]1

1=>A;
1 1+ (3,A) $**
Num[R1C2:I]4 2

>
> Vector notation does not take precedence over assignment.
>
> A{is}1
> A B{is}2 3
> 1 2 3
> A
> 1
> B
> 2 3

1=>A;
2 3 => A B;
A $**;
Num[R3C2:I]2 3
B $**;
NV:

> (A B){is}2 3
> A
> 2
> B
> 3

2 3 =>(A B);

[0^1:11]
2 3 =>(A B);
^
Value error
Invalid symbol:C:\CPPProjs\Interpreter\KArg.cpp[53]

>
> Nor does it take precedence over bracket indexing.
>
> A{is}1 2 3
> A A[2]
> 1 2 3 2

1 2 3 =>A;
A[2] A $**;
Seq[R1C2:K]
[1]Num[R1C1:I]2
[2]Num[R4C3:I]1 2 3

A A[2] $**;
Seq[R1C1:K]
[1]Num[R4C3:I]1 2 3


>
> So if APL were really doing implicit concatenation, then
> 1 2,3+4 5 6

1 2 3 + 4,5 6 $**
Num[R1C5:I]5 6 7 5 6

> would be the same as
> 1 2 3+4 5 6

1 2 3+4 5 6 $**
Num[R1C5:I]5 6 7 5 6

1 2 3+(4 5 6) $**
Num[R1C3:I]5 7 9

>
> but
>
> 1 2,3+4 5 6
> yields 1 2 7 8 9
>
> whereas
>
> 1 2 3+4 5 6
> yields 5 7 9
>
> QED.


James L. Ryan

2004-06-16, 3:55 pm

On Tue, 15 Jun 2004 18:03:54 -0500, James J. Weinkam wrote
(in article <canv88$p71$1@morgoth.sfu.ca> ):

[responding to my stating that at one time the expression sequence

x is 5
(x is 10) + x

would at one time deliver the result 20 in IBM APLs]


> Nonsense. It's the essence of APL: functions have no precedence and are
> right
> associative.
>
> I just ran the example below 30 seconds ago on APL2 for OS/2:
>
> x{is}5
> (x{is}10)+x
> 15



The behavior of IBM APL, in this regard, was changed in response to a
decision of the APL standards committee made sometime in the mid to late
seventies. Prior to the change the expression result would be 20 and not 15,
and this behavior was defined in a document from IBM in which it was stated
(my paraphrasing here) that if the argument to a dyadic function is a
variable and not an expression that the association of the value to the
variable will not occur until any argument that is an expression is evaluated
first.

The precise order of evaluation of an expression is defined in detail in the
APL standard, and that is essentially one of strict right-to-left ordering,
that is that the right argument to a dyadic function is always evaluated
prior to the left argument. One of the things addressed by the APL standards
committee was how much liberty an APL implementation could take in
paraphrasing an expression for the sake of efficiency, etc. This led the
"phantom error" prohibition which, say, would disallow an implementation from
producing a valid result in the case of such as

x is 2 take a divide b

where there was a zero in b beyond the second position. In other words, an
implementation couldn't process the above expression as though it were

x is (2 take a) divide (2 take b)

While writing this another instance of where IBM changed the behavior of APL
in response to the standards committee was in the behavior of localized
system variables within defined functions. The original IBM behavior was such
that if, say, index origin was localized, that any attempt to execute an
origin sensitive function prior to an origin assignment within the containing
function would produce an "implicit" error. The notion of pass-through
localization of system variables was introduced in Burrough's APL\700 and was
subsequently included in other APL systems.



-- James L. Ryan -- TaliesinSoft

Michael Levine

2004-06-16, 3:55 pm

array <- "abcd" "efgh" "ijkl"
vec <- (3 3 2 1) ( 1 1 1 1) ( 2 2 1 1)



Squad (Index) Solution:
---------------

((enclose) (enclose) 3 3 2 1)(squad)(each) array
((enclose) (each) vec)(squad)(each) array


Matrix Solution:
-----------------
((enclose)[2]) ((disclose) array) [ ;3 3 2 1]


Choose Solution:
----------------------------------------------------------------------------
------
((enclose)[2]) ((disclose) array) [ (disclose)( (iota)(rho)array) (jot
dot comma)(each) vec ]



"Don Wiss" <donwiss@no_spam.com> wrote in message
news:qhesc09uvrtdd6d74ojnfjjns2qtjjrl35@
4ax.com...
> I am using APL+Win. I have a vector and each element is a vector of the
> same length. For this example let's assume each has three scalars. I'd

like
> to index into each nest and make each have four scalars in a different
> order. If it was a simple vector of three, with no nesting, I would index
> using: [3 3 2 1]. How would I do the same, but have it work on each vector
> in the nested vector?
>
> Thanks, Don <donwiss at panix.com>.



David Liebtag

2004-06-16, 3:55 pm

James,

You wrote:

> While writing this another instance of where IBM changed the behavior of

APL
> in response to the standards committee was in the behavior of localized
> system variables within defined functions. The original IBM behavior was

such
> that if, say, index origin was localized, that any attempt to execute an
> origin sensitive function prior to an origin assignment within the

containing
> function would produce an "implicit" error. The notion of pass-through
> localization of system variables was introduced in Burrough's APL\700 and

was
> subsequently included in other APL systems.


IBM's APL2 still behaves the old way. Implicit errors occur on uses of
functions that use unassigned localized variables. Does this really not
happen in the other dialects? I never knew that.

David Liebtag
IBM APL Products and Services


James L. Ryan

2004-06-16, 3:55 pm

On Wed, 16 Jun 2004 11:37:49 -0500, David Liebtag wrote
(in article <1087406694.104924@jabba.vermontel.net> ):

> IBM's APL2 still behaves the old way. Implicit errors occur on uses of
> functions that use unassigned localized variables. Does this really not
> happen in the other dialects? I never knew that.


[commenting on the use of pass through localization of system variables as a
means of avoiding implicit errors]

Pass through localization was first implemented on Burroughs APL\700 and, if
memory serves me correctly, was then included on STSC and Sharp APLs. As of
now the only APL I have access to is Dyalog APL which includes pass through
localization. I had thought that IBMs APL2 also had changed to this
definitiion but apparently I'm wrong here.


-- James L. Ryan -- TaliesinSoft

James J. Weinkam

2004-06-16, 8:55 pm

James L. Ryan wrote:
> On Tue, 15 Jun 2004 18:03:54 -0500, James J. Weinkam wrote
> (in article <canv88$p71$1@morgoth.sfu.ca> ):
>
> [responding to my stating that at one time the expression sequence
>
> x is 5
> (x is 10) + x
>
> would at one time deliver the result 20 in IBM APLs]
>

But that isn't what the passage I was responding to said:

[commenting on the expression (x is 10) + x in which the value of the right
hand x retains the value it had prior to the expression]

That anomalous behaviour was indeed part of the "original" IBM APLs, and there
was even an "official" justification for it. I believe that IBM changed that
behaviour as a result of a decision of the standards committee.



That sounded to me as if you were saying that at one time the IBM implementation
returned 15 and they later changed it to return 20.

Perhaps there was something earlier in the thread that I did not see that made
it clear that it was the other way around. Sorry about that.
James L. Ryan

2004-06-16, 8:55 pm

On Wed, 16 Jun 2004 14:43:43 -0500, James J. Weinkam wrote
(in article <caq7st$pso$1@morgoth.sfu.ca> ):

> That sounded to me as if you were saying that at one time the IBM
> implementation returned 15 and they later changed it to return 20.


What I intended to say was that for the expression sequence

X is 5
(X is 10) + X

IBM APL at one time returned 20 and later was changed to return 15.

Sorry for the confusion.

-- James L. Ryan -- TaliesinSoft

Ray Cannon

2004-06-25, 7:20 pm

Back to the origional question
Try

({enclose} 3 3 2 1){pick}{each}{each}{enclose}{each}vecto
r

I seem to recall the idiom

{pick}{each}{each}{enclose}
being called "a chipmonk with glasses"

3 3 2 1{pick}{each}{enclose}'ABC'
CCBA

Ray

"Don Wiss" <donwiss@no_spam.com> wrote in message
news:qhesc09uvrtdd6d74ojnfjjns2qtjjrl35@
4ax.com...
> I am using APL+Win. I have a vector and each element is a vector of the
> same length. For this example let's assume each has three scalars. I'd

like
> to index into each nest and make each have four scalars in a different
> order. If it was a simple vector of three, with no nesting, I would index
> using: [3 3 2 1]. How would I do the same, but have it work on each vector
> in the nested vector?
>
> Thanks, Don <donwiss at panix.com>.



Sponsored Links







Also available: Server administration forum archive | Web Design forum archive | Software forum archive | Hardware reviews archive

Copyright 2008 codecomments.com