each or not each - designquestion

each or not each - designquestion

Post by Marc Micha » Mon, 20 Jun 2005 20:32:26


Hello,

I am relative new to APL. Using APLX3 on Windows.

I've written a function PING, which simply sends a PING to another host
and returns the time it takes to receive the "PONG".

PING 'turboland.de'
49

But if I have a list of hosts, it doesn't work:

PING 'turboland.de' 'heise.de'
DOMAIN ERROR
PING[1] FOOOST 'COMMAND.COM /C PING ',HOST

If I use the Each-operator on the PING-Function, it works. But, if I
look at the primitive function Negate, it simply works on scalars and
arrays - Without the Each-operator. The question now is: "Why?" Should I
generalize my PING-function to work on every object? But then the
question arises: "Why there exists the Each-Operator?"

Best regards,
Yogi Marc Michael
 
 
 

each or not each - designquestion

Post by Mike Ken » Tue, 21 Jun 2005 12:34:24

arc Michael wrote:

The behavior of the "not" primitive is mirrored by a number
of primitive functions -- {absolute_value}, {arithmetic_negate},
{random_roll} and others: the shape of the result is the same
as the shape of the argument, and the value in each position is
the result of the function application to the scalar in that
position in the argument. Functions that have exhibit this
behavior are special enough to have a name-- they are called
"scalar pervasive" functions. There are scalar pervasive
functions of two arguments (addition, subtraction, max, min,
and, or, ...) that exhibit similar behavior -- the shape and
value of their result is determined by the shape of their
arguments and the application of the same functions between
"corresponding" scalars from the left and right arguments.

Functions that depend on the arguments in second way you
consider for PING (one item in the result for each item in
argument, representing the application of the function to
the corresponding argument item) are called -- IIRC -- scalar
functions (without the "pervasive").

[ Now, many APL primitives are not scalar -- the "shape_of"
function {rho}, for instance. You would not want {rho} to
return a 5 x 20 result when applied to a 5 x 20 matrix; the
idea that it might is "not even wrong". ]

But you are _not_ asking here for PING to work in quite this
way -- you want PING 'x.y.z' to work on the _whole string_
'x.y.z' and NOT on each of its items 'x' '.' 'y' '.' and 'z'.
This is quite reasonable and for utility code it is often
convenient -- but it is not the same kind of behavior that
the APL primitives exhibit. The idea that this is somehow
"natural" arises from a confusion of levels: at the semantic
level and in a particular contest, 'x.y.z' represent "a network
address", and it's sensible to want utility functions to operate
on arrays of network addresses; to the APL interpreter, though,
'x.y.z' is just a vector of characters, and is not really
different from '800.555.1212'. If you're constructing utility
code, you need to be aware of and to think a bit about issues
of this kind; it can make a difference between a function that
is easy to change later _without requiring changes to other
code that depends on it_ and a function that you can't change
because too many other things would break.

There's also the practical issue of the added complexity and
the accompanying chance of introducing a bug when you modify
a function that takes an argument of some specific kind that's
_not_ a simple scalar to work on either a single argument of
the appropriate kind or on an array of such arguments. If you
have a working routine, what do you gain by modifying it so as
not to need {each} to handle the "do this to several things"
situation? If you're writing it from scratch, it is almost
surely simpler to write it to handle the do-one-thing case
and let the caller be responsible for distinguishing between
a direct do-one-thing call and a call through {each} to do
the same thing to several items.

In short: Sometimes you don't want "scalar" behavior. For
code you write, you have to decide, based on your
estimate of the situation and requirements, and on
your experience and best judgment.

Making things simple is rarely simple.

 
 
 

each or not each - designquestion

Post by Marc Micha » Tue, 28 Jun 2005 05:21:12


Many thanks for your text! This is a very interesting point:

'turboland.de' is in the view of APL a vector of chars. It's an array.
But in the view of the user, it's not an array! It's a domain, or a name
of a machine on the net. It's atomic.

Back to APL; It's interesting to see that APL doesn't have Strings. The
type system is more general. Looks to me a little bit like TCL.

Best regards,
Yogi Marc Michael
 
 
 

each or not each - designquestion

Post by balak » Tue, 28 Jun 2005 23:29:13

> Back to APL; It's interesting to see that APL doesn't have Strings. The

Hi Marc,

APLs array structure is more general then array structures of other
languages.
'aaa' is array of characters (you may consider it to be string).
but:
'aaa' 'bbb' is indeed (for most APL versions) two item nested array
with EACH item being string.
That's why you need to use EACH operator to apply function to the EACH
item of nested array.
In your example:
PING[1] FOO,,OST 'COMMAND.COM /C PING ',HOST
if HOST is 'turboland.de' 'heise.de'
derived array:
'COMMAND.COM /C PING ',HOST
is not a string.
It is array with 22 items.
20 items are characters: 'COMMAND.COM /C PING '
and 2 last are nested strings: 'turboland.de' 'heise.de'
This structure may not be considered as string.

If you will use EACH operator
first time it will be 32 item array (string)
'COMMAND.COM /C PING turboland.de'
and second time
'COMMAND.COM /C PING heise.de'
In both cases it will be string.

Look for DISPLAY function in your APL installation, which will be quite
useful to understand arrays in APL (you do not need to use EACH
operator with DISPLAY function but you may try and will see
difference).

Regards,
Alex
 
 
 

each or not each - designquestion

Post by Randy Macd » Mon, 04 Jul 2005 11:54:08


@online.de:


This is quite an interesting statement, given my perception that character
lists _were_ strings. Or perhaps the capitalization means something. What
does this Strings thing have that APL's character lists do not?
 
 
 

each or not each - designquestion

Post by Stefano "W » Tue, 05 Jul 2005 16:34:01

>> Back to APL; It's interesting to see that APL doesn't have Strings. The

Strings are normally considered scalar types. So something similar closer to
a String would be an enclosed character arrayin APL. Jim Brown said the same
thing at the conference in Berlin in his paper "What's wrong with APL2".
http://www.yqcomputer.com/ #con02

--
WildHeart'2k5
 
 
 

each or not each - designquestion

Post by Marc Micha » Wed, 06 Jul 2005 06:19:06


This depends on the language you use for comparisson. For example, in
Smalltalk you can put anything into an Array, even "Functions", Sockets,
or simply Strings.

But this is truly done by a trick: In Smalltalk, all is based on
pointers. So, an Array doesn't hold the value for example of a String
itself, it holds a pointer to a String, or a "Function" or Socket.


This is a good point.


So, my function simply works with an array, an array of chars.


Yes, the DISPLAY function is the most important function to learn APL.


Greets,
Yogi Marc Michael
 
 
 

each or not each - designquestion

Post by Marc Micha » Wed, 06 Jul 2005 06:54:28


*Structure directly described by content.*
In TCL, the only datatype which exists is the String. This means, there
even doesn't exists Numbers! The meaning of the content of a string
simply depends on the function which you call with the string as
argument. If you want to calculate the expression 3+4 you have to call
the function "expr" with the string "3+4" as an argument. The function
will return a string (the %-sign is simply an input-prompt):

(bin) 49 % expr "3 + 4"
7
(bin) 66 % string bytelength [expr "3 + 4"]
1
(bin) 67 % string bytelength [expr "512 + 1024"]
4

Lists of Lists are simply Strings with special characters to describe
the structure:

(bin) 51 % set foo Hallo
Hallo
(bin) 52 % lappend foo Welt
Hallo Welt
(bin) 53 % puts $foo
Hallo Welt
(bin) 54 % lappend foo "Hello World"
Hallo Welt {Hello World}
(bin) 55 % puts $foo
Hallo Welt {Hello World}
(bin) 56 % llength $foo
3
(bin) 57 % string bytelength $foo
24

llength interprets the argument as a list. "sting bytelength" interprets
the argument as a normal string. So, it's possible to change the
structure of the list by simply change the content of the string:

(bin) 59 % set bar "{$foo"
{Hallo Welt {Hello World}
(bin) 63 % set apfel [string replace $bar 11 11 "} "]
{Hallo Welt} {Hello World}
(bin) 64 % llength $apfel
2
(bin) 65 % string bytelength $apfel
26

In contrast, in APL the structure of an Array is encoded internaly in a
way, where a programmer doesn't have access to it. The programmer can
change the structure only by the functions the system provides.

So long,
Yogi Marc Michael