Pascal Jasmin wrote:
> unlambda kind of breaks with a real train, bc `'' adds a 3
> to the verb, and breaks the above assignment.
> unlambda =: 3 : 'a b`:6 c [''a b c'' =. y'
> unlambda 2 + lambdafy 3
> 5
Just to clarify, (`'') is not responsible for that leading 3, nor does the
leading 3 "break" the assignment.
The leading 3 is part of the atomic representation of (+/ % #) . No matter how
you produced the a.r. of that train, whether through ` or 5!:1 or whatever, it
will (or, anyway, should) have that 3.
Atomic representations are a way to represent any J object, of any nameclass,
as a noun. That inherently leads to an ambiguity. For if I have an a.r., and
it is a noun (as all a.r.s are), how can I tell whether it represents e.g. a
verb, and not that specific noun, itself?
For example, if the a.r. of +/ % # were just '+/';'%';'#', how would you
distinguish that from the actual noun, '+/';'%';';'#' ? First answer: you can't.
Better answer: through decoration. The rule for a.r.s is: primitives represent
themselves; all others must have ID ("In Ken we trust; all others pay cash").
The ID takes the form of a marker identifying the type of object represented.
For forks, that marker is (unsurprisingly) '3'; for nouns, it is (also
unsurprisingly) '0'. A complete list can be found under the entry for 5!:1 [1].
So, to distinguish the a.r. of the verb + % # from that of the noun
'+';'%';'#', you simply say what you want. The verb is <'3';<'+';'%';'#' and
the noun is <'0';<'+';'%';'#' (or, following my personal preference, (":verb);<
... vs (":noun);< ... )*.
Anyway, in re your "broken" assignment, it's not broken. Try it:
2 (+/ % #) 3
1.66667 1.66667
unlambda 2 (+/ % #) lambdafy 3
1.66667 1.66667
Though you might find evocative assignment more satisfying:
L =: 1 : '5!:1<''u'' '
2 L, + L, 3 L
+-----+-+-----+
|+-+-+|+|+-+-+|
||0|2|| ||0|3||
|+-+-+| |+-+-+|
+-----+-+-----+
NB. Note absence of `:6 and leading ` left of =.
UL =: 3 : 'a b c [''`a b c'' =. y'
UL 2 L, + L, 3 L
5
But note, for a b c to work, the gerund must be consistent. Because '`a b
c'=.y will evoke each item of y, each item of y must be in an evocable format.
That is, each atom of y must be an atomic representation, including the atoms
that represent nouns. In other words, y must be a gerund (so, rather than
passing in 3, you must pass in (<(":noun);3 ).
-Dan
* In order to reduce visual noise in this series of posts, I've been fairly
liberal in how I format a.r.s. Specifically, I've said things like
<'3';<'+/';'%';'#' when I really should have said <(,'3');<(,'+');(,'%');(,'#')
or '"';something;'0';_ where I should have said (,'"');something;(,'0');_ etc.
In short, the primitives and type markers of a.r.s should be vectors, not
scalars. In fact, the only place where scalars should appear in a.r.s is in the
actual data segments of a.r.s which represent scalar nouns or nouns with boxed
scalars.
Now, J is as permissive in its parsing of a.r.s as I have been in my formatting
of them [2], but I wouldn't like to count on that in production code. It's
better practice to format them strictly. That's one reason I prefer (":noun) -
it already produces a vector, whereas '0' is a scalar, which I must ravel
myself (and ,'0' is just ugly).
[1] Definition of 5!:1, including table of type-markers:
http://www.jsoftware.com/help/dictionary/dx005.htm#1
[2] Bug report: "define" is permissive
http://www.jsoftware.com/jwiki/System/Interpreter/Bugs?highlight=%28permissive%29#define_is_permissive
-----Original Message-----
From: [email protected]
[mailto:[email protected]] On Behalf Of Pascal Jasmin
Sent: Sunday, November 03, 2013 11:06 AM
To: [email protected]
Subject: Re: [Jprogramming] making a 'first' adverb tacit
Here is an interesting use case:
lambdafy =: 1 : ('u`'''';y';':';'x;u`'''';y')
lambdafy
1 : 0
u`'';y
:
x;u`'';y
)
2 + lambdafy 3
┌─┬───┬─┐
│2│┌─┐│3│
│ ││+││ │
│ │└─┘│ │
└─┴───┴─┘
unlambda =: 3 : 'a b`:6 c [''a b c'' =. y'
unlambda 2 + lambdafy 3
5
unlambda kind of breaks with a real train, bc `'' adds a 3 to the verb, and
breaks the above assignment.
(+/ % #)`''
┌─────────────────┐
│┌─┬─────────────┐│
││3│┌───────┬─┬─┐││
││ ││┌─┬───┐│%│#│││
││ │││/│┌─┐││ │ │││
││ │││ ││+│││ │ │││
││ │││ │└─┘││ │ │││
││ ││└─┴───┘│ │ │││
││ │└───────┴─┴─┘││
│└─┴─────────────┘│
└─────────────────┘
even if this still works.
(+/ % #)`''`:6
+/ % #
Not necessarily with this exact example, but I can see the overall usefullness
for passing around executions for delayed/async execution or to another core or
computer.
----- Original Message -----
From: Dan Bron <[email protected]>
To: [email protected]
Cc:
Sent: Sunday, November 3, 2013 10:10:05 AM
Subject: Re: [Jprogramming] making a 'first' adverb tacit
Pascal Jasmin wrote:
> (`'') is an anonymous tacit adverb that will produce the atomic rep
>of
> its verb argument that seems pretty cool, but I haven't been able to
> grasp a use for it yet.
Advanced adverbial programming -- past the outskirts of (`:6), beyond the
hinterlands of the sneaky agenda trick -- often involves transforming atomic
representations. That is, writing verbs which take a.r.s as input and produce
different, related a.r.s as output. The adverb (`'') is a short, simple way to
convert input into its atomic representation, and so prepare it for further
transformation.
Think of it as anesthesia for verbs: like people, verbs prefer to be
unconscious during surgery, so (`'') puts them under the beginning, and
(`:6) wakes them up at the end, transformed.
-Dan
PS: "But wait,", you remark, "adverbs can take nouns for input as well as
verbs. So what implications does (`'') have for them?". Good question. It
really depends on what your adverb is doing. The first thing to note is that
(`'') is mostly an identity function for nouns: x`'' is identical to x, except
where x is scalar, in which case it's identical to ,x (viz, x,'' ).
So, in a sense, (`'') is a normalizing preprocessor: it ensures all inputs are
nouns (verbs are converted to nouns, and nouns are left alone, mostly).
So, if your only requirement is that the inputs to the core of your adverb are
nouns, (`'') is perfect. However, since we're discussing the method of
adverbial programming which transforms atomic representations, we require a
deeper normalization than that. Recall that (`'') converts verbs to nouns, but
not any old nouns; no, verb inputs are converted to a special type of noun, in
a restricted domain: atomic representations. So, to really put verb and noun
inputs on equal footing, to achieve true homogenization, so that our core
transformation doesn't have to care whether the original input was a verb or a
noun (unless it wants to), we need to do something extra.
We need to force nouns into the same restricted domain as verbs: to
nondestructively convert a noun to its own atomic representation.
One quick, cute (and arguably elegantly symmetric) method to do that is
simple: just convert all nouns to verbs before converting all verbs to nouns!
But ... doesn't that beg the question? Surely if we could distinguish noun from
verb input, we wouldn't need to convert nouns to verbs in the first place? Or,
conversely, if we try to coerce nouns to verbs without knowing what kind of
input we have, won't that have unintended consequences for verbal input?
Well, kinda. What we'd really like is some kind of identity adverb. Sort of
like (`''), which converts verbs to nouns and (mostly) leaves nouns alone.
Only we want its dual: we wish to convert nouns to verbs, and leave verbs
(mostly) alone. Sound familiar?
Convert noun to verb: N"_ . Leave verb (mostly) alone: f"_ . Tada!
So, how's this for a homogenizing utility adverb? ("_) (`'') . Pretty sweet!
First, all nouns are converted to verbs (N"_) and verbs are mostly left alone
(f"_ will never change the results of f applied to arguments, though it may
change other verbs derived from f ). Second, all verbs (now
meaning: all input) are converted to nouns, specifically atomic
representations. Voila! We have evolved from raw chloroform to balanced
anesthesia.
Of course, there are some artifacts left behind: the needle in the vein, or the
mask over the face, which may interfere with our operation. But, since the
patient is safely knocked out, we can remove these extranea without fear; he'll
sleep until we're ready to wake him. In this case, the obstructive mask is
("_) : our verb (or noun) wasn't wearing that when he walked in. Let's take it
off, and give ourselves complete access to the patient.
knockOut =: ("_) (`'')
strip =: ((<":noun)`) (({.@>@{:)`) (@.(0; 1 2))
prep =: knockOut strip
ar =: 1 : '5!:1<,''u'''
(+ ar ) -: + prep NB. a.r. of plus
1
(+/ ar) -: +/ prep NB. a.r. of sum
1
(3 ar ) -: 3 prep NB. a.r. of three
1
(a: ar) -: a: prep NB. a.r. of ace
1
Pretty neat. A tacit adverb which produces the unadulterated atomic
representation of its input, with a total domain (i.e. all nouns and all
verbs: everything an adverb could possibly take as an argument).
However, we lost a little something of the elegance of 'knockOut' by
introducing 'strip' (which I considered naming 'stripNude', but since the NSA
is watching, I thought it prudent to be more prudish). As compensation, 'strip'
serves both as a self-documenting example and a utility. That is, it
demonstrates how to manipulate atomic representations to modify code, while
also producing exactly the a.r.s intended to be so manipulated. And, as a
utility, it can save you a step. Rather than use the output of 'strip', you
could layer your own transformation on top of the one it applies, and then
execute the result.
For example:
stripNtriple =: ((<":noun)`) (((<3;~":noun),#`'',{.@>@{:)`) (@.(0; 1 2))
+/ knockOut stripNtriple 1 2 3
6 6 6
6 knockOut stripNtriple
6 6 6
Anyway, that's the "why" and "how" of (`''). For more examples of the "what",
try searching the Forum archives or the Wiki for instances of (`'') or (''`) .
PPS: Exercise for the very ambitious reader: define a tacit adverb opTheat
(operating theatre), which, given a verb (the surgeon), derives another tacit
adverb, such that
surgeon OpTheat
((<":0)`) (surgeon`) (@.(0; 1 2))
The objective is to be able to provide an convenient utility / interface for
adverbial programmers, so that their responsibility is only to write the core
a.r.-transforming function (i.e. perform the surgery), and not always have to
prepare the patient and the operating theatre themselves.
Note that excessive quoting will somewhat defeat the purpose of the exercise
(defining the adverb _tacitly_; it's easy to do explicitly, exactly because
that's just quoted code).
----------------------------------------------------------------------
For information about J forums see http://www.jsoftware.com/forums.htm
----------------------------------------------------------------------
For information about J forums see http://www.jsoftware.com/forums.htm
----------------------------------------------------------------------
For information about J forums see http://www.jsoftware.com/forums.htm