Re: signum
These are issues of taste. The text of a single mote may be 1024 characters in length. Historically they were kept terse to save storage. This rationale for brevity is no more, I therefore try to provide very full information in error mnotes, including any contextual information that is likely to be helpful. Macro definitions are often written by programmers who are less accomplished than the programmer who wrote the corresponding macro definition; and it is, I think, his or her responsibility to diagnose any errors, syntactic and semantic, that are accessible, even if the result is longer than it otherwise would be. Brevity may well be the soul of wit, but in this context it is unhelpful. Specifically here, it is my view that if duplication is an error just what hs been duplicated must be made clear, unambiguously so. Our notions of what constitutes 'eye candy' are thus very different. We indeed disagree sharply, but that does not distress me and should not distress you. John Gilmore, Ashland, MA 01721 - USA
Re: signum
On 25 October 2013 17:59, John Gilmore wrote: > Rob's macro FOOBAR is easy to improve, as in > I don't disagree yet, but what's the improvement? It's a lot more code (though still less than what I inherited) and I agree the mnote is more verbose. But does it serve a purpose? Maybe I've tried too much C that I rarely feel helped by the compiler messages but instead go look at the source and figure out where I screwed up. With HLASM the messages rarely describe my mistake, at best I can see why he thought that way... I should likely do better than an mnote with "that's wrong, go look again" but to double the amount of code (and likely mistakes) just for eye candy isn't my first choice. Could I redesign the FOOBAR macro, I would have opted for a scheme that enforces the semantics better, like FOOBAR B,17 Rob
Re: signum
Rob's macro FOOBAR is easy to improve, as in | macro | FOOBAR &a=,&b=&c= | more than one keyword-pasrameter value supplied? | |&a_in setb(t'&a ne 'O')--&a value supplied? |&b_in setb(t'&b ne 'O')--&b value supplied? |&c_in setb(t'&c ne 'O')--&c value supplied? |&ns seta&a_in+&b_in+&c_in --count of values supplied |only_one setb (&ns eq 1) --only one value supplied? | aif (&only_one).after_too_many--if so, ok |&text(1) setc ' not ',' '--mnote variable text |&asub seta (3+&a_in)/2--0,1==>1,2 |&bsub seta (3+&b_in)/2--0,1==>1,2 |&csub seta (3+&c_in)/2--0,1==>1,2 mnote 8,'FOOBAR000i, Only one of the a=, b=, c= keyword+ parameters may be given a value; here &ns were. Sp+ ecifically, &&a was&text(asub).given a value, &&b was+ &text(&bsub).given a alue; and &&c was&text(csub).g+ iven a value.' .after_too_many anop mexit mend Here of course &&a was&text(&asub).given a value yields '&a was given a value' when one was supplied, or '&a was not given a value' when one was not supplied. I am unenthusiastic about the notion that a nul string value is an omitted one, not least because the macro language makes a specific. wholly unambiguous test for omisses available. John Gilmore, Ashland, MA 01721 - USA
Re: signum
I by no means meant to criticize the technique you described. On the contrary, I find it cool and refreshing. I like when it makes me think to determine what it is doing and how. OTOH you are perfectly correct that a 1000-line if clause is just as (or maybe more) hard to decipher. Managers and even sometimes fellow programmers do not always like it when code makes them think ... :) Peter -Original Message- From: IBM Mainframe Assembler List [mailto:ASSEMBLER-LIST@LISTSERV.UGA.EDU] On Behalf Of Rob van der Heij Sent: Friday, October 25, 2013 8:36 AM To: ASSEMBLER-LIST@LISTSERV.UGA.EDU Subject: Re: signum On 24 October 2013 16:25, Farley, Peter x23353 wrote: > Wow. I have occasionally been accused of using obscure, "unmaintainable" > code in the name of efficiency, but that "gubbins" example and Rob's > default parameter assignment parse make me look positively conservative. > Oh dear, I need to defend myself... As Paracelsus said "Alle Dinge sind Gift.. " (Google for the rest) and even if you have something like if/then/else that is simple to understand, when you have enough the result gets complicated (like a 1000-line if clause) Getting back to HLASM, I inherited macro that (simplified) starts like this: MACRO FOOBAR &A=,&B=,&C= Now it needs to test that exactly one of the 3 parameters is being used, and it does so using a cascade of simple AIF statement using ('&A' EQ ' ') to verify that. This may have been trivial before, and got tedious when C= was added. The error messages also introduced an ordering of the alternatives that does not match the argument (eg "must not B when A is specified" when invoked as FOOBAR B=1,A=3). While I agree the following takes some creativity, it's basically not more complicated and easier to maintain when you add another one... LCLA&P &P SETA K'&A+K'&B+K'&C AIF (&P EQ 1).FOOX MNOTE 8,'Foobar using &P of the A= B= C= options' .FOOXANOP , Rob -- This message and any attachments are intended only for the use of the addressee and may contain information that is privileged and confidential. If the reader of the message is not the intended recipient or an authorized representative of the intended recipient, you are hereby notified that any dissemination of this communication is strictly prohibited. If you have received this communication in error, please notify us immediately by e-mail and delete the message and any attachments from your system.
Re: signum
On 2013-10-24, at 00:41, Rob van der Heij wrote: > On 24 October 2013 02:42, Tony Harminc wrote: > >> That's a very APLish thing to do. >> I'm sorry. > No doubt a matter of style and experience, but I find if/then/else hard to > follow when reading. Especially when ident does not match the nesting. Once > you're familiar with the idioms, they reduce the amount of reading and > increase what you can oversee on a single screen or page. > What about the HLASM TK SP Macros? I coded yesterday for a test, growing out of an example I posted on IBM-MAIN: ... RC = BPXWDYN( 'alloc rtddn(DDX) rtdsn(DSX) rtvol(VLX) new delete' , word( 'dsn('userid()'.TEMP.LMTEST)' , 'unit(VIO)', 1 ) , 'dsorg(PS) recfm(V,B) lrecl(137) msg(WTP)' ) ... I can change the word number either to 1 for a DASD data set or to 2 for VIO. Cleary I miss the facility of conditional expressions in Rexx. -- gil
Re: signum
On 2013-10-23, at 19:33, robin wrote: > From: "Paul Gilmartin" > Sent: Thursday, October 24, 2013 11:51 AM > >> On 2013-10-23 18:36, robin wrote: >>> >>> And anyway, how do you think that J > K is computed? >>> >>> The comparison is performed by subtracting K from J >>> (without changing either J or K, of course). >> >> Why not use the Compare instruction? (As in Assembler > > That IS what a compare is (in hardware). C compares > by subtracting one operand from the other. (without changing > either operand). > I'm skeptical: o How does it set the condition code? o What happens if the values of J and K are so extreme that the subtraction would result in overflow? (I suppose I could imagine guard bits on the left.) o How is Compare done for non-numeric operands, as by CLC? -- gil
Re: signum
On 24 October 2013 16:25, Farley, Peter x23353 wrote: Wow. I have occasionally been accused of using obscure, "unmaintainable" > code in the name of efficiency, but that "gubbins" example and Rob's > default parameter assignment parse make me look positively conservative. > Oh dear, I need to defend myself... As Paracelsus said "Alle Dinge sind Gift.. " (Google for the rest) and even if you have something like if/then/else that is simple to understand, when you have enough the result gets complicated (like a 1000-line if clause) Getting back to HLASM, I inherited macro that (simplified) starts like this: MACRO FOOBAR &A=,&B=,&C= Now it needs to test that exactly one of the 3 parameters is being used, and it does so using a cascade of simple AIF statement using ('&A' EQ ' ') to verify that. This may have been trivial before, and got tedious when C= was added. The error messages also introduced an ordering of the alternatives that does not match the argument (eg "must not B when A is specified" when invoked as FOOBAR B=1,A=3). While I agree the following takes some creativity, it's basically not more complicated and easier to maintain when you add another one... LCLA&P &P SETA K'&A+K'&B+K'&C AIF (&P EQ 1).FOOX MNOTE 8,'Foobar using &P of the A= B= C= options' .FOOXANOP , Rob
Re: signum
Wow. I have occasionally been accused of using obscure, "unmaintainable" code in the name of efficiency, but that "gubbins" example and Rob's default parameter assignment parse make me look positively conservative. Bravo! And thanks for showing us interesting concepts (assembler or not, I think concepts are not OT). Peter -Original Message- From: IBM Mainframe Assembler List [mailto:ASSEMBLER-LIST@LISTSERV.UGA.EDU] On Behalf Of Rob van der Heij Sent: Thursday, October 24, 2013 2:41 AM To: ASSEMBLER-LIST@LISTSERV.UGA.EDU Subject: Re: signum On 24 October 2013 02:42, Tony Harminc wrote: On 23 October 2013 19:43, Paul Gilmartin wrote: > > I have occasionally gotten > > flamboyant and coded such as: > > > > X = copies( 'gubbins', A==B ) /* instead of: */ > > > > if A==B > > then X = 'gubbins' > > else X = '' > > That's a very APLish thing to do. > I would be worried about (when the language permits it)x = copies('gubbins', c=a==b) No doubt a matter of style and experience, but I find if/then/else hard to follow when reading. Especially when ident does not match the nesting. Once you're familiar with the idioms, they reduce the amount of reading and increase what you can oversee on a single screen or page. Reducing the vocabulary does not make a coded algorithm easier to understand. I you have no clue about binary search, then following the if/then/else with your finger may not help you spot an error. Knowing the language is the least of your concerns. A popular one we use is this: return rc * (rc <> 12) Or this (to assign defaults to missing arguments): parse value subword(outf,1,3) subword('BUNDLE VMFPLC A', words(outf)+1) with outf Rob (almost Friday) -- This message and any attachments are intended only for the use of the addressee and may contain information that is privileged and confidential. If the reader of the message is not the intended recipient or an authorized representative of the intended recipient, you are hereby notified that any dissemination of this communication is strictly prohibited. If you have received this communication in error, please notify us immediately by e-mail and delete the message and any attachments from your system.
Re: signum
On 24 October 2013 02:42, Tony Harminc wrote: On 23 October 2013 19:43, Paul Gilmartin wrote: > > I have occasionally gotten > > flamboyant and coded such as: > > > > X = copies( 'gubbins', A==B ) /* instead of: */ > > > > if A==B > > then X = 'gubbins' > > else X = '' > > That's a very APLish thing to do. > I would be worried about (when the language permits it)x = copies('gubbins', c=a==b) No doubt a matter of style and experience, but I find if/then/else hard to follow when reading. Especially when ident does not match the nesting. Once you're familiar with the idioms, they reduce the amount of reading and increase what you can oversee on a single screen or page. Reducing the vocabulary does not make a coded algorithm easier to understand. I you have no clue about binary search, then following the if/then/else with your finger may not help you spot an error. Knowing the language is the least of your concerns. A popular one we use is this: return rc * (rc <> 12) Or this (to assign defaults to missing arguments): parse value subword(outf,1,3) subword('BUNDLE VMFPLC A', words(outf)+1) with outf Rob (almost Friday)
Re: signum
From: "Paul Gilmartin" Sent: Thursday, October 24, 2013 11:51 AM On 2013-10-23 18:36, robin wrote: Any overflow is detected. And anyway, how do you think that J > K is computed? The comparison is performed by subtracting K from J (without changing either J or K, of course). Why not use the Compare instruction? (As in Assembler That IS what a compare is (in hardware). C compares by subtracting one operand from the other. (without changing either operand).
Re: signum
On 2013-10-23 18:36, robin wrote: > > Any overflow is detected. > > And anyway, how do you think that J > K is computed? > > The comparison is performed by subtracting K from J > (without changing either J or K, of course). Why not use the Compare instruction? (As in Assembler -- on-topic.) -- gil
Re: signum
On 23 October 2013 19:43, Paul Gilmartin wrote: > I have occasionally gotten > flamboyant and coded such as: > > X = copies( 'gubbins', A==B ) /* instead of: */ > > if A==B > then X = 'gubbins' > else X = '' That's a very APLish thing to do. Tony H.
Re: signum
From: "Paul Gilmartin" Sent: Thursday, October 24, 2013 10:47 AM On 2013-10-23 17:33, robin wrote: What? Rexx'sm = ( j > k ) - ( j < k ); would be exactly the same in PL/I. However, you would never write it like that. It's just obfuscation. simplest (and trivial-est) in PL/I is m = sign(j-k); But beware: for extreme values of j and k this might result in an undetected overflow (is this nowadays called an ON SIZE condition?) and undesired results. Any overflow is detected. And anyway, how do you think that J > K is computed? The comparison is performed by subtracting K from J (without changing either J or K, of course).
Re: signum
- Original Message - From: "Paul Gilmartin" To: Sent: Thursday, October 24, 2013 10:43 AM Subject: Re: signum On 2013-10-23 17:26, robin wrote: In Rexx, this could be written with no (explicit) branches as: m = ( j > k ) - ( j < k ); In PL/I, m = sign(j-k); The objective was to synthesize sign() in a language such as Rexx which, unlike PL/I, lacks it. The KISS principle is worthy of more attention. An IF construct is more obvious. I have occasionally gotten flamboyant and coded such as: X = copies( 'gubbins', A==B ) /* instead of: */ You have to be joking. if A==B then X = 'gubbins' else X = '' Clearly, I've been polluted by excessive exposure to CDC 6600, whose programmers went to extremes to avoid branches which might break pipelining. You can't avoid branches, either implicit or explicit. On 2013-10-23 15:09, John Gilmore wrote: Boolean values are bits in PL/I. ... but nothing quite like your REXX construct is available. IOW, PL/I provides no coercion from boolean (bit) values to integer? Conversion from boolean to integer is readily available in PL/I.
Re: signum
I've been reading quietly and wondering how the dialog drifted off to rexx and pl1 land. Can we get back on topic? Thanks On Oct 23, 2013 7:43 PM, "Paul Gilmartin" wrote: > On 2013-10-23 17:26, robin wrote: > > > >> In Rexx, this could be written with no (explicit) branches > >> as: > >> > >>m = ( j > k ) - ( j < k ); > > > > In PL/I, > >m = sign(j-k); > > > The objective was to synthesize sign() in a language such as > Rexx which, unlike PL/I, lacks it. I have occasionally gotten > flamboyant and coded such as: > > X = copies( 'gubbins', A==B ) /* instead of: */ > > if A==B > then X = 'gubbins' > else X = '' > > Clearly, I've been polluted by excessive exposure to CDC 6600, > whose programmers went to extremes to avoid branches which > might break pipelining. > > > On 2013-10-23 15:09, John Gilmore wrote: > > Boolean values are bits in PL/I. > > ... > > but nothing quite like your REXX construct is available. > > > IOW, PL/I provides no coercion from boolean (bit) values to > integer? > > ("[my] REXX construct"? It's conventional; I lay no claim > to originality.) > > --- gil >
Re: signum
On 2013-10-23 17:33, robin wrote: > > What? Rexx'sm = ( j > k ) - ( j < k ); > > would be exactly the same in PL/I. > > However, you would never write it like that. It's just obfuscation. > > simplest (and trivial-est) in PL/I is m = sign(j-k); > But beware: for extreme values of j and k this might result in an undetected overflow (is this nowadays called an ON SIZE condition?) and undesired results. -- gil
Re: signum
On 2013-10-23 17:26, robin wrote: > >> In Rexx, this could be written with no (explicit) branches >> as: >> >>m = ( j > k ) - ( j < k ); > > In PL/I, >m = sign(j-k); > The objective was to synthesize sign() in a language such as Rexx which, unlike PL/I, lacks it. I have occasionally gotten flamboyant and coded such as: X = copies( 'gubbins', A==B ) /* instead of: */ if A==B then X = 'gubbins' else X = '' Clearly, I've been polluted by excessive exposure to CDC 6600, whose programmers went to extremes to avoid branches which might break pipelining. On 2013-10-23 15:09, John Gilmore wrote: > Boolean values are bits in PL/I. > ... > but nothing quite like your REXX construct is available. > IOW, PL/I provides no coercion from boolean (bit) values to integer? ("[my] REXX construct"? It's conventional; I lay no claim to originality.) --- gil
Re: signum
- Original Message - From: "John Gilmore" To: Sent: Thursday, October 24, 2013 8:09 AM Subject: Re: signum Boolean values are bits in PL/I. Writing, say, declare (a,b, d) signed binary fixed(63,0), signum signed binary fixed(7, 0), (bigger, equal, smaller) aligned bit ; permits either d = a - b ; select ; when(d > 0) signum = +1 ; when(d = 0) signum = 0 ; when(d < 0) signum = -1 ; end ; or d = a - b ; bigger = (d > 0 equal = (d = 0) ; smaller = (d < 0) ; but nothing quite like your REXX construct is available. What? Rexx'sm = ( j > k ) - ( j < k ); would be exactly the same in PL/I. However, you would never write it like that. It's just obfuscation. simplest (and trivial-est) in PL/I is m = sign(j-k);
Re: signum
From: "Paul Gilmartin" Sent: Thursday, October 24, 2013 2:28 AM What are the representations of boolean values in PL/I? A single bit. True is 1, false is 0. In Rexx, this could be written with no (explicit) branches as: m = ( j > k ) - ( j < k ); In PL/I, m = sign(j-k);
Re: signum
Boolean values are bits in PL/I. Writing, say, declare (a,b, d) signed binary fixed(63,0), signum signed binary fixed(7, 0), (bigger, equal, smaller) aligned bit ; permits either d = a - b ; select ; when(d > 0) signum = +1 ; when(d = 0) signum = 0 ; when(d < 0) signum = -1 ; end ; or d = a - b ; bigger = (d > 0 equal = (d = 0) ; smaller = (d < 0) ; but nothing quite like your REXX construct is available. John Gilmore, Ashland, MA 01721 - USA
Re: signum
On 2013-10-23, at 07:35, robin wrote: > From: "John Gilmore" > Sent: Wednesday, October 23, 2013 10:02 PM > > >> Interestingly, when I take your C example, >> >> if ( j < k ) m = -1; >> else if (j > k) m = 1; >> else m = 0; >> return m; >> >> and rewrite it trivially modified in PL/I as >> >> if j < k then m = -1; >> else if j > k then m = 1; >> else m = 0; >> return (m); >> >> I cannot reproduce your results. > > What does it produce (under highest optimisation) ? What are the representations of boolean values in PL/I? In Rexx, this could be written with no (explicit) branches as: m = ( j > k ) - ( j < k ); -- gil
Re: signum
From: "John Gilmore" Sent: Wednesday, October 23, 2013 10:02 PM Interestingly, when I take your C example, if ( j < k ) m = -1; else if (j > k) m = 1; else m = 0; return m; and rewrite it trivially modified in PL/I as if j < k then m = -1; else if j > k then m = 1; else m = 0; return (m); I cannot reproduce your results. What does it produce (under highest optimisation) ?
Re: signum (was: Linear search vs binary)
I understand. I don't even need a computer to do that :-) The "return" was just to discourage the optimizer to throw away all the code because I didn't use the result. The thing that kept me awake briefly was whether the optimizer would recognize that the shortcut and code a single compare with two branches using the CC. I suppose my next attempt would have been a case statement using sign() Rob On 23 October 2013 12:25, robin wrote: > From: "Rob van der Heij" > Sent: Wednesday, October 23, 2013 8:12 PM > > > > Since the machine architectures that came to mind all have this 3-state >> result after comparison, I expected the compiler to take advantage of it >> when I write something like >> if ( j < k ) m = -1; >> else if (j > k) m = 1; >> else m = 0; >> return m; >> > > It is sufficient to write: >return (sign(j-k) ); >
Re: signum (was: Linear search vs binary)
Rob, Interestingly, when I take your C example, if ( j < k ) m = -1; else if (j > k) m = 1; else m = 0; return m; and rewrite it trivially modified in PL/I as if j < k then m = -1; else if j > k then m = 1; else m = 0; return (m); I cannot reproduce your results. John Gilmore, Ashland, MA 01721 - USA
Re: signum (was: Linear search vs binary)
From: "Rob van der Heij" Sent: Wednesday, October 23, 2013 8:12 PM Since the machine architectures that came to mind all have this 3-state result after comparison, I expected the compiler to take advantage of it when I write something like if ( j < k ) m = -1; else if (j > k) m = 1; else m = 0; return m; It is sufficient to write: return (sign(j-k) );
Re: signum (was: Linear search vs binary)
Since the machine architectures that came to mind all have this 3-state result after comparison, I expected the compiler to take advantage of it when I write something like if ( j < k ) m = -1; else if (j > k) m = 1; else m = 0; return m; A few surprises with gcc, like pretty dumb code without -O3 and then very smart code with -O3 :-) and the result is below. What I considered interesting is that we indeed have a single "CR" followed by the "JL" and "JNLE" so the language allows me to express this situation properly. I suppose the "LHI" at 062E is also done early to take advantage of the pipeline? (the setting of the scene is with R10 and R2 holding "j" and "k" respectively') 8628: 19 a2 cr %r10,%r2 862a: a7 44 00 1a jl 865e 862e: a7 28 00 00 lhi %r2,0 8632: a7 34 00 0b jnle8648 8636: e3 40 f1 10 00 04 lg %r4,272(%r15) 863c: b9 14 00 22 lgfr%r2,%r2 8640: eb af f0 f0 00 04 lmg %r10,%r15,240(%r15) 8646: 07 f4 br %r4 8648: a7 28 00 01 lhi %r2,1 864c: e3 40 f1 10 00 04 lg %r4,272(%r15) 8652: b9 14 00 22 lgfr%r2,%r2 8656: eb af f0 f0 00 04 lmg %r10,%r15,240(%r15) 865c: 07 f4 br %r4 865e: a7 28 ff ff lhi %r2,-1 8662: e3 40 f1 10 00 04 lg %r4,272(%r15) 8668: b9 14 00 22 lgfr%r2,%r2 866c: eb af f0 f0 00 04 lmg %r10,%r15,240(%r15) 8672: 07 f4 br %r4
Re: signum (was: Linear search vs binary)
From: "John Gilmore" Sent: Tuesday, October 22, 2013 9:31 AM PL/I was robbed of FIXEDOVERFLOW for binary fixed values. Use SIZE instead. It is still available for PL/I decimal fixed, i.e., packed decimal values. The LE does in fact make a facility available for executing what is in efffect an arbitrary SPM instruction; but it is documented so poorly---It has been all but hidden---that it is difficult to use. When binary FIXEDOVERFLOW is important I now do the arithmetic in an assembly-language subroutine. Use SIZE instead. SIZE is raised for fixed binary overflow. This a is a pity, a disagreeable consequence of the fact that much PL/I implementation machinery is now shared with C; but it must be conceded that there have been benefits too, e.g., for select groups that are exact functional equivalents of licit C switch statements, which are now better optimized than they once were.
Re: signum
On 2013-10-21 16:31, John Gilmore wrote: > PL/I was robbed of FIXEDOVERFLOW for binary fixed values. It is still > available for PL/I decimal fixed, i.e., packed decimal values. > > ... > > This a is a pity, a disagreeable consequence of the fact that much > PL/I implementation machinery is now shared with C; ... > Truly a pity because reporting fixed overflow is entirely compatible with the ANSI specification of C. I suspect some of the motivation lies in LE library routines which carelessly generate fixed overflow, smugly expecting it will be ignored, and which programmers lack the ambition to correct. Likewise, IBM's C some time ago made the invalid dereferencing of NULL behave as a reference to "", in deference to pervasive misusage. -- gil
Re: signum (was: Linear search vs binary)
PL/I was robbed of FIXEDOVERFLOW for binary fixed values. It is still available for PL/I decimal fixed, i.e., packed decimal values. The LE does in fact make a facility available for executing what is in efffect an arbitrary SPM instruction; but it is documented so poorly---It has been all but hidden---that it is difficult to use. When binary FIXEDOVERFLOW is important I now do the arithmetic in an assembly-language subroutine. This a is a pity, a disagreeable consequence of the fact that much PL/I implementation machinery is now shared with C; but it must be conceded that there have been benefits too, e.g., for select groups that are exact functional equivalents of licit C switch statements, which are now better optimized than they once were. John Gilmore, Ashland, MA 01721 - USA