Keep running into this (help!)

Keep running into this (help!)

Post by pineappl » Mon, 26 Jan 2009 16:57:37


Call me "slow," but despite having used APL for several months now, I
keep running into the same problem and have not found a suitable
solution.

I am forever confronted with the following type of situation:

x (is or gets) (some condition) / 3

x has the potential to get assigned "nothing." I always struggle to
deal with this. The shape of nothing is 0, and I can test for that.
But then the problem is that the shape of "something" is sometimes
"nothing" (for instance, the shape of a scalar). How the heck do I
test for that? I end up having to check whether the shape of nothing
is 0, then whether the shape of something is nothing, etc. The code
just gets messier and messier as I struggle to deal with more and more
situations which will cause the program to explode if I DON'T check
for these situations. I would swear that I've even been confronted
with checking for the shapes of different TYPES of nothings. For
instance, "1 rho 0" appears as "nothing," but has a different shape
than other "nothings." It just gives me a headache every time I sit
down to write some APL.

Bottom line, what on earth is the solution to this? What's the
standard way APL'ers deal with it? I mean, it has to be something
laughably simple - something I just missed or never learned.

Thanks.
 
 
 

Keep running into this (help!)

Post by pineappl » Mon, 26 Jan 2009 17:02:46


Whoops. I meant to say that "1 0 rho 0" appears as "nothing," but has
a different shape than other "nothings" ("0 rho 0," for instance).

 
 
 

Keep running into this (help!)

Post by kaithomasm » Mon, 26 Jan 2009 17:35:50


Of course: an empty vector must be different from a matrix which has
one row but no columns!

As to your other question:

{0 1 (1 2) (2 2) (1 0) (0 1)

So the expression returns a 1 if the array tested is..., well how to
put this? ... somehow empty.
 
 
 

Keep running into this (help!)

Post by Ibeam200 » Tue, 27 Jan 2009 01:09:01

With an expression like

X := (PARM = 6) / 3

depending on the value of the boolean condition, the result of the
compression can be two things:

If true, X is a one element vector. 1 / scalar is a vector
If false, X is an empty vector, like iota zero. 0 / scalar is an
empty numeric vector, same as iota 0.

Most APLs have a symbol for this, the Zilde, zero overstruck with a
not sign (called a tilde, hence zilde). It is identical to iota 0.

My usual test for emptyness is 0 element rho X.

There are types of nothings. If you have a nested array and do a 0/
of it, it is an empty vector, but there is prototype information
stored. Caution: Different APLs treat this differently.

Also, a character empty is the not the same as a numeric empty. A
character nothing is ''.

Zilde == '' is false (match function)

Generally you don't have to pay attention to scalars vs. one element
vectors with things like normal branches. However, with the Case
statement, the shape does matter.

In APL, there is no such thing as "Nothing". Instead, there is VALUE
ERROR.

If you have a scalar and want a vector, ,X
If you have a vector and want the first element as a scalar, take X.
(Monadic take, the up arrow)

In the old days,

(iota 0) rho X

would give you the first element of a vector as a scalar. The shape
of a scalar is iota 0

'' rho X

would do the same.
 
 
 

Keep running into this (help!)

Post by pineappl » Tue, 27 Jan 2009 07:19:57


> So the expression returns a 1 if the array tested is..., well how >o
> put this? ... somehow empty.

So the function I need is on the left (I THINK I understand it), and
you have plugged in an example array to test on the right?

Thanks for the help, and I am somewhat relieved to know that yae,
verily, this is an issue that other APL'ers deal with. I half
expected someone to say "Why are you testing for all this crap? Just
do blah blah and be done with it!"

Thanks to the other poster as well.
 
 
 

Keep running into this (help!)

Post by kaithomasm » Tue, 27 Jan 2009 07:28:52

> So the function I need is on the left (I THINK I understand it), and

Sorry, I should have been absolutely clear but I wasn't.

I try again: The expression you need is
0

Examples:

0 1
0 1
0
0 1 2
0
0 2 2
0
0 1 0
1
0 0 1
1
 
 
 

Keep running into this (help!)

Post by pineappl » Tue, 27 Jan 2009 18:53:08


You were fairly clear the first time. What you write here is more or
less what I had gathered previously.

THANKS!
 
 
 

Keep running into this (help!)

Post by Gosi » Wed, 28 Jan 2009 00:05:31


Instead of checking for what a variable is not you might assert
instead that it is what you expect and in some cases use try and
catch.
 
 
 

Keep running into this (help!)

Post by James J. W » Sat, 31 Jan 2009 16:27:28


Others have told you how to do what you asked. I venture to say that you
should endeavor to avoid having to make such a test in the first place.

If you think about what your are doing, you will see that you have found
out something, (some condition), and used that knowledge to decide
whether to assign 3 or an empty numeric vector to x. You have then gone
on to forget what you have learned and have to find it out all over again.

This is not a good plan.

(Incidentally, with regard to the question you asked, one obvious way to
"test for that" that I didn't see anyone mention is to test the same
condition you tested in the first place. And that should show you what
you are doing wrong. Why test the same condition twice?)

The secret is not to forget what you learned in the original test until
you have no further need of the knowledge.

For example:

{goto}(some condition)/true
do whatever you need to do only when x does not get a value
{goto}merge
true: x{is}3
do whatever you need to do only when x does get a value
merge:
do whatever you need to do in either case
...

APL has much less need of explicit branching than other languages, but
there are cases where it is useful.

Notice by the way, that if the value to be assigned to x is not a
constant but the result of a complex computation, your formulation
(remember right to left execution) computes that value and throws it
away if (some condition) is false, whereas my suggested approach doesn't
compute the value unless it is actually needed.