Kip Murry wrote
> 3!:0 says the internal type of A is 32,
There is a key word missing here -- "internal". 3!:0 produces the
/internal/ type of its argument.
J is a notation. We can implement this notation in software, but to do so
necessarily requires abstractions from the hardware (because the
specification of the notation does not mention hardware). An
implementation of J may choose to allow its users to interrogate this
abstraction, to augment their powers.
JSoftware's implementation of J has so chosen, through a set of foreigns.
But note that these foreigns answer questions about the particular
/implementation/ of J, not about the /notation/ J. The name "foreign" is
not a coincidence: foreigns deal with things outside of (the notation) J.
One of those things being this particular implementation.
Put another way: J (the Platonic, ideal J) is specified in the first few
sections of the Dictionary, and primarily (for the sake of this
discussion) in the Vocabulary. Foreigns are specified in an appendix;
they are ancillary, a convenience for the user. Special code is another
appendix, which of course only applies to an implementation -- the
notation can't be optimized for performance.
Here's a concrete example. We know J (the notation) requires arrays to be
homogeneous. So it is illegal, for example, to append a numeric array to
a string array:
'5' , 5
|domain error
| '5' ,5
yet, if we reach outside the notation and (ab)use some ancillary tools, we
can apparently violate this principle:
3!:0 '5' NB. strings have internal type 2
2
3!:0 (5) NB. integers have internal type 4
4
string =. 0 $ '5'
integer =. 5
3!:0 string NB. strings have internal type 2
4
3!:0 (5) NB. integers have internal type 4
4
string, (5)
5
is this a peculiarity with , ? Or is it more proper to say,
paraphrasing Raul, that concatentation requires that the set of the atoms
of both arrays be homogeneous?
Returning to ; , we can say that the Platonic, ideal dyad ; specifies
that "x;y is (<x),y if y is boxed, and (<x),<y if y is open". The way to
use the /notation/ (the Vocabulary) to test whether y is open is
(0~:L.)y or (-:>)y .
The implementation, under the covers, then does some work for you to
determine if 0~:L. . If you pull back the covers, you might see where
it's handled some inconvenient details for you (e.g. when y is empty and
happened to be created from a boxed list).
That's the point of covers (abstractions) in the first place: they're there
so you don't have to worry about the details (see concatention example
above). If you avoid the abstractions, then you have to start worrying.
That is, if you're going to use the implementation's tools to answer
notational questions, you have to be as careful as the implementation is
in applying them. In this case, you're going to have to say isBoxed =:
(0 e. $) < 32 = 3!:0 .
But why do this? We're just reimplementing L. . And we may still not
have gotten it right: the interpreter may cover more edge conditions we
haven't encountered.
.... which was all a long way of saying that, if your interest is what you
say it is:
> My interest:
> Properties of E as the empty set, where "set" is modeled as a sorted list of
> boxes, without repetitions, and "element" is the array contained in a box.
> IsSet =: [: *./ (-: /:~),(-: ~.),(1 = #...@$),(32 = 3!:0)
then you should use the notation to answer the question:
IsSet =: [: *./ (-: /:~),(-: ~.),(1 = #...@$),(0~:L.)
This definition is correct theoretically and pragmatically.
-Dan
----------------------------------------------------------------------
For information about J forums see http://www.jsoftware.com/forums.htm