Diamondized control strucures and the Tracer

APL-related discussions - a stream of APL consciousness.
Not sure where to start a discussion ? Here's the place to be
Forum rules
This forum is for discussing APL-related issues. If you think that the subject is off-topic, then the Chat forum is probably a better place for your thoughts !

Diamondized control strucures and the Tracer

Postby kai on Mon Jul 19, 2021 6:07 am

Is it a good idea the write code like this:

Code: Select all
:IF 0∊⍴from ⋄ from←'kai@aplteam.com' ⋄ :EndIf


rather than:

Code: Select all
:If 0∊⍴from 
     from←'john.doe@foo.com'
:EndIf



My opinion: as long as the Debugger is not able to jump from one ⋄ to the next (=have a line as the smallest unit of operation) it's not a good idea at all.

The reason is that in the Tracer when you go over that line you have no idea whether "from" is what it was before or was set to "john.doe@foo.com", and I consider this as really bad.

(It would argue that it is also less readable and defeats the purpose of control structure but that's a different matter)

Dyalog appears to have no plans for the foreseeable future to extend the Tracer (viewtopic.php?f=30&t=1549&p=6107&hilit=Tracer#p6107)

Therefore I suggest to not write code like that.

This is not only about debugging, though that's already important enough a point. It's also about tracing through any third-party code in order to find out what's going on: it's much harder with diamondized code.

If saving two lines here really is the issue then I would argue that using a control structure is plain wrong: used in this way they produce a lot of noise without any advantage.
User avatar
kai
 
Posts: 137
Joined: Thu Jun 18, 2009 5:10 pm
Location: Hillesheim / Germany

Re: Diamondized control strucures and the Tracer

Postby Morten|Dyalog on Mon Jul 19, 2021 8:42 am

I hope we don't have a lot of people writing exactly like that:

Code: Select all
:If 0∊⍴from
     from←'john.doe@foo.com'
:EndIf


I suggest that you write a single line:

Code: Select all
     from,←(0∊⍴from)/'john.doe@foo.com'


... which you also won't be able to trace through in any meaningful way until we implement some kind of token-by-token (rather than just diamond-by-diamond) debugging. That is something that is on our ToDo list, but as you correctly conclude, we have quite a few other things we feel have higher priority.
User avatar
Morten|Dyalog
 
Posts: 451
Joined: Tue Sep 09, 2008 3:52 pm

Re: Diamondized control strucures and the Tracer

Postby kai on Mon Jul 19, 2021 9:48 am

> I hope we don't have a lot of people writing exactly like that:

Well, I must disappoint you; this is taken from code provided by Dyalog:

Code: Select all
 
:If 0∊⍴Userid ⋄ Userid←From ⋄ :EndIf
:If 0∊⍴From ⋄ From←Userid ⋄ :EndIf


There are countless examples of this kind.

My code was just meant to be a simple example, but obviously I failed to get my point across.

Maybe this illustrates the problem a bit better:

Code: Select all
⍝ Given this: MyDfn←{+/⍵}

:If <some APL expression> ⋄ r←MyDfn data ⋄ :Endif


Notes:

1. <some APL expression> means that you cannot just hover with the mouse over a variable name.

2. Because it is a one-line dfns you cannot tell whether it got executed even if you use Ctrl+Enter


Another one:

Code: Select all
:If done=¯1 ⋄ :Return ⋄ :EndIf


In the Tracer I might execute such a statement without paying too much attention to the line number because I happen to know that "done" will not be ¯1, only to find out that it was ¯1 anyway, and I now have the problem that I might not know where I came from if the function is lengthy enough.

I can provide more examples if you wish.
User avatar
kai
 
Posts: 137
Joined: Thu Jun 18, 2009 5:10 pm
Location: Hillesheim / Germany

Re: Diamondized control strucures and the Tracer

Postby Morten|Dyalog on Mon Jul 19, 2021 12:31 pm

kai wrote:My code was just meant to be a simple example, but obviously I failed to get my point across.


Not at all, the point is very clear and well argued. I'm just saying that we have a few other things we want to do first, and if we are going to do work to break with the fundamental line-by-line limitation, we should really plan to do a bit more and also include token-by-token debugging, and perhaps the ability to evaluate the test, and so on.

At the moment - as you point out - it is fairly easy to "not write code like that" until we have more granular debugging.
User avatar
Morten|Dyalog
 
Posts: 451
Joined: Tue Sep 09, 2008 3:52 pm

Re: Diamondized control strucures and the Tracer

Postby Brian|Dyalog on Mon Jul 19, 2021 2:51 pm

With regard to
      :If 0∊⍴x ⋄ x←'some value' ⋄ :EndIf

versus
      x,←(0∊⍴x)/'some value'

This may sound heretical, but I will tend to prefer the former. Why? Ignorance and historical bias.

My ignorance lies in that I don't know who's going to be looking at the code, an uber-experienced APLer like Morten or Kai or someone quite new to APL? To even modestly-experienced APLers, the latter form is almost instantly obvious and, to APL purists, it's more "APLish" and elegant. But to anyone with even a modicum of (non-APL) coding experience, the former is still clear. One of my goals when I write tools for other people's consumption and contribution is to make the code as clear as possible (sadly, I'm not always successful in this pursuit).

My historical bias has its roots in my APL beginnings back in the 1970s when CPU resources were a precious commodity. As such, I try to avoid unnecessary processing. Granted neither of these expressions today consumes a noticeable amount of CPU, but the latter case always does more work whether x is empty or not. This was borne out when I did some very simple profiling - the former being between 10 and 20% faster depending on the emptiness of x.

As to Kai's original point about the traceability of diamondized control statements, I try to diamondize what I consider to be trivial statements and undiamondize those where meaningful work is being performed. Again sadly, I'm not always successful here either.

Token-by-token debugging would be a nice option. If we ever implement it, I think it should have a separate keystroke to invoke. This way I can optionally trace into more complex statements (and single-line dfns). Until then, it's easy enough to undiamondize the former expression for tracing purposes.
User avatar
Brian|Dyalog
 
Posts: 116
Joined: Thu Nov 26, 2009 4:02 pm
Location: West Henrietta, NY

Re: Diamondized control strucures and the Tracer

Postby kai on Mon Jul 19, 2021 3:25 pm

> Until then, it's easy enough to undiamondize the former expression for tracing purposes.

Hmmm.

Imagine in C++ somebody would have suggested a long time ago to implement something like to Dyalog Tracer and gets rejected with "Well, you can simply inject printf statement, can't you."
User avatar
kai
 
Posts: 137
Joined: Thu Jun 18, 2009 5:10 pm
Location: Hillesheim / Germany

Re: Diamondized control strucures and the Tracer

Postby ray on Mon Jul 19, 2021 9:22 pm

May I offer another reason against using diamondized lines in general.

If possible, every line of code should be re-startable.

If a line of code fails in the middle, once the problem is fixed, restarting on that line should work.
Example:
Code: Select all
i←0
i+←1 ⋄ a←i+j

If "j" is undefined when the code is run, on the value error, setting "j←0" and restarting that line, "a" will now have the value of 2 rather than the expected 1.

Having said that, I am guilty of using diamonds for the readability it can provide:
Code: Select all
 i←0
⍝ Define the column names in world array (Boolean) defining scent trails in each cell
 wc_c0_sW←i ⋄ i+←1 ⍝         1 if red ant scent #0 is set (White)
 wc_c0_sR←i ⋄ i+←1 ⍝         1 if red ant scent #1 is set (Red)
 wc_c0_sG←i ⋄ i+←1 ⍝         1 if red ant scent #2 is set (Green)
 wc_c0_sB←i ⋄ i+←1 ⍝         1 if red ant scent #3 is set (Blue)
 wc_c0_sY←i ⋄ i+←1 ⍝         1 if red ant scent #4 is set (Yellow)
 wc_c0_sB←i ⋄ i+←1 ⍝         1 if red ant scent #5 is set (Black)

but I think this code is at least re-startable.

Ray
Ray Cannon
Please excuse any smelling pisstakes.
User avatar
ray
 
Posts: 218
Joined: Wed Feb 24, 2010 12:24 am
Location: Blackwater, Camberley. UK

Re: Diamondized control strucures and the Tracer

Postby kai on Tue Jul 20, 2021 3:57 am

Yes, I agree with you Ray. There are quite a number of reasons why the diamond should be banned from APL altogether.

Unfortunately there are a number of cases when it is invaluable:

1. Execute code where threads must not change in between
2. Doing several things on ⎕LX like

⎕trap←0 'S' ⋄ #.Foo.Run

However, it should only be used in limited cases, and certainly not to save a couple of lines.
User avatar
kai
 
Posts: 137
Joined: Thu Jun 18, 2009 5:10 pm
Location: Hillesheim / Germany


Return to APL Chat

Who is online

Users browsing this forum: No registered users and 1 guest