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

Reply via email to