Spin2 Operator Syntax - Page 9 — Parallax Forums

# Spin2 Operator Syntax

• Posts: 3,694
@Chip,

min d,s should give as result the smaller value into d. d=min(d,s).

same goes for max. max d,s should give you the bigger value.

the whole limit thing is complete nonsense.

I do not know of any language besides spin and pasm where max gives you the minimum value and min gives you the maximum value.

it is just wrong.

Mike

• Posts: 6,347
Chip, the operators #> and <# impose an upper and lower limit (or maybe I have them backwards). The terms min and max imply performing minimum and maximum functions, which is the opposite interpretation. So when you say min you really mean lower limit, and your use of max means upper limit. So why not use opcodes that are more accurate, such as lolim and hilim, or limlo and limhi. Or if you want it shorter, how about llim and hlim, or liml and limh.
• Posts: 2,665
Can MIN and MAX still be used as method names if they are operators? I don't think so.
This means you have no chance to make your own MIN, MAX functions that work in the traditional way.

I would just keep the <# and #> operators.
```pub min(a,b)
return a #> b

pub max(a,b)
return a <# b
```

Andy
• Posts: 13,528
edited 2017-04-13 18:17
I agree with Andy...

I've seen something like this in C code a lot:
```#ifndef NOMINMAX
#define min(x,y) ((x) < (y) ? (x) : (y))
#define max(x,y) ((x) > (y) ? (x) : (y))
#endif
```

Should be fine to do it this way in Spin also...
• Posts: 2,996
Chip,
For the PASM instructions, literally the opposite names. Given the two operands, MAX currently puts the lower of the two values in D (either moving S to D or leaving D), and that's backwards of what any normal person would expect. Other CPU/MCUs would have MAX "return" the higher of the two inputs, not the lower.

The operation you use for you example is called CLAMP in shaders (GPU stuff) and some extended CPU instructions. It takes 3 operands though. The value to clamp and the min and max range values. Since we don't have 3 operand instructions, it's fine to have it split into 2 instructions. Maybe just rename MAX and MIN to CLAMPU and CLAMPL (for upper and lower). Then we can have an alias of those to be MIN and MAX (but with the opposite of what they are now).
• Posts: 2,996
For spin, you could do CLAMP(x, a, b)
• Posts: 1,235
edited 2017-04-14 09:33
...
In a typical microcontroller app, where most shifts are binary instead of arithmetic, I think it's justifiable to give that task to >>, rather than relegate it to SHR. Anyway, I never saw anything wrong with ~> for SAR (except that I would've used -> or ->> instead, since it has a minus sign as part of the operator).

Anyway, elegance lies in complementary construction. If >> preserves the sign bit, by complementarity, << should also preserve the LSB, right?

-Phil
forget it - shouldn't post before coffee - of course we do not only shift by 1 bit ...
in Tachyon we have the shift operators
2* and 2/ which I use and like a lot, makes it very clear what happens
could be written in SPIN as *2 or /2 ???

• Posts: 8,697
edited 2017-04-13 19:24
T Chap wrote: »
I always have to look up #> and <# to remember what they mean. Why not something simple like X := LimMax(Y, maxval) or X := LimMax(Y, 100) then you see exactly what the maximum value will be and there is zero confusion about it.

I also had a problem remembering what they meant until I started to think of # as a combination of number and equal symbol. Then x:= #> 0 <# 99 became a number greater than or equal to 0 and less than or equal to 99. Perhaps just a quirk of how my mind works, but it may work for others as well.
• Posts: 21,230
edited 2017-04-13 19:29
MJB,
in Tachyon we have the shift operators
2* and 2/
... makes it very clear what happens
Clear as mud.

Kind of makes sense for a single bit shift up or down. Shift up is multiply (*) by 2. Shift down is divide (/) by two.

Except of course shifting right by 1 is not always the same as a divide by 2.

Very confusing.
• Posts: 6,347
MJB wrote: »
...
In a typical microcontroller app, where most shifts are binary instead of arithmetic, I think it's justifiable to give that task to >>, rather than relegate it to SHR. Anyway, I never saw anything wrong with ~> for SAR (except that I would've used -> or ->> instead, since it has a minus sign as part of the operator).

Anyway, elegance lies in complementary construction. If >> preserves the sign bit, by complementarity, << should also preserve the LSB, right?

-Phil
in Tachyon we have the shift operators
2* and 2/ which I use and like a lot, makes it very clear what happens
could be written in SPIN as *2 or /2 ???
Oh, please no. Let's not do that.

• Posts: 15,135
edited 2017-04-13 22:41
Dave Hein wrote: »
The wording of "Ensure x => y" for the MIN operator seems confusing. It sounds like the value of x is changed to equal the value of y if y is greater than x. The description for "x MIN y" should say exactly what it does, which is "returns the maximum value of x and y". And the description of MAX should be "returns the minimum value of x and y". Of course, those accurate descriptions will make the novice programmer wonder why the operator does the opposite of what the name implies, but I think all of us have wondered that ourselves.

EDIT: I would suggest not having aliases for #> and <#, or if you do want to use MIN and MAX for the aliases then swap them so their use is obvious instead of obfuscating the meaning. Of course, if you do that you would probably need to fix the meaning in assembly as well. Maybe better aliases would be CLIPHI and CLIPLO, or CLPH and CLPL. I think it's better to avoid using the terms MIN and MAX because of the misleading connotation of the operators.
Dave Hein wrote: »
Chip, the operators #> and <# impose an upper and lower limit (or maybe I have them backwards). The terms min and max imply performing minimum and maximum functions, which is the opposite interpretation. So when you say min you really mean lower limit, and your use of max means upper limit. So why not use opcodes that are more accurate, such as lolim and hilim, or limlo and limhi. Or if you want it shorter, how about llim and hlim, or liml and limh.

I agree MIN and MAX are now tarnished by historic misuse, so something else is needed in both PASM2 and Spin2.
cgracey wrote: »
Maybe we should just use names, instead:
```somecalc MIN 0 MAX 99       'clamp within 0..99
```

Yes, names are better, just avoid ones that have been misused in the past....
Cluso99 wrote: »
Here is a limit use from code by Jason Dorie...
```    Elev := 1000 #> Elev <# 2000                        'limit between 1ms..2ms
```
which will now read (assuming MINS/MAXS rather than MIN/MAX)...
```    Elev := 1000 MINS Elev MAXS 2000                        'limit between 1ms..2ms
```
The idea is good, but MINS already exists in PASM as backwards, so is best avoided as a 'new' keyword.

What about trying to get closer to the actual operation ?
Along the lines of this :
```    Elev := 1000 ABOVE Elev BELOW 2000
```
That's easy to read, but strictly applied, does 'above,below' suggests 1001..1999 ?

or Trim Greater or Equal, and Trim Less or Equal
```    Elev := 1000 TRIMGE Elev TRIMLE 2000                       '1000..2000,
Elev := 1000 TRIMGE Elev                     '>= 1000
Elev := Elev TRIMLE 2000                      '<= 2000
```

I favour TRIMLE and TRIMGE as you know what the expected result range is from the LE GE

Maybe this also works in PASM2 ?
```TRIMLE   D,S   D -> smaller of D,S
TRIMGE  D,S   D -> largest of D,S
```

cgracey wrote: »
Given that PASM instructions MIN and MAX potentially modify D, what names would be appropriate?
See above TRIMGE, TRIMLE suggestion. (TRIMSGE, TRIMSLE for signed versions ?, or TRIMUGE, TRIMULE for unsigned )

• Posts: 21,230
Looks like we should rename SPIN 2 as BABEL.

Sorry, could not resist.

Anyway, that name is already taken for a tool to handle similar chaos in the Javascript language world.

• Posts: 4,195
LMIN and LMAX for Limit Min Limit Max
• Posts: 18,066
edited 2017-04-13 23:10
I was about to argue that MAX, MIN, <# and #> were/are the wrong way around. I put my argument together offline, and in doing so, I realised I had been thinking about this the wrong way.

Here is my explanation why I now think it was/is correct. IMHO, it just needs a better explanation as to why it is so.

We perceive MAX means take the MAXIMUM of two values, and of course MIN means take the MINIMUM of two values.

However, when we look at this from the perspective of placing limits on a value, we have a lower limit (MIN) and an upper limit (MAX).

Mathematically we say MIN <= x <= MAX

Programatically, in spin we could say x := (v1 MIN x) MAX v2 where v1 is the lower limit and v2 is the upper limit.

Thus, MIN will take the greater value of v1 and x,followed by MAX taking the lesser value of the result and v2.

So, in this context, MIN takes the greater value, and MAX takes the lesser value.

This is precisely what we had/have. So, no change necessary!
• Posts: 2,996
Cluso,
I just don't agree with changing the meaning of MIN and MAX. Ask any programmer anywhere, and they will say that MAX should give you the maximum of the two values. This is because on other CPUs and in most languages that have MAX, that's what it does.

I'm fine with the #> and <# being how they are, but I strongly think the PASM instructions need a new name that is not MAX or MIN (nor contain them). I like CLAMPU/CLAMPL, or maybe CLAMPGE/CLAMPLE.

Then we can make functions called MIN and MAX that do what is expecting my most everyone.
• Posts: 23,514
Yes, keep <# and #>. Change PASM MIN and MAX to LLIM and HLIM, keeping mnemonics to four letters -- or LOLIM and HILIM if that doesn't matter.

-Phil
• Posts: 21,230
Does Spin have a WTF operator yet?

This is getting out of hand.
• Posts: 14,020
I think the conflict occurs because C uses MIN/MAX as an adjective/selector and the Prop uses it as a verb.
• Posts: 14,020
I will change back to #> and <#.

Not sure how to rename the PASM mnemonics.
• Posts: 14,020
At any rate, I feel we've got the right operator functions and the right precedence. Just some trailing naming issues.
• Posts: 21,230
What?

There is no MIN or MAX defined in C.

Or did I miss the memo?

• Posts: 14,020
edited 2017-04-14 01:30
Heater. wrote: »
What?

There is no MIN or MAX defined in C.

Or did I miss the memo?

I figured MIN (,) and MAX (,) were common C functions. I figured that must be where these notions came from.
• Posts: 14,507
cgracey wrote: »
Heater. wrote: »
What?

There is no MIN or MAX defined in C.

Or did I miss the memo?

I figured MIN (,) and MAX (,) were common C functions. I figured that must be where these notions came from.
They are not built into the standard C libraries but I've often defined them as macros:
```#define min(x,y) ((x) < (y) ? (x) : (y))
#define max(x,y) ((x) > (y) ? (x) : (y))
```
I thought that was the standard meaning of min and max. Or is it more like what Spin does? The Spin definitions surprised me.

• Posts: 21,230
min and max are often used in C. Generally as macros rather than functions.

I can't think it through now but the simplistic macros David presents are full of problems when used with different types.

Linus Torvalds made a bit of a storm about this when min/max was used badly in his kernel some years ago. The end result is this (from /kernel.h):
```/*
* min()/max()/clamp() macros that also do
* strict type-checking.. See the
* "unnecessary" pointer comparison.
*/
#define __min(t1, t2, min1, min2, x, y) ({              \
t1 min1 = (x);                                  \
t2 min2 = (y);                                  \
(void) (&min1 == &min2);                        \
min1 < min2 ? min1 : min2; })
#define min(x, y)                                       \
__min(typeof(x), typeof(y),                     \
__UNIQUE_ID(min1_), __UNIQUE_ID(min2_),   \
x, y)

#define __max(t1, t2, max1, max2, x, y) ({              \
t1 max1 = (x);                                  \
t2 max2 = (y);                                  \
(void) (&max1 == &max2);                        \
max1 > max2 ? max1 : max2; })
#define max(x, y)                                       \
__max(typeof(x), typeof(y),                     \
__UNIQUE_ID(max1_), __UNIQUE_ID(max2_),   \
x, y)

```

• Posts: 13,528
edited 2017-04-14 02:22
cgracey wrote: »
I will change back to #> and <#.

Not sure how to rename the PASM mnemonics.

Thanks! Don't care if PASM is weird, but let people define MAX and MIN in Spin as we want...

• Posts: 23,514
min and max would be handy variable names, were it not for their use as PASM instruction mnemonics.

-Phil
• Posts: 2,665
edited 2017-04-14 02:54
cgracey wrote: »
I will change back to #> and <#.

Not sure how to rename the PASM mnemonics.

MINU, MAXU for unsigned version
MINS, MAXS for the signed version

So min and max are no longer reserved words, and the menmonics do not look like min(,) max(,) macros in C.

Andy
• Posts: 2,996
min/max are not defined in C, but they are defined in C++ STL. std::min and std::max are the normal expected definitions.

Intel added various min/max instructions to the extended instruction (SSE2, SSE4, etc.). MIXSD/MAXSD, MINPD/MAXPD, PMINSD/PMAXSD, etc. These all work as expected. ARM has similar stuff in their NEON extensions (VMIN/VMAX).
That's just two of the most common chips on the planet. I'm sure if I go look I can find more, and they will all work the way I expect them to work. Which is the opposite of what PASM does.
• Posts: 18,066
edited 2017-04-14 02:59
Roy Eltham wrote: »
Cluso,
I just don't agree with changing the meaning of MIN and MAX. Ask any programmer anywhere, and they will say that MAX should give you the maximum of the two values. This is because on other CPUs and in most languages that have MAX, that's what it does.

I'm fine with the #> and <# being how they are, but I strongly think the PASM instructions need a new name that is not MAX or MIN (nor contain them). I like CLAMPU/CLAMPL, or maybe CLAMPGE/CLAMPLE.

Then we can make functions called MIN and MAX that do what is expecting my most everyone.
I have to confess, I was caught out enough originally, that I always check the manual for these, both in pasm and spin.

Here are some possible suggestions for naming...
```Possible suggestions:
--P1--  -----new suggestions---------------------------------------------------
PASM2:
MAX     MIN     LOWER   LOLIM   LIMLO   LIMITL  LIMITLO LIMMIN  CLAMPL  CLAMPLE
MAXS    MINS    LOWERS  LOLIMS  LIMLOS  LIMITLS LIMITLS LIMMINS CLAMPLS CLAMPLS
MIN     MAX     UPPER   HILIM   LIMHI   LIMITH  LIMITHI LIMMAX  CLAMPU  CLAMPGE
MINS    MAXS    UPPERS  HILIMS  LIMHIS  LIMITHS LIMITHS LIMMAXS CLAMPUS CLAMPGS
SPIN2:
#>      #>      LOWERS  LOLIMS  LIMLOS  LIMITLS LIMITLS LIMMINS CLAMPLS CLAMPLS
<#      <#      UPPERS  HILIMS  LIMHIS  LIMITHS LIMITHS LIMMAXS CLAMPUS CLAMPGS
```

Once decided, can we back fix (the same into???) P1 PASM1 and SPIN1 ???
• Posts: 21,230
You mean "PMAXSD" actually means something to you?

Well, why not, Intel has been adding a few new instructions every month for three decades now!