Assert Dfn

General APL language issues

Assert Dfn

Postby rbe on Wed May 08, 2019 7:28 pm

I'm looking for an assertion function that will operate correctly under a Dfn.
Mine (similar to Hui's, below) fails in a Dfn:

assert←{⍺←'assertion failure' ⋄ 0∊⍵:⍺ ⎕signal 8 ⋄ shy←0}

E.g.:

No result was provided when the context expected one
Dfn2Trad[5] ('Expected assignment arrow for Dfn ',fnm)assert'←'=1↑t

I'm probably doing something dumb, of course...

Bob
rbe
 
Posts: 9
Joined: Fri Apr 13, 2018 7:55 pm

Re: Assert Dfn

Postby kai on Thu May 09, 2019 4:01 pm

You just forgot 1:

      assert←{⍺←'assertion failure' ⋄ 0∊⍵:⍺ ⎕signal 8 ⋄ 1:shy←0}


Shouldn't an assert function expect 1 as argument and signal an error in all other cases?

      assert←{⍺←'assertion failure' ⋄ (,1)≢,⍵:⍺ ⎕signal 8 ⋄ 1:shy←0}


Using 8 is kind of brave: it's one of the reserved yet undefined error numbers. You might be better off using a number in the range of 500-999 which are reserved for user defined events if you don't want to go for something like 11 (DOMAIN ERROR).
User avatar
kai
 
Posts: 137
Joined: Thu Jun 18, 2009 5:10 pm
Location: Hillesheim / Germany

Re: Assert Dfn

Postby gil on Thu May 09, 2019 7:31 pm

I'm confused. I meant to give the same reply as Kai this morning, but when I tested the expression Bob wrote, it worked fine for me. Tested now again in both 16.0 and 17.0 and I get the expected result. There seems to be a difference though between a one-liner and a multi-line dfn:
      ⎕CR'shy1'
shy1←{s←⍵}
⎕CR'shy2'
shy2←{
s←⍵
}
⎕CR'shy3'
shy3←{
1:s←⍵
}
⎕←shy1 1
1
⎕←shy2 1
VALUE ERROR: No result was provided when the context expected one
⎕←shy2 1

⎕←shy3 1
1
shy1 1
shy2 1
shy3 1
gil
 
Posts: 71
Joined: Mon Feb 15, 2010 12:42 am

Re: Assert Dfn

Postby Phil Last on Thu May 09, 2019 8:59 pm

John explained (I think his word was "excused") the difference between shy1 and shy2 on the grounds that the interpreter knows that "s←⍵" in shy1 is the last expression because it's followed immediately by the brace "}".
      shy4←{s←⍵⋄}
behaves as shy2.
User avatar
Phil Last
 
Posts: 624
Joined: Thu Jun 18, 2009 6:29 pm
Location: Wessex

Re: Assert Dfn

Postby gil on Thu May 09, 2019 9:16 pm

Ah, thanks for that Phil!
And following on form that I get:
      shy5←{  
s←⍵}


behaving like shy1.

I guess it is safest to always prefix with a true guard `1:` to make sure it doesn't rely on a trailing `}`.
gil
 
Posts: 71
Joined: Mon Feb 15, 2010 12:42 am

Re: Assert Dfn

Postby Roger|Dyalog on Sun May 12, 2019 3:36 am

assert as written is correct.
Code: Select all
assert←{⍺←'assertion failure' ⋄ 0∊⍵:⍺ ⎕SIGNAL 8 ⋄ shy←0}
(It was in fact written on advice from the master, John Scholes.) To use it, in a tradfn you just say assert blah ; but in a dfn you have to say assert blah: (with the trailing colon). For example:

First, tradfn:

Code: Select all
z←x tradfn y
assert x=y 
z←x+y

      2 tradfn 3
assertion failure
tradfn[1] assert x=y
          ∧
      →
      3 tradfn 3
6

Now, dfn:
Code: Select all
dfn←{       
 assert ⍺=⍵:
 ⍺+⍵       
}   

      2 dfn 3
assertion failure
dfn[1] assert ⍺=⍵:
       ∧
      →
      3 dfn 3
6
Roger|Dyalog
 
Posts: 238
Joined: Thu Jul 28, 2011 10:53 am

Re: Assert Dfn

Postby rbe on Sun May 12, 2019 9:18 pm

Wow. More than I expected. Thanks!

Bob
rbe
 
Posts: 9
Joined: Fri Apr 13, 2018 7:55 pm

Re: Assert Dfn

Postby kai on Mon May 13, 2019 5:12 pm

assert as written is correct.


I object. Although naming the result `shy` when it is not shy does not hurt in terms of functionality it's misleading because it is not shy.

(It was in fact written on advice from the master, John Scholes.)


Interesting; I never heard anything about this. In the dfns workspace there are just three functions which have a colon as the very last character.

But this technique is actually quite useful.

Given these functions:

Code: Select all
∇ rc←DoSomething
 [1] ⍝ Dummy
rc←0


∇ {r}←Log msg
 [1]  r←⍬
 [2] ⍝ dummy log function


 Test_1←{
     rc←DoSomething
     _←assert 0=rc
     ⍬
 }

 Test_2←{
     rc←DoSomething
     assert 0=rc:
     ⍬
 }

 Do←{
     ⍺⍺¨⍳⍵
 }


So far I've always used the _← technique in order to suppress an unwanted result and make it work inside a dfn. The technique used in Test_2 does not only avoid an unnecessary variable, it's also faster:


Code: Select all
      cmpx '#.Test_1 #.Do⊣100' '#.Test_2 #.Do⊣100'
  #.Test_1 #.Do⊣100 → 1.8E¯4 |   0% ⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕
  #.Test_2 #.Do⊣100 → 1.6E¯4 | -10% ⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕
User avatar
kai
 
Posts: 137
Joined: Thu Jun 18, 2009 5:10 pm
Location: Hillesheim / Germany

Re: Assert Dfn

Postby Roger|Dyalog on Mon May 13, 2019 11:42 pm

I say again, "assert" as written is correct, and the result is shy. I'll grant you that it's equally shy if the name is (say) "eager", but the name "shy" is a useful hint. Suppose:

Code: Select all
assert1← {⍺←'assertion failure' ⋄ 0∊⍵:⍺ ⎕SIGNAL 8 ⋄     0}
assert ← {⍺←'assertion failure' ⋄ 0∊⍵:⍺ ⎕SIGNAL 8 ⋄ shy←0}

z←x tradfn1 y                 z←x tradfn y
assert1 x=y                   assert x=y   
z←x+y                         z←x+y       

Now try the examples in my last msg
Code: Select all
      3 tradfn1 4                  3 tradfn 4
assertion failure             assertion failure
tradfn1[1] assert1 ⍺=⍵        tradfn[1] assert ⍺=⍵
           ∧                            ^
      →                            →

      3 tradfn1 3                  3 tradfn 3
0                             6
6

Interesting; I never heard anything about this. In the dfns workspace there are just three functions which have a colon as the very last character.

The technique have been used in few public places. For example:

In the Dyalog QA suite, I estimate that "assert" is used a few thousand times, run 365.2425 days a year.

To properly evaluate "assert", you have to know its objectives:

  • A function that works silently, without side effects, if the proposition is true.
  • A function that suspends in the calling function or operator, if the proposition is not true.
  • A function that works (nearly) the same in dfns and tradfns.
  • A function that requires a minimal of extra stuff, hopefully none. (In particular, _←assert blah is undesired for aesthetic reasons.) In this case, the trailing colon when used in a dfn is the best that we (John Scholes and I) can do.
Roger|Dyalog
 
Posts: 238
Joined: Thu Jul 28, 2011 10:53 am

Re: Assert Dfn

Postby Roger|Dyalog on Tue May 14, 2019 2:42 am

In the Dyalog QA suite, I estimate that "assert" is used a few thousand times, run 365.2425 days a year.

Used at least 3558 times.
Roger|Dyalog
 
Posts: 238
Joined: Thu Jul 28, 2011 10:53 am

Next

Return to Language

Who is online

Users browsing this forum: No registered users and 1 guest