Nested explicit definitions - nested

For the sake of argument, let's say I want the following program:
foo =: monad define
bar =. dyad define
x * y
)
bar/ y * 2 3
)
Ideally, for input 3, this would yield 54. However, when putting this into the console, the first of the two )s is treated as the ending for the first define. Is there any way to prevent this? I want to avoid an inline verb, like monad def 'x * y'. My actual verb example is more complex than this.

You can not have nested multiline definitions as there is no check for the contents of the definition. The definition ends and saved on the first encounter of ^)LF.
a multiline body is a script terminated by a solo right parenthesis, so we cannot have one such body inside another.
There are (messy) ways to go around this, for example by forming strings and evaluating them:
foo =: monad define
str =. 'x * y'
bar =. 4 : (str,:'')
bar /y * 2 3
)
foo 3
54
Maybe forming a helper adverb is a better idea.
(edit) Example by defining bar's body separately:
bar_body =: 0 : 0
c=. x + y
c * y
)
foo =: 3 : 0
bar =. 4 : bar_body
bar/y * 2 3
)
foo 3
135

The nested terminating ')'s are problematic, but this could work
foo =: monad define
bar =. 4 : 'x * y'
bar/ y * 2 3
)
foo 3
54
Multiple lines in bar definition could just be consecutive boxed
strings.
foo =: monad define
bar =. 4 : ('t=.x * y';'t+1') NB. parenthesis required
bar/ y * 2 3
)
foo 3
55

The absence of nested blocks was an intentional design decision.
The idea is to put pressure on the developer to name blocks. (And, more generally, there's some significant pressure on the developer to favor concise, simple code.)
That said, adverbs (and conjunctions) can be used to tie blocks together.

Related

Creating y shape random float array in J

I am trying to creating y shape random float array, and this is my current right now:
input_dim =: 2
hidden_dim =: 16
0 ?#$ ~ (input_dim, hidden_dim)
0.838135 0.96131 0.766721 0.420625 0.640265 0.683779 0.683311 0.427981 0.281479 0.305607 0.385446 0.898389 0.24596 0.452391 0.739534 0.973384
0.914155 0.172582 0.146184 0.624908 0.333564 0.132774 0.475515 0.802788 0.277571 0.146896 0.40596 0.735201 0.943969 0.259493 0.442858 0.374871
It seems like this code returns what I exactly want, so I tried to make a function like below:
rand =: 0 ?#$ ~
but rand (input_dim, hidden_dim) gives me a syntax error...
I think I am missing one very important part, but I am not sure what that is.
Any advice would be grateful!
The only thing missing from your verb is ].
That is:
rand =: 0 ?#$~ ]
rand 2 3
0.891663 0.888594 0.716629
0.9962 0.477721 0.946355
Potentially your confusion arose because you were wanting to create a fork of the form (noun verb verb), however ~ is an adverb and so combines with the verb to its left to create a new verb (in your case ?#$~) so your rand had the form (0 ?#$~) or (noun verb) which J does not recognise - hence the syntax error.
It makes sense to use the combination ?#$ if possible because it is supported by special code and does not create x $ y.
Without the argument, the syntax of 0 ?#$ ~ is ambiguous and the interpreter missclassifies the parenthesization (or, more accurately, the correct parenthesization is not the one you think it is).
The easiest way around this is to define rand as:
rand =: 3 :'0 ?#$ ~ y'
Of course, any other way of removing the syntactic ambiguity will also work:
rand =: [: ? 0 $~ ]
rand =: ?#(0$~])
rand =: ?#(0&($~))
...

How to count each list length in K?

On a page https://shakti.com/tutorial/ I've found the solution, it is
#:'z / counts each list
The same solution was mentioned in https://code.kx.com/v2/learn/startingkdb/language/ by switching to k mode in q:
q) #:'(1 2;"abc") / equivalent k expression
2 3
Why this expression #:' counts the number?
# counts
' is an each Adverb
but what : means in this case? This is not an assignment, right?
On a page http://www.math.bas.bg/bantchev/place/k.html they mentioned that:
: within |: is used to force the verb | to be interpreted as a monad,
as by default ambiguities are resolved in favour of dyads
Also here http://web.archive.org/web/20050504070651/http://www.kx.com/technical/documents/kreflite.pdf noted about the same:
Note that whenever Each is applied to the monad of a primitive verb,
as in !:' for Enumerate-Each, the monadic case must be made explicit
by modifying the verb with colon. The dyadic case is assumed if no
modifier is present.
And that's make sense:
/ # want's to act as dyadic verb
#' (1 2; "abc")
#'[(1 2;"abc")]
/ make use of dyadic # behavior
5 6 #' (1 2; "abc")
(1 2 1 2 1;"abcabc")
/ monadic case
#:' (1 2; "abc")
2 3

Understanding trains with literal values in J

I'm sure this is obvious but I'm a little unclear about it. Suppose I wanted to make a function do something like f(x) = 3x+1. Knowing the rule for forks, I expect to see something like this: [: 1&+ 3&* which is not that beautiful to me, but I guess is nicer looking that (1&+) #: (3&*) with the extra parentheses. Instead, if I query with 13: I get this:
13 : '1+3*y'
1 + 3 * ]
Way more beautiful, but I don't understand how it is possible. ] is the identity function, * and + are doing their usual thing, but how are the literals working here? Why is J not attempting to "call" 1 and 3 with arguments as if they are functions? I notice that this continues to do the right thing if I replace any of the constants with [ or ], so I think it is interpreting this as a train of some kind, but I'm not sure.
When J was first described, forks were all verbs (V V V), but then it was decided to let nouns be in the left tine position and return their face value. So (N V V) is seen as a fork as well. In some older code you can see the left tine of the fork show up as a 'verbified' noun such as 1: or 'a'"_ which act as verbs that return their face value when given any argument.
(N V V) configuration is described in the dictionary as "The train N g h (a noun followed by two verbs) is equivalent to N"_ g h ." http://www.jsoftware.com/help/dictionary/dictf.htm

Why does map-each preserve the last value for references to the word to set?

map-each can be used to evaluate some code for every member in a collection, and aggregate the results of the evaluation in a block:
>> values: map-each x [1 2] [
print ["Doing mapping for" x]
x * 10
]
Doing mapping for 1
Doing mapping for 2
== [10 20]
I was building a block of blocks in this way. But I forgot that since blocks aren't evaluated by default, the x would be left as-is and not get the value I wanted:
>> blocks: map-each x [1 2] [
print ["Doing mapping for" x]
[x * 10]
]
Doing mapping for 1
Doing mapping for 2
== [[x * 10] [x * 10]]
No surprise there. After the evaluation x has no value--much less the ability to take on many values:
>> probe x
** Script error: x has no value
So it's too late, the evaluation must be done with a REDUCE or COMPOSE inside the body of the map-each. But...
>> reduce first blocks
== [20]
>> reduce second blocks
== [20]
The evaluations of items in the result block don't throw an error, but behave as if x had the value of the last iteration.
How is it doing this? Should it be doing this?
Just like 'FOREACH, 'MAP-EACH binds the block you give it within a context it creates and executes it there.
the X is never created globally. the fact that you gave it a word (and not a lit-word) as an argument is managed by the function's interface which probably uses the lit-word notation, and uses the word given, as-is, un-evaluated, instead of the value it may contain.
for this reason, the X used in your call to map-each doesn't trigger a
** Script error: x has no value
since map-each is grabbing it before it gets evaluated and only uses the word as a token, directly.
To illustrate how binding works more vividly and to show how 'X may survive existence past its original context, here is an example which illustrates the foundation of how words are bound in Rebol (and the fact that this binding persists).
look at this example:
a: context [x: "this"]
b: context [x: "is"]
c: context [x: "sensational!"]
>> blk: reduce [in a 'x in b 'x in c 'x]
== [x x x]
x: "doh!"
== "doh!"
>> probe reduce blk
["this" "is" "sensational!"]
We created a single block with three 'X words, but none of them are bound to the same context.
Because the binding in Rebol is static, and scope doesn't exist, the same word can have different values, even when they are being manipulated in the same context (in this case the console is the global | user context).
This is the penultimate example of why a word is really NOT a variable in Rebol.
blocks: map-each x [1 2] [
print ["Doing mapping for" x]
[x * 10]
]
probe bound? first blocks/1
gives this
Doing mapping for 1
Doing mapping for 2
make object! [
x: 2
]

replace within boxed structure

I have the following (for example) data
'a';'b';'c';'a';'b';'a'
┌─┬─┬─┬─┬─┬─┐
│a│b│c│a│b│a│
└─┴─┴─┴─┴─┴─┘
and I'd like to replace all 'a' with a number, 3, and 'b' with another number 4, and get back
┌─┬─┬─┬─┬─┬─┐
│3│4│c│3│4│3│
└─┴─┴─┴─┴─┴─┘
how can I do that?
Thanks for help.
rplc
If that was a string (like 'abcaba') there would be the easy solution of rplc:
'abcaba' rplc 'a';'3';'b';'4'
34c343
amend }
If you need to have it like boxed data (if, for example, 'a' represents something more complex than a character or atom), then maybe you can use amend }:
L =: 'a';'b';'c';'a';'b';'a'
p =: I. (<'a') = L NB. positions of 'a' in L
0 3 5
(<'3') p } L NB. 'amend' "3" on those positions
putting the above into a dyad:
f =: 4 :'({.x) (I.({:x) = y) } y' NB. amend '{.x' in positions where '{:x' = y
('3';'a') f L
┌─┬─┬─┬─┬─┬─┐
│3│b│c│3│b│3│
└─┴─┴─┴─┴─┴─┘
which you can use in more complex settings:
]L =: (i.5);'abc';(i.3);'hello world';(<1;2)
┌─────────┬───┬─────┬───────────┬─────┐
│0 1 2 3 4│abc│0 1 2│hello world│┌─┬─┐│
│ │ │ │ ││1│2││
│ │ │ │ │└─┴─┘│
└─────────┴───┴─────┴───────────┴─────┘
((1;2);(i.3)) f L
┌─────────┬───┬─────┬───────────┬─────┐
│0 1 2 3 4│abc│┌─┬─┐│hello world│┌─┬─┐│
│ │ ││1│2││ ││1│2││
│ │ │└─┴─┘│ │└─┴─┘│
└─────────┴───┴─────┴───────────┴─────┘
btw, {.y is the first item of y; {:y is the last item of y
bottom line
Here's a little utility you can put in your toolbox:
tr =: dyad def '(y i.~ ({." 1 x),y) { ({:" 1 x) , y'
] MAP =: _2 ]\ 'a';3; 'b';4
+-+-+
|a|3|
+-+-+
|b|4|
+-+-+
MAP tr 'a';'b';'c';'a';'b';'a'
+-+-+-+-+-+-+
|3|4|c|3|4|3|
+-+-+-+-+-+-+
just above the bottom line
The utility tr is a verb which takes two arguments (a dyad): the right argument is the target, and the left argument is the mapping table. The table must have two columns, and each row represents a single mapping. To make just a single replacement, a vector of two items is acceptable (i.e. 1D list instead of 2D table, so long as the list is two items long).
Note that the table must have the same datatype as the target (so, if you're replacing boxes, it must be a table of boxes; if characters, then a table of characters; numbers for numbers, etc).
And, since we're doing like-for-like mapping, the cells of the mapping table must have the same shape as the items of the target, so it's not suitable for tasks like string substitution, which may require shape-shifting. For example, ('pony';'horse') tr 'I want a pony for christmas' won't work (though, amusingly, 'pony horse' tr&.;: 'I want a pony for christmas' would, for reasons I won't get into).
way above the bottom line
There's no one, standard answer to your question. That said, there is a very common idiom to do translation (in the tr, or mapping 1:1, sense):
FROM =: ;: 'cat dog bird'
TO =: ;: 'tiger wolf pterodactyl'
input=: ;: 'cat bird dog bird bird cat'
(FROM i. input) { TO
+-----+-----------+----+-----------+-----------+-----+
|tiger|pterodactyl|wolf|pterodactyl|pterodactyl|tiger|
+-----+-----------+----+-----------+-----------+-----+
To break this down, the primitive i. is the lookup function and the primitive { is the selection function (mnemonic: i. gives you the *i*ndex of the elements you're looking for).
But the simplistic formulation above only applies when you want to replace literally everything in the input, and FROM is guaranteed to be total (i.e. the items of the input are constrained to whatever is in FROM).
These contraints make the simple formulation appropriate for tasks like case conversion of strings, where you want to replace all the letters, and we know the total universe of letters in advance (i.e. the alphabet is finite).
But what happens if we don't have a finite universe? What should we do with unrecognized items? Well, anything we want. This need for flexibility is the reason that there is no one, single translation function in J: instead, the language gives you the tools to craft a solution specific to your needs.
For example, one very common extension to the pattern above is the concept of substitution-with-default (for unrecognized items). And, because i. is defined to return 1+#input for items not found in the lookup, the extension is surprisingly simple: we just extend the replacement list by one item, i.e. just append the default!
DEFAULT =: <'yeti'
input=: ;: 'cat bird dog horse bird monkey cat iguana'
(FROM i. input) { TO,DEFAULT
+-----+-----------+----+----+-----------+----+-----+----+
|tiger|pterodactyl|wolf|yeti|pterodactyl|yeti|tiger|yeti|
+-----+-----------+----+----+-----------+----+-----+----+
Of course, this is destructive in the sense it's not invertible: it leaves no information about the input. Sometimes, as in your question, if you don't know how to replace something, it's best to leave it alone.
Again, this kind of extension is surprisingly simple, and, once you see it, obvious: you extend the lookup table by appending the input. That way, you're guaranteed to find all the items of the input. And replacement is similarly simple: you extend the replacement list by appending the input. So you end up replacing all unknown items with themselves.
( (FROM,input) i. input) { TO,input
+-----+-----------+----+-----+-----------+------+-----+------+
|tiger|pterodactyl|wolf|horse|pterodactyl|monkey|tiger|iguana|
+-----+-----------+----+-----+-----------+------+-----+------+
This is the strategy embodied in tr.
above the top line: an extension
BTW, when writing utilities like tr, J programmers will often consider the N-dimensional case, because that's the spirit of the language. As it stands, tr requires a 2-dimensional mapping table (and, by accident, will accept a 1-dimensional list of two items, which can be convenient). But there may come a day when we want to replace a plane inside a cube, or a cube inside a hypercube, etc (common in in business intelligence applications). We may wish to extend the utility to cover these cases, should they ever arise.
But how? Well, we know the mapping table must have at least two dimensions: one to hold multiple simultaneous substitutions, and another to hold the rules for replacement (i.e. one "row" per substition and two "columns" to identify an item and its replacement). The key here is that's all we need. To generalize tr, we merely need to say we don't care about what's beneath those dimensions. It could be a Nx2 table of single characters, or an Nx2 table of fixed-length strings, or an Nx2 table of matrices for some linear algebra purpose, or ... who cares? Not our problem. We only care about the frame, not the contents.
So let's say that, in tr:
NB. Original
tr =: dyad def '(y i.~ ({." 1 x),y) { ({:" 1 x) , y'
NB. New, laissez-faire definition
tr =: dyad def '(y i.~ ({."_1 x),y) { ({:"_1 x) , y'
A taxing change, as you can see ;). Less glibly: the rank operator " can take positive or negative arguments. A positive argument lets the verb address the content of its input, whereas a negative argument lets the verb address the frame of its input. Here, "1 (positive) applies {. to the rows of the x, whereas "_1 (negative) applies it to the the "rows" of x, where "rows" in scare-quotes simply means the items along the first dimension, even if they happen to be 37-dimensional hyperrectangles. Who cares?
Well, one guy cares. The original definition of tr let the laziest programmer write ('dog';'cat') tr ;: 'a dog makes the best pet' instead of (,:'dog';'cat') tr ;: 'a dog makes the best pet'. That is, the original tr (completely accidentally) allowed a simple list as a mapping table, which of course isn't a Nx2 table, even in an abstract, virtual sense (because it doesn't have at least two dimensions). Maybe we'd like to retain this convenience. If so, we'd have to promote degenerate arguments on the user's behalf:
tr =: dyad define
x=.,:^:(1=##$) x
(y i.~ ({."_1 x),y) { ({:"_1 x) , y
)
After all, laziness is a prime virtue of a programmer.
Here's the simplest way I can think of to accomplish what you have asked for:
(3;3;3;4;4) 0 3 5 1 4} 'a';'b';'c';'a';'b';'a'
┌─┬─┬─┬─┬─┬─┐
│3│4│c│3│4│3│
└─┴─┴─┴─┴─┴─┘
here's another approach
(<3) 0 3 5} (<4) 1 4} 'a';'b';'c';'a';'b';'a'
┌─┬─┬─┬─┬─┬─┐
│3│4│c│3│4│3│
└─┴─┴─┴─┴─┴─┘
Hypothetically speaking, you might want to be generalizing this kind of expression, or you might want an alternative. I think the other posters here have pointed out ways of doing that. . But sometimes just seeing the simplest form can be interesting?
By the way, here's how I got my above indices (with some but not all of the irrelevancies removed):
I. (<'a') = 'a';'b';'c';'a';'b';'a'
0 3 5
('a') =S:0 'a';'b';'c';'a';'b';'a'
1 0 0 1 0 1
('a') -:S:0 'a';'b';'c';'a';'b';'a'
1 0 0 1 0 1
I.('a') -:S:0 'a';'b';'c';'a';'b';'a'
0 3 5
I.('b') -:S:0 'a';'b';'c';'a';'b';'a'
1 4

Resources