## Shape “Domain Error” Question

Learning APL or new to Dyalog? Ask "silly" questions here, without fear...

### Shape “Domain Error” Question

Hello, I’ve been interested in APL for a while and I’m finally digging into it. I went through the online tutorial and started Legrand’s book as well. It’s a lot to take in (in a good way) so forgive me if I’m overlooking something obvious. I’m reconstructing something in my own way that I believe I saw elsewhere; reshaping a character array into an nxm matrix where each row is padded as is necessary with spaces so they are all the same number of columns. I would like to wrap this all into a monadic function “reshape.”

To start, find length of rows and columns, the left hand side for dyadic shape:

name←'ed' 'sue' 'mike'

(⍴name),(⌈/⍴¨name)

this gives

3 4

The other part; a character vector, padded with spaces, of length “rows x columns” to be reshaped:

∊(⌈/⍴¨name)↑¨name

so far so good, however when I try and put them together, dyadic shape is giving me a “DOMAIN ERROR” message:

((⍴name),⌈/⍴¨name)⍴∊(⌈/⍴¨name)↑¨name

“DOMAIN ERROR”

I can’t figure it out.

The goal is this:

reshape←{((⍴⍵),⌈/⍴¨⍵)⍴∊(⌈/⍴¨⍵)↑¨⍵}

Just to experiment I tried this:

func1←{(⍴⍵),⌈/⍴¨⍵}

func1 name
3 4

func2←{⍺⍴∊(⌈/⍴¨⍵)↑¨⍵}

3 4func2 name
ed
sue
mike

⍝As expected. But…

(func1 name)func2 name
DOMAIN ERROR
func2[0] func2←{⍺⍴∊(⌈/⍴¨⍵)↑¨⍵}

I’m guessing there’s something fundamental in monadic vs. dyadic behavior in DFNs that I’m not getting.

Another experiment:

var← 3 4
var func2 name
ed
sue
mike

⍝As expected. But…

var2← func1 name
var2
3 4
var2 func2 name
DOMAIN ERROR
func2[0] func2←{⍺⍴∊(⌈/⍴¨⍵)↑¨⍵}

Like I said, it seems like something basic that I didn’t pick up. Thanks for your help!
OregonTrailAPL

Posts: 4
Joined: Fri Mar 23, 2018 11:28 am

### Re: Shape “Domain Error” Question

Just a note:

the "∧" in the error messages should be under the "⍴." Copy and paste shifted them.
OregonTrailAPL

Posts: 4
Joined: Fri Mar 23, 2018 11:28 am

### Re: Shape “Domain Error” Question

Hi, and welcome to the APL world!

Your testing is a good example of an innocent error. When you construct the shape, calculating the max length with
`      ⌈/⍴¨name`

produces (reading from left) first a vector of vectors, and then when you apply the maximum reduce, its result is a _nested_ scalar, i.e.
`      ]box onWas OFF      name←'ed' 'sue' 'mike'      ⍴¨name┌─┬─┬─┐│2│3│4│└─┴─┴─┘      ⌈/⍴¨name┌─┐│4│└─┘      (⍴name),⌈/⍴¨name┌─┬─┐│3│4│└─┴─┘`

Because the left argument to reshape cannot be a nested vector, you'll get the dreaded error message.

There are some ways worth experimenting. Using enlist removes the extra nesting:
`      (∊(⍴name),⌈/⍴¨name)⍴∊(⌈/⍴¨name)↑¨nameed  sue mike`

or using tally:
`      ((≢name),⌈/≢¨name)⍴∊(⌈/≢¨name)↑¨nameed  sue mike`

or just simply using disclose
`      ⊃nameed  sue mike`

(there are some people around who use another symbol for disclose, with their low values of []ML :) )

-Veli-Matti
Veli-Matti

Posts: 56
Joined: Sat Nov 28, 2009 3:12 pm

### Re: Shape “Domain Error” Question

Duh! Such an easy fix. Thanks for the insight. I'll know to look for things like this when trouble shooting next time.

Another question,

I have this, "⌈/≢¨⍵", occurring twice in the function.

reshape←{((≢⍵),⌈/≢¨⍵)⍴∊(⌈/≢¨⍵)↑¨⍵}

From an efficiency standpoint, should I worry about the redundancy? If it was a big deal I could go multi-line and do it once and put it in a variable inside the function. However, I was trying to think if there is something from the functional vocabulary like a fork that I could use to tidy that up? I know this is a toy example but for the sake of learning I'm over-thinking things.

Thanks!
OregonTrailAPL

Posts: 4
Joined: Fri Mar 23, 2018 11:28 am

### Re: Shape “Domain Error” Question

Hmm - efficiency...

There are good tools to check the code (for me the optimum is efficient and clear code, sometimes it is quite hard to get). If we check the original code against some variants in v. 17 (and []ML 3):
`      reshape0←{(∊(⍴⍵),⌈/⍴¨⍵)⍴∊(⌈/⍴¨⍵)↑¨⍵}    ⍝ the original function        reshape←{((≢⍵),⌈/≢¨⍵)⍴∊(⌈/≢¨⍵)↑¨⍵}      ⍝ tally-ho!                    reshape2←{wd←⌈/≢¨⍵ ⋄ ((≢⍵),wd)⍴∊wd↑¨⍵}  ⍝ avoid redundancy             reshape3←{((≢⍵),⌈/≢¨⍵)⍴∊⊃⍵}            ⍝ direct cut with disclose      disclose←{⊃⍵}                         ⍝ direct disclose         names←'ed' 'sue' 'mike'                ⍝ the original test set`

The ]runtime user command is handy here (you could as well use the cmpx function in the dfns workspace):

`      ]runtime "disclose names" "reshape0 names" "reshape names" "reshape2 names" "reshape3 names" -compare                                                                             disclose names → 3.7E¯7 |    0% ⎕⎕⎕⎕⎕                                      reshape0 names → 2.9E¯6 | +679% ⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕   reshape names  → 1.9E¯6 | +412% ⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕                 reshape2 names → 1.7E¯6 | +359% ⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕                   reshape3 names → 1.1E¯6 | +183% ⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕`

As I expected - but usually the algorithms need to be tested with a more realistic data:

`      ≢names←↑⎕NGET'B:\lista3.txt' 1          ⍝ a text file with variable line lengths    1585      ]runtime "disclose names" "reshape0 names" "reshape names" "reshape2 names" "reshape3 names" -compare                                                                             disclose names → 8.8E¯5 |    0% ⎕⎕⎕⎕⎕                                      reshape0 names → 6.7E¯4 | +664% ⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕   reshape names  → 3.8E¯4 | +338% ⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕                    reshape2 names → 3.8E¯4 | +334% ⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕                    reshape3 names → 1.3E¯4 |  +52% ⎕⎕⎕⎕⎕⎕⎕⎕`

-Veli-Matti
Veli-Matti

Posts: 56
Joined: Sat Nov 28, 2009 3:12 pm

### Re: Shape “Domain Error” Question

Wow, you gave me a lot to mull over! I really appreciate the long responses, super helpful.

Thanks again!

Carl
OregonTrailAPL

Posts: 4
Joined: Fri Mar 23, 2018 11:28 am