you know there are a lacking tiny functions in c-lib
(by c-lib i mean those standard c includes all know)
AND if people use many maybe there is a need to standarize it
byslef? if you need some could be ggood candidates for standarisation
maybe write it here (i mean whole body of such function)
we could and should discuss them
fir pisze:
you know there are a lacking tiny functions in c-lib
(by c-lib i mean those standard c includes all know)
AND if people use many maybe there is a need to standarize it
byslef? if you need some could be ggood candidates for standarisation
maybe write it here (i mean whole body of such function)
we could and should discuss them
maybe something liek this?
int mini(int a,int b) { return a<b?a:b; }
int maxi(int a,int b) { return a>b?a:b; }
float minf(float a,float b) { return a<b?a:b; }
float maxf(float a,float b) { return a>b?a:b; }
int absi(int x) { return x<0?-x:x; }
float absf(float x) { return x<0?-x:x; }
float signf(float x) { return x>0?1:x<0?-1:0; }
int signi(int x) { return x>0?1:x<0?-1:0; }
//above controversial?
int clampi(int x,int a,int b) { return x<a?a:x>b?b:x; }
float clampf(float x,float a,float b) { return x<a?a:x>b?b:x; }
int betweeni(int x,int a,int b) {-a return x>=a && x<=b; }
float lerp(float a,float b,float t) { return a+(b-a)*t; }
float inv_lerp(float a,float b,float x) { return (x-a)/(b-a); }
float remap(float x,float a,float b,float c,float d) { return c+(x- a)*(d-c)/(b-a); }
float rad(float x) { return x*PI/180.0f; }
float deg(float x) { return x*180.0f/PI; }
//thise above i dont quite use
float dist2_square(float x1,float y1,float x2,float y2) {-a-a float x=x2- x1,y=y2-y1;-a-a-a-a return x*x+y*y; }
float dist2(float x1,float y1,float x2,float y2) {-a-a-a return sqrtf(dist2(x1,y1,x2,y2));}
float len2_square(float x,float y) {-a-a-a return x*x+y*y; }
float len2(float x,float y) {-a return sqrtf(x*x+y*y);}
float dot2(float ax,float ay,float bx,float by){-a-a return ax*bx+ay*by;} float cross2(float ax,float ay,float bx,float by){-a-a-a return ax*by-ay*bx;} void-a norm2(float *x,float *y) {-a float d=sqrtf(*x**x+*y**y);-a-a if(d>0) { *x/=d;-a *y/=d; }}
float dist2_to_line(float px,float py,float ax,float ay,float bx,float by){-a-a-a return fabsf(cross2(bx-ax,by-ay,px-ax,py-ay)) / sqrtf(dist2_square(ax,ay,bx,by));}
On 27/09/2026 19:04, fir wrote:
fir pisze:
you know there are a lacking tiny functions in c-lib
(by c-lib i mean those standard c includes all know)
AND if people use many maybe there is a need to standarize it
byslef? if you need some could be ggood candidates for standarisation
maybe write it here (i mean whole body of such function)
we could and should discuss them
maybe something liek this?
int mini(int a,int b) { return a<b?a:b; }
int maxi(int a,int b) { return a>b?a:b; }
float minf(float a,float b) { return a<b?a:b; }
float maxf(float a,float b) { return a>b?a:b; }
int absi(int x) { return x<0?-x:x; }
float absf(float x) { return x<0?-x:x; }
float signf(float x) { return x>0?1:x<0?-1:0; }
int signi(int x) { return x>0?1:x<0?-1:0; }
//above controversial?
int clampi(int x,int a,int b) { return x<a?a:x>b?b:x; }
float clampf(float x,float a,float b) { return x<a?a:x>b?b:x; }
int betweeni(int x,int a,int b) {-a return x>=a && x<=b; }
My systems language has these as built-ins. That means they are
overloaded for all numeric types.
Here, a, b, c are signed or unsigned 64-bit ints, and x,y,z can be 32-
or 64-bit floats:
-a-a-a min(a, b)
-a-a-a min(x, y)
-a-a-a max(x, y)
-a-a-a max(x, y)
-a-a-a abs(a)
-a-a-a abs(x)
-a-a-a sign(a)
-a-a-a sign(x)
-a-a-a clamp(a, b, c)
-a-a-a clamp(x, y, z)
-a-a-a a in b..c-a-a-a-a-a-a-a-a # or:
-a-a-a b <= a <= c
-a-a-a x <= y <= z
I wouldn't have a problem with these being part of standard C. But since they will be functions (they will never be added to the core), you will
need versions for:
-a-a i32 u32 i64 u64 f32 f64
You might get away having only 64-bit versions, but on 32-targets that
would be inefficient.
Note that abs, labs, llabs, fabs, fabsf already exist in the standard library. Notice that 'abs' has 3 integer versions, so it is possible it
can get even uglier than I said; you might need versions for:
-a-a int, long, long long, i32 i64
-a-a unsigned int, unsigned long, unsigned long long, u32 u64
to cover both 'classic' int types and ones from stdint.h.
(abs() will only need signed; but anything involving comparisons needs both.)
float lerp(float a,float b,float t) { return a+(b-a)*t; }
float inv_lerp(float a,float b,float x) { return (x-a)/(b-a); }
float remap(float x,float a,float b,float c,float d) { return c+(x-
a)*(d-c)/(b-a); }
I've never heard of these.
float rad(float x) { return x*PI/180.0f; }This will be application-specific and don't really belong in a language
float deg(float x) { return x*180.0f/PI; }
//thise above i dont quite use
float dist2_square(float x1,float y1,float x2,float y2) {-a-a float
x=x2- x1,y=y2-y1;-a-a-a-a return x*x+y*y; }
float dist2(float x1,float y1,float x2,float y2) {-a-a-a return
sqrtf(dist2(x1,y1,x2,y2));}
float len2_square(float x,float y) {-a-a-a return x*x+y*y; }
float len2(float x,float y) {-a return sqrtf(x*x+y*y);}
float dot2(float ax,float ay,float bx,float by){-a-a return ax*bx+ay*by;}
float cross2(float ax,float ay,float bx,float by){-a-a-a return
ax*by-ay*bx;}
void-a norm2(float *x,float *y) {-a float d=sqrtf(*x**x+*y**y);
if(d>0) { *x/=d;-a *y/=d; }}
float dist2_to_line(float px,float py,float ax,float ay,float bx,float
by){-a-a-a return fabsf(cross2(bx-ax,by-ay,px-ax,py-ay)) /
sqrtf(dist2_square(ax,ay,bx,by));}
like C. They can be in a third-party library.
(I used to have many of these in my first scripting language, but that
was part of my 3D graphics apps. It was a sort of DSL. My current
scripting language doesn't have them.)
But if such a library is created, it needs to have a lot more. Like supporting 3D for a start. Beyond that it would again depend on application.)
AND if people use many maybe there is a need to standarize it
byslef? if you need some could be ggood candidates for standarisation
maybe write it here (i mean whole body of such function)
we could and should discuss them
bart pisze:
On 27/09/2026 19:04, fir wrote:
fir pisze:
you know there are a lacking tiny functions in c-lib
(by c-lib i mean those standard c includes all know)
AND if people use many maybe there is a need to standarize it
byslef? if you need some could be ggood candidates for
standarisation maybe write it here (i mean whole body of such function) >>>>
we could and should discuss them
maybe something liek this?
int mini(int a,int b) { return a<b?a:b; }
int maxi(int a,int b) { return a>b?a:b; }
float minf(float a,float b) { return a<b?a:b; }
float maxf(float a,float b) { return a>b?a:b; }
int absi(int x) { return x<0?-x:x; }
float absf(float x) { return x<0?-x:x; }
float signf(float x) { return x>0?1:x<0?-1:0; }
int signi(int x) { return x>0?1:x<0?-1:0; }
//above controversial?
int clampi(int x,int a,int b) { return x<a?a:x>b?b:x; }
float clampf(float x,float a,float b) { return x<a?a:x>b?b:x; }
int betweeni(int x,int a,int b) {-a return x>=a && x<=b; }
My systems language has these as built-ins. That means they are
overloaded for all numeric types.
Here, a, b, c are signed or unsigned 64-bit ints, and x,y,z can be 32-
or 64-bit floats:
-a-a-a-a min(a, b)
-a-a-a-a min(x, y)
-a-a-a-a max(x, y)
-a-a-a-a max(x, y)
-a-a-a-a abs(a)
-a-a-a-a abs(x)
-a-a-a-a sign(a)
-a-a-a-a sign(x)
-a-a-a-a clamp(a, b, c)
-a-a-a-a clamp(x, y, z)
-a-a-a-a a in b..c-a-a-a-a-a-a-a-a # or:
-a-a-a-a b <= a <= c
-a-a-a-a x <= y <= z
I wouldn't have a problem with these being part of standard C. But
since they will be functions (they will never be added to the core),
you will need versions for:
-a-a-a i32 u32 i64 u64 f32 f64
You might get away having only 64-bit versions, but on 32-targets that
would be inefficient.
Note that abs, labs, llabs, fabs, fabsf already exist in the standard
library. Notice that 'abs' has 3 integer versions, so it is possible
it can get even uglier than I said; you might need versions for:
-a-a-a int, long, long long, i32 i64
-a-a-a unsigned int, unsigned long, unsigned long long, u32 u64
to cover both 'classic' int types and ones from stdint.h.
(abs() will only need signed; but anything involving comparisons needs
both.)
float lerp(float a,float b,float t) { return a+(b-a)*t; }
float inv_lerp(float a,float b,float x) { return (x-a)/(b-a); }
float remap(float x,float a,float b,float c,float d) { return c+(x-
a)*(d-c)/(b-a); }
I've never heard of these.
float rad(float x) { return x*PI/180.0f; }This will be application-specific and don't really belong in a
float deg(float x) { return x*180.0f/PI; }
//thise above i dont quite use
float dist2_square(float x1,float y1,float x2,float y2) {-a-a float
x=x2- x1,y=y2-y1;-a-a-a-a return x*x+y*y; }
float dist2(float x1,float y1,float x2,float y2) {-a-a-a return
sqrtf(dist2(x1,y1,x2,y2));}
float len2_square(float x,float y) {-a-a-a return x*x+y*y; }
float len2(float x,float y) {-a return sqrtf(x*x+y*y);}
float dot2(float ax,float ay,float bx,float by){-a-a return ax*bx+ay*by;} >>> float cross2(float ax,float ay,float bx,float by){-a-a-a return ax*by-
ay*bx;}
void-a norm2(float *x,float *y) {-a float d=sqrtf(*x**x+*y**y); if(d>0) >>> { *x/=d;-a *y/=d; }}
float dist2_to_line(float px,float py,float ax,float ay,float
bx,float by){-a-a-a return fabsf(cross2(bx-ax,by-ay,px-ax,py-ay)) /
sqrtf(dist2_square(ax,ay,bx,by));}
language like C. They can be in a third-party library.
(I used to have many of these in my first scripting language, but that
was part of my 3D graphics apps. It was a sort of DSL. My current
scripting language doesn't have them.)
But if such a library is created, it needs to have a lot more. Like
supporting 3D for a start. Beyond that it would again depend on
application.)
i not quite understood why most of it cant be added (?)
literally i forgot there is fabs and fmin fmax - it is all mess that
some are some not.. imo it should be standarised just to not various
names be used for same thing of various thing for same name
(lask of this standarisatio is also another c annoyance imo)
On 27/09/2026 22:16, fir wrote:
bart pisze:
On 27/09/2026 19:04, fir wrote:
fir pisze:
you know there are a lacking tiny functions in c-lib
(by c-lib i mean those standard c includes all know)
AND if people use many maybe there is a need to standarize it
byslef? if you need some could be ggood candidates for
standarisation maybe write it here (i mean whole body of such
function)
we could and should discuss them
maybe something liek this?
int mini(int a,int b) { return a<b?a:b; }
int maxi(int a,int b) { return a>b?a:b; }
float minf(float a,float b) { return a<b?a:b; }
float maxf(float a,float b) { return a>b?a:b; }
int absi(int x) { return x<0?-x:x; }
float absf(float x) { return x<0?-x:x; }
float signf(float x) { return x>0?1:x<0?-1:0; }
int signi(int x) { return x>0?1:x<0?-1:0; }
//above controversial?
int clampi(int x,int a,int b) { return x<a?a:x>b?b:x; }
float clampf(float x,float a,float b) { return x<a?a:x>b?b:x; }
int betweeni(int x,int a,int b) {-a return x>=a && x<=b; }
My systems language has these as built-ins. That means they are
overloaded for all numeric types.
Here, a, b, c are signed or unsigned 64-bit ints, and x,y,z can be
32- or 64-bit floats:
-a-a-a-a min(a, b)
-a-a-a-a min(x, y)
-a-a-a-a max(x, y)
-a-a-a-a max(x, y)
-a-a-a-a abs(a)
-a-a-a-a abs(x)
-a-a-a-a sign(a)
-a-a-a-a sign(x)
-a-a-a-a clamp(a, b, c)
-a-a-a-a clamp(x, y, z)
-a-a-a-a a in b..c-a-a-a-a-a-a-a-a # or:
-a-a-a-a b <= a <= c
-a-a-a-a x <= y <= z
I wouldn't have a problem with these being part of standard C. But
since they will be functions (they will never be added to the core),
you will need versions for:
-a-a-a i32 u32 i64 u64 f32 f64
You might get away having only 64-bit versions, but on 32-targets
that would be inefficient.
Note that abs, labs, llabs, fabs, fabsf already exist in the standard
library. Notice that 'abs' has 3 integer versions, so it is possible
it can get even uglier than I said; you might need versions for:
-a-a-a int, long, long long, i32 i64
-a-a-a unsigned int, unsigned long, unsigned long long, u32 u64
to cover both 'classic' int types and ones from stdint.h.
(abs() will only need signed; but anything involving comparisons
needs both.)
float lerp(float a,float b,float t) { return a+(b-a)*t; }
float inv_lerp(float a,float b,float x) { return (x-a)/(b-a); }
float remap(float x,float a,float b,float c,float d) { return c+(x-
a)*(d-c)/(b-a); }
I've never heard of these.
float rad(float x) { return x*PI/180.0f; }This will be application-specific and don't really belong in a
float deg(float x) { return x*180.0f/PI; }
//thise above i dont quite use
float dist2_square(float x1,float y1,float x2,float y2) {-a-a float
x=x2- x1,y=y2-y1;-a-a-a-a return x*x+y*y; }
float dist2(float x1,float y1,float x2,float y2) {-a-a-a return
sqrtf(dist2(x1,y1,x2,y2));}
float len2_square(float x,float y) {-a-a-a return x*x+y*y; }
float len2(float x,float y) {-a return sqrtf(x*x+y*y);}
float dot2(float ax,float ay,float bx,float by){-a-a return ax*bx+ay*by;} >>>> float cross2(float ax,float ay,float bx,float by){-a-a-a return ax*by- >>>> ay*bx;}
void-a norm2(float *x,float *y) {-a float d=sqrtf(*x**x+*y**y);
if(d>0) { *x/=d;-a *y/=d; }}
float dist2_to_line(float px,float py,float ax,float ay,float
bx,float by){-a-a-a return fabsf(cross2(bx-ax,by-ay,px-ax,py-ay)) /
sqrtf(dist2_square(ax,ay,bx,by));}
language like C. They can be in a third-party library.
(I used to have many of these in my first scripting language, but
that was part of my 3D graphics apps. It was a sort of DSL. My
current scripting language doesn't have them.)
But if such a library is created, it needs to have a lot more. Like
supporting 3D for a start. Beyond that it would again depend on
application.)
i not quite understood why most of it cant be added (?)
Because it is application-specific as I said.
Ones like MIN(x, y) can be considered fundamental, but not the length of
a 2D vector which takes discrete X, Y float arguments.
It is just too specific, and the requirements in real applications will
be too diverse.
And also, where do you stop; why not a string library and a million
other things?
I'm sure there are plenty of such libraries about. They don't need to be core language features at this level.
literally i forgot there is fabs and fmin fmax - it is all mess that
some are some not.. imo it should be standarised just to not various
names be used for same thing of various thing for same name
I wasn't aware of fmin etc. But they can't use the same name as there
needs to be one function for each type.
Unless fminl/fmaxl, which take 'long double', also deal with float and double, but it can mean expensive conversions.
(lask of this standarisatio is also another c annoyance imo)
float len2(float x,float y) { return sqrtf(x*x+y*y);}
Ones like MIN(x, y) can be considered fundamental, but not the length of
a 2D vector which takes discrete X, Y float arguments.
It is just too specific, and the requirements in real applications will
be too diverse.
And also, where do you stop; why not a string library and a million
other things?
I'm sure there are plenty of such libraries about. They don't need to be core language features at this level.
literally i forgot there is fabs and fmin fmax - it is all mess that
some are some not.. imo it should be standarised just to not various
names be used for same thing of various thing for same name
I wasn't aware of fmin etc. But they can't use the same name as there
needs to be one function for each type.
Unless fminl/fmaxl, which take 'long double', also deal with float and double, but it can mean expensive conversions.
On Sun, 27 Sep 2026 20:04:20 +0200, fir wrote:
float len2(float x,float y) { return sqrtf(x*x+y*y);}
Interesting:
/*
Comparison of the na|>ve calculation of a triangle
hypotenuse with the standard-library hypot(3) function.
*/
#include <math.h>
#include <values.h>
#include <stdio.h>
static float len2(float x,float y) { return sqrtf(x*x+y*y);}
static void compare_for
(
float x
)
{
fprintf
(
stdout,
"for %.7e: len2 = %.7e, hypot = %.7e\n",
x, len2(x, x), hypotf(x, x)
);
} /*compare_for*/
int main(void)
{
compare_for(FLT_MAX / 2.0f);
compare_for(2.0 / FLT_MAX);
return
0;
} /*main*/
Output:
ldo@theon:c_try> !./
./naive_hypot
for 1.7014117e+38: len2 = inf, hypot = 2.4061594e+38
for 5.8774718e-39: len2 = 0.0000000e+00, hypot = 8.3120008e-39
ldo@theon:c_try>
How is it the standard library function is able to produce a reasonable-looking result where your function breaks down?
On Sun, 27 Sep 2026 20:04:20 +0200, fir wrote:
float len2(float x,float y) { return sqrtf(x*x+y*y);}
Interesting:
/*
Comparison of the na|>ve calculation of a triangle
hypotenuse with the standard-library hypot(3) function.
*/
#include <math.h>
#include <values.h>
#include <stdio.h>
static float len2(float x,float y) { return sqrtf(x*x+y*y);}
static void compare_for
(
float x
)
{
fprintf
(
stdout,
"for %.7e: len2 = %.7e, hypot = %.7e\n",
x, len2(x, x), hypotf(x, x)
);
} /*compare_for*/
int main(void)
{
compare_for(FLT_MAX / 2.0f);
compare_for(2.0 / FLT_MAX);
return
0;
} /*main*/
Output:
ldo@theon:c_try> !./
./naive_hypot
for 1.7014117e+38: len2 = inf, hypot = 2.4061594e+38
for 5.8774718e-39: len2 = 0.0000000e+00, hypot = 8.3120008e-39
ldo@theon:c_try>
How is it the standard library function is able to produce a reasonable-looking result where your function breaks down?
On 28/09/2026 01:53, bart wrote:
Ones like MIN(x, y) can be considered fundamental, but not the length
of a 2D vector which takes discrete X, Y float arguments.
It also has a "hypot" function that returns, approximately, sqrt(x*x +
y*y).
C has a string library.
It's not very high level, compared to the
support found in many other languages.
I'm sure there are plenty of such libraries about. They don't need to
be core language features at this level.
Agreed.-a Things like "min", "abs", trig functions, etc., should normally not be core language features in any language unless the language is dedicated to numerical calculations.
Lots can be part of a standard
library, however.-a There's no rule where the line should be drawn
between standard libraries and additional libraries - that depends on
the language.-a Since we are in c.l.c., the C standards show where the
line is drawn in C.
I wasn't aware of fmin etc. But they can't use the same name as there
needs to be one function for each type.
C has had type-generic maths macros since C99 - if you use #include <tgmath.h> and write "fabs(x)", then the appropriate real or complex floating point fabs, fabsf, fabsl, cabs, cabsf, cabsl function will be called.
On 28/09/2026 09:25, David Brown wrote:
On 28/09/2026 01:53, bart wrote:
Ones like MIN(x, y) can be considered fundamental, but not the length
of a 2D vector which takes discrete X, Y float arguments.
It also has a "hypot" function that returns, approximately, sqrt(x*x +
y*y).
fir's len2 function was one of a suite of functions familiar to me from
3D graphics.
If C's obscure 'hypot' function does that job, then great. My point was
that that set of functions was too specific for a general purpose
language at this level.
But then, MSVCRT.DLL exports over 1300 functions, about the same number
as SDL3!
C has a string library.
OK. I meant a higher level one!
It's not very high level, compared to the support found in many other
languages.
I'm sure there are plenty of such libraries about. They don't need to
be core language features at this level.
Agreed.-a Things like "min", "abs", trig functions, etc., should
normally not be core language features in any language unless the
language is dedicated to numerical calculations.
Many of these are available as machine instructions, so they are
considered fundamental there. Some are available on my Casio.
You think a cheap calculator should have sin() but not a programming language?
Having them via user-functions in standard library is just about
acceptable, but it's not ideal - see below for the machinations that are needed when you need to overload.
One of fir's points, with which I agree, is that how C does it is a mess.
Lots can be part of a standard library, however.-a There's no rule
where the line should be drawn between standard libraries and
additional libraries - that depends on the language.-a Since we are in
c.l.c., the C standards show where the line is drawn in C.
So why was hypot() ever added? Somebody thought it was a good idea at
one time to add a such a one-line function?
But then a one-line function is also trivial to write in user-code,
compared to your own cos() for example.
I wasn't aware of fmin etc. But they can't use the same name as there
needs to be one function for each type.
C has had type-generic maths macros since C99 - if you use #include
<tgmath.h> and write "fabs(x)", then the appropriate real or complex
floating point fabs, fabsf, fabsl, cabs, cabsf, cabsl function will be
called.
OK. I don't have tgmath.h in bcc, and tcc doesn't have it either. But
I've looked at how it works in those that do. If I try this program:
-a-a-a ly = sin(lx);-a // long double
-a-a-a dy = sin(dx);-a // double
-a-a-a fy = sin(fx);-a // float
then lccwin32 preprocesses it to:
-a-a-a ly = __sin(lx);
-a-a-a dy = __sin(dx);
-a-a-a fy = __sin(fx);
Clang does:
-aly = __tg_sin((__typeof__(__tg_promote((lx))))(lx));
-ady = __tg_sin((__typeof__(__tg_promote((dx))))(dx));
-afy = __tg_sin((__typeof__(__tg_promote((fx))))(fx));
And Gcc does:
-a __builtin_tgmath (sinf, sin, sinl, csinf, csin, csinl, (lx))
-a __builtin_tgmath (sinf, sin, sinl, csinf, csin, csinl, (dx))
-a __builtin_tgmath (sinf, sin, sinl, csinf, csin, csinl, (fx))
So it's not clear how the mechanism works. Compiler magic?
With lccwin32 at least, it seems it implements an actual overloaded
sin() in the form of __sin(), to distinguish from the underlying sin()
in C which uses 'double'.
But in practice, tgmath is used so rarely in open source code I've seen, that I've forgotten it existed.
On 28/09/2026 09:25, David Brown wrote:
On 28/09/2026 01:53, bart wrote:
Ones like MIN(x, y) can be considered fundamental, [...]
It also has a "hypot" function that returns, approximately, sqrt(x*x +
y*y).
[...]
If C's obscure 'hypot' function does that job, then great.
My point was
that that set of functions was too specific for a general purpose
language at this level.
[...]
I'm sure there are plenty of such libraries about. They don't need to
be core language features at this level.
Agreed.-a Things like "min", "abs", trig functions, etc., should
normally not be core language features in any language unless the
language is dedicated to numerical calculations.
Many of these are available as machine instructions, so they are
considered fundamental there. Some are available on my Casio.
You think a cheap calculator should have sin() but not a programming language?
Having them via user-functions in standard library is just about
acceptable, but it's not ideal - [...]
One of fir's points, with which I agree, is that how C does it is a mess.
Lots can be part of a standard library, however.-a There's no rule
where the line should be drawn between standard libraries and
additional libraries - that depends on the language.-a Since we are in
c.l.c., the C standards show where the line is drawn in C.
So why was hypot() ever added? Somebody thought it was a good idea at
one time to add a such a one-line function?
But then a one-line function is also trivial to write in user-code,
compared to your own cos() for example.
[...]
On 28/09/2026 12:45, bart wrote:
On 28/09/2026 09:25, David Brown wrote:
On 28/09/2026 01:53, bart wrote:
Ones like MIN(x, y) can be considered fundamental, but not the
length of a 2D vector which takes discrete X, Y float arguments.
It also has a "hypot" function that returns, approximately, sqrt(x*x
+ y*y).
fir's len2 function was one of a suite of functions familiar to me
from 3D graphics.
If C's obscure 'hypot' function does that job, then great. My point
was that that set of functions was too specific for a general purpose
language at this level.
"hypot" - short for "hypotenuse" but easier to spell - is not obscure.
It is a common name and part of the IEEE 754 standard.-a It makes a lot
of sense for a language that is often used with code that requires conformance to that standard, to have support for the standard's
required and recommended functions in its standard library.-a As Lawrence showed, proper implementations of such functions is not just a matter of copying the pure mathematical formula.
It is common to have "sin" as a standard library function in languages,
but not as part of the core language itself.-a It is pointless having
such functions in core language, taking up limited identifier space with
a keyword that the solid majority of programs will never need.-a Put it
in the library.
taking up limited identifier space with
I've had my own "sin" function in C programs.-a I do not remember that
any complications were involved.
One of fir's points, with which I agree, is that how C does it is a mess.
Lots can be part of a standard library, however.-a There's no rule
where the line should be drawn between standard libraries and
additional libraries - that depends on the language.-a Since we are in
c.l.c., the C standards show where the line is drawn in C.
So why was hypot() ever added? Somebody thought it was a good idea at
one time to add a such a one-line function?
It is not a one-line function.-a Did you fail to read that bit of my
post?
With lccwin32 at least, it seems it implements an actual overloaded
sin() in the form of __sin(), to distinguish from the underlying sin()
in C which uses 'double'.
With only the information you posted to go on, it looks more like a
direct use of a single "__sin" function, but it is entirely possible
that the compiler has some extensions that are not visible here.-a I
don't know the details of lccwin32 - it is not a toolchain of interest
to me.
On 28/09/2026 12:56, David Brown wrote:
On 28/09/2026 12:45, bart wrote:
On 28/09/2026 09:25, David Brown wrote:
On 28/09/2026 01:53, bart wrote:
Ones like MIN(x, y) can be considered fundamental, but not the
length of a 2D vector which takes discrete X, Y float arguments.
It also has a "hypot" function that returns, approximately, sqrt(x*x
+ y*y).
fir's len2 function was one of a suite of functions familiar to me
from 3D graphics.
If C's obscure 'hypot' function does that job, then great. My point
was that that set of functions was too specific for a general purpose
language at this level.
"hypot" - short for "hypotenuse" but easier to spell - is not obscure.
It is a common name and part of the IEEE 754 standard.-a It makes a lot
of sense for a language that is often used with code that requires
conformance to that standard, to have support for the standard's
required and recommended functions in its standard library.-a As
Lawrence showed, proper implementations of such functions is not just
a matter of copying the pure mathematical formula.
He showed a way to avoid overflowing (with inputs above 10**19) if you
can't be bothered to use a more appropriate type.
However everywhere there is x*x in a program, or even x*y and x/y, there
can be floating point overflow for certain values of x and y.
You just have to be aware of what you are doing and know the limitations.
It is common to have "sin" as a standard library function in
languages, but not as part of the core language itself.-a It is
pointless having such functions in core language, taking up limited
identifier space with a keyword that the solid majority of programs
will never need.-a Put it in the library.
Disagree. Make it part of the core language and you get benefits:
- Easier for a simple compiler to optimise for example
- Easier to overload across numeric types
- Always available without needing those annoying #includes (and is
-a it math.h or float.h? I can never remember).
- Not possible to override (in Python you can do math.sin = 342,
-a in C it possible to either shadow or write a private 'sin')
Downsides might be in not being able to create a function reference; it
all depends on how the language works.
taking up limited identifier space with
See my last point - you don't /want/ user programs to use 'sin'!
As for limited identifier space, AFAICS that is essentially unlimited.
I've had my own "sin" function in C programs.-a I do not remember that
any complications were involved.
The usual approach for a custom version is to use a slightly different
name. I dislike overriding or shadowing built-ins.
(Funny how shadowing or overriding is usually perceived as bad, until
you want to shadow something like 'sin' then it's a must-have!)
One of fir's points, with which I agree, is that how C does it is a
mess.
Lots can be part of a standard library, however.-a There's no rule
where the line should be drawn between standard libraries and
additional libraries - that depends on the language.-a Since we are
in c.l.c., the C standards show where the line is drawn in C.
So why was hypot() ever added? Somebody thought it was a good idea at
one time to add a such a one-line function?
It is not a one-line function.-a Did you fail to read that bit of my post?
I did then I misremembered it as being from LD'O's post which I replied to.
On Sun, 27 Sep 2026 20:04:20 +0200, fir wrote:
float len2(float x,float y) { return sqrtf(x*x+y*y);}
Interesting:
/*
Comparison of the na|>ve calculation of a triangle
hypotenuse with the standard-library hypot(3) function.
*/
#include <math.h>
#include <values.h>
#include <stdio.h>
static float len2(float x,float y) { return sqrtf(x*x+y*y);}
static void compare_for
(
float x
)
{
fprintf
(
stdout,
"for %.7e: len2 = %.7e, hypot = %.7e\n",
x, len2(x, x), hypotf(x, x)
);
} /*compare_for*/
int main(void)
{
compare_for(FLT_MAX / 2.0f);
compare_for(2.0 / FLT_MAX);
return
0;
} /*main*/
Output:
ldo@theon:c_try> !./
./naive_hypot
for 1.7014117e+38: len2 = inf, hypot = 2.4061594e+38
for 5.8774718e-39: len2 = 0.0000000e+00, hypot = 8.3120008e-39
ldo@theon:c_try>
How is it the standard library function is able to produce a reasonable-looking result where your function breaks down?
On 28/09/2026 09:25, David Brown wrote:sqrt(x*x +
It also has a "hypot" function that returns, approximately,
It was part of the major expansion to the <math.h> library that occurredy*y).So why was hypot() ever added? Somebody thought it was a good idea at
one time to add a such a one-line function?
But Fir could well have included other functions that are not likely to
make sense in a standard library for a general-purpose programming
language - and to have omitted many that should be there.
On 28/09/2026 12:45, bart wrote:
On 28/09/2026 09:25, David Brown wrote:sqrt(x*x +
It also has a "hypot" function that returns, approximately,
It was part of the major expansion to the <math.h> library that occurredy*y).So why was hypot() ever added? Somebody thought it was a good idea at
one time to add a such a one-line function?
in C99. It was added because of the "without undue overflow or
underflow." requirement. Achieving that result makes it a bit more complicated than just a one-line function. Also, even most people who
are well aware of that problem are unaware of how best to avoid it. See <https://en.wikipedia.org/wiki/Pythagorean_addition#Calculation_order>
for more details.
fir pisze:
you know there are a lacking tiny functions in c-lib
(by c-lib i mean those standard c includes all know)
AND if people use many maybe there is a need to standarize it
byslef? if you need some could be ggood candidates for standarisation
maybe write it here (i mean whole body of such function)
we could and should discuss them
maybe something liek this?
int mini(int a,int b) { return a<b?a:b; }
int maxi(int a,int b) { return a>b?a:b; }
float minf(float a,float b) { return a<b?a:b; }
float maxf(float a,float b) { return a>b?a:b; }
int absi(int x) { return x<0?-x:x; }
float absf(float x) { return x<0?-x:x; }
float signf(float x) { return x>0?1:x<0?-1:0; }
int signi(int x) { return x>0?1:x<0?-1:0; }
//above controversial?
int clampi(int x,int a,int b) { return x<a?a:x>b?b:x; }
float clampf(float x,float a,float b) { return x<a?a:x>b?b:x; }
int betweeni(int x,int a,int b) {-a return x>=a && x<=b; }
float lerp(float a,float b,float t) { return a+(b-a)*t; }
float inv_lerp(float a,float b,float x) { return (x-a)/(b-a); }
float remap(float x,float a,float b,float c,float d) { return c+(x-a)*(d-c)/(b-a); }
float rad(float x) { return x*PI/180.0f; }
float deg(float x) { return x*180.0f/PI; }
//thise above i dont quite use
float dist2_square(float x1,float y1,float x2,float y2) {-a-a float x=x2-x1,y=y2-y1;-a-a-a-a return x*x+y*y; }
float dist2(float x1,float y1,float x2,float y2) {-a-a-a return sqrtf(dist2(x1,y1,x2,y2));}
float len2_square(float x,float y) {-a-a-a return x*x+y*y; }
float len2(float x,float y) {-a return sqrtf(x*x+y*y);}
float dot2(float ax,float ay,float bx,float by){-a-a return ax*bx+ay*by;} float cross2(float ax,float ay,float bx,float by){-a-a-a return ax*by-ay*bx;} void-a norm2(float *x,float *y) {-a float d=sqrtf(*x**x+*y**y);-a-a if(d>0) { *x/=d;-a *y/=d; }}
float dist2_to_line(float px,float py,float ax,float ay,float bx,float by){-a-a-a return fabsf(cross2(bx-ax,by-ay,px-ax,py-ay)) /sqrtf(dist2_square(ax,ay,bx,by));}
// hare names may be controversial
the fact is imo though people should generallu decide and use one set of such names imo
there is also more functions to put here
On 28/09/2026 15:38, bart wrote:
As for limited identifier space, AFAICS that is essentially unlimited.
Don't be silly.
I've had my own "sin" function in C programs.-a I do not remember that
any complications were involved.
The usual approach for a custom version is to use a slightly different
name. I dislike overriding or shadowing built-ins.
Your "usual approach" and what you like or dislike is no indication of
what other people may do.-a There are reasons why I would sometimes pick
a name that is different from the standard library name, and reasons
while I would sometimes pick the same name.
(Funny how shadowing or overriding is usually perceived as bad, until
you want to shadow something like 'sin' then it's a must-have!)
It is not a "must-have", it is a convenience.-a Of course it's possible
to work in a language where "sin" is a built-in function that is fixed
in the language.-a But it usually has no benefit, and just disadvantages compared to using a standard library.-a That's why few languages since
BASIC have gone your route.
On 28/09/2026 15:12, David Brown wrote:
On 28/09/2026 15:38, bart wrote:
As for limited identifier space, AFAICS that is essentially unlimited.
Don't be silly.
But you brought it up!
I've had my own "sin" function in C programs.-a I do not remember
that any complications were involved.
The usual approach for a custom version is to use a slightly
different name. I dislike overriding or shadowing built-ins.
Your "usual approach" and what you like or dislike is no indication of
what other people may do.-a There are reasons why I would sometimes
pick a name that is different from the standard library name, and
reasons while I would sometimes pick the same name.
(Funny how shadowing or overriding is usually perceived as bad, until
you want to shadow something like 'sin' then it's a must-have!)
It is not a "must-have", it is a convenience.-a Of course it's possible
to work in a language where "sin" is a built-in function that is fixed
in the language.-a But it usually has no benefit, and just
disadvantages compared to using a standard library.-a That's why few
languages since BASIC have gone your route.
Yes, I know, most languages prefer to have things in libraries rather
than in the core.
Some even want to have basics such as statements in libraries (Clisp was mentioned but this stuff is popular in esolangs).
But one example where built-in is better is with Print. Otherwise this presents challenges to do in user-code:
* Variable-length set of arguments
* Mixed argument types
* Optional per-item information
* Optional per-print information (eg. destination)
* Less than ideal syntax
In C, this meant several things:
* Needing to add stdio.h each time
* Having to introduce variadic functions (possibly just for this reason)
* Less type safety
* Using format codes to import type information
Other languages have their own problems in fitting those requirements to standard functions
On 28/09/2026 17:52, bart wrote:
Yes, I know, most languages prefer to have things in libraries rather
than in the core.
So perhaps it's a good idea?
The examples below suggest otherwise.But one example where built-in is better is with Print. Otherwise this
presents challenges to do in user-code:
No, "print" is not "better" as a built-in.-a That's pure bias on your part.
Lots of programs have little or no use for "print", or they need
something significantly different (showing messages in a dialog box, printing them to logs or serial ports, etc.
These can all be handled in a language-definable function, and do not
need special handling.
Other languages have their own problems in fitting those requirementsIf you want something complex, it is complex.
to standard functions
All you do by having it as a special built-in feature of the language is limited its usefulness, and mean that people have to re-invent it anyway.
I understand your style of thinking - it's the way people thought about programming language forty-odd years ago.
It is not a one-line function. Did you fail to read that bit of my
post? My guess is that it was added to C (I have no idea when)
A C11 implementation might be :
#define sin(x) \
_Generic((x), \
float : sinf, \
double : sin, \
long double : sinl, \
float complex : csinf, \
double complex : csin, \
long double complex : csinl \
)(x)
its not breaking down, depend how you define breaking down for me
for exampla sinf cosf or pow can be said are breaking don if thay
count to much bits
You mean a reasonable looking result for quite unreasonable inputs?
On Mon, 28 Sep 2026 12:42:31 +0200, fir wrote:
its not breaking down, depend how you define breaking down for me
for exampla sinf cosf or pow can be said are breaking don if thay
count to much bits
Your code breaks down because it cannot produce a result which is
perfectly representable within the implementation range.
Lawrence DrCOOliveiro pisze:
On Mon, 28 Sep 2026 12:42:31 +0200, fir wrote:
its not breaking down, depend how you define breaking down for me
for exampla sinf cosf or pow can be said are breaking don if thay
count to much bits
Your code breaks down because it cannot produce a result which is
perfectly representable within the implementation range.
LOL, im not sure if i understand this above sentence but for me code
is broken if its too slow not when it present exact same graphics
just faster
If C's obscure 'hypot' function does that job, then great.
On 28/09/2026 15:38, bart wrote:
- Always available without needing those annoying #includes (and is
-a-a it math.h or float.h? I can never remember).
Other C programmers manage that without effort.
(Funny how shadowing or overriding is usually perceived as bad, until
you want to shadow something like 'sin' then it's a must-have!)
On 28/09/2026 12:56, David Brown wrote:
"hypot" - short for "hypotenuse" but easier to spell - is not
obscure. It is a common name and part of the IEEE 754 standard.-a It
makes a lot of sense for a language that is often used with code
that requires conformance to that standard, to have support for the
standard's required and recommended functions in its standard
library.-a As Lawrence showed, proper implementations of such
functions is not just a matter of copying the pure mathematical
formula.
He showed a way to avoid overflowing (with inputs above 10**19) if
you can't be bothered to use a more appropriate type.
But one example where built-in is better is with Print. Otherwise
this presents challenges to do in user-code:
On 28/09/2026 17:52, bart wrote:
But one example where built-in is better is with Print. Otherwise this
presents challenges to do in user-code:
No, "print" is not "better" as a built-in.-a That's pure bias on your part.
[...]
On 28/09/2026 17:49, David Brown wrote:
On 28/09/2026 17:52, bart wrote:
Yes, I know, most languages prefer to have things in libraries rather
than in the core.
So perhaps it's a good idea?
IS it a good idea? Or is it just what is commonly done and people go
along with it?
I always find it odd when people strive to keep a core language to a few dozen keywords to reduce 'cognitive load', but are fine with needing to
use a library that exports a thousand identifiers, all in the same namespace.
The examples below suggest otherwise.But one example where built-in is better is with Print. Otherwise
this presents challenges to do in user-code:
No, "print" is not "better" as a built-in.-a That's pure bias on your
part.
Lots of programs have little or no use for "print", or they need
something significantly different (showing messages in a dialog box,
printing them to logs or serial ports, etc.
So they /are/ using Print, which still has a variety of uses:
These can all be handled in a language-definable function, and do not
need special handling.
No, they usually can't. Functions generally take a fixed number of parameters, and in a typed language, they are also usually a fixed type.
Here is a task that prints an integer 'i', and its square root, followed
by a newline, to the console, in several languages:
Zig:-a-a std.debug.print("{} {}\n",.{i,@sqrt(@as(f64,@floatFromInt(i)))});
C:-a-a-a-a printf("%d %f\n", i, sqrt(i));
C++:-a-a std::cout << i << " " << sqrt(i) << std::endl;
M:-a-a-a-a println i, sqrt i
BASIC: 10 PRINT I, SQR(I)
The first three all need prerequisites to make it work. The last two
need nothing, not even variadic functions.
Maybe it's a coincidence that both have Print and Sqrt as built-ins.
Other languages have their own problems in fitting those requirementsIf you want something complex, it is complex.
to standard functions
All you do by having it as a special built-in feature of the language
is limited its usefulness, and mean that people have to re-invent it
anyway.
I understand your style of thinking - it's the way people thought
about programming language forty-odd years ago.
More like 50 years. But yes, when things were simple: see my examples
above. So what the hell happened?
David Brown <david.brown@hesbynett.no> writes:
[...]
It is not a one-line function. Did you fail to read that bit of my
post? My guess is that it was added to C (I have no idea when)
hypot(), hypotf(), and hypotl() were added in C99, along with the type-generic macro hypot() in <tgmath.h>.
[...]
A C11 implementation might be :
#define sin(x) \
_Generic((x), \
float : sinf, \
double : sin, \
long double : sinl, \
float complex : csinf, \
double complex : csin, \
long double complex : csinl \
)(x)
That wouldn't be conforming. The sin() macro with an argument of an
integer type has to work, converting the argument to double.
Handling that correctly and emitting sensible error messages for things
like sin("foo") is difficult if the implementation uses _Generic,
which is why some implementations use compiler "magic".
(tcc uses _Generic for this -- and it appears to have a bug whereby sin("foo") is not diagnosed and produces a garbage result).
[...]
On 2026-09-28 16:12, David Brown wrote:
On 28/09/2026 15:38, bart wrote:
- Always available without needing those annoying #includes (and is
-a-a it math.h or float.h? I can never remember).
Other C programmers manage that without effort.
I seem to recall that on his platform there's no man-pages.
(Or that he, maybe, dislikes looking into the documentation?
Sometime he gives that impression.)
(Funny how shadowing or overriding is usually perceived as bad, until
you want to shadow something like 'sin' then it's a must-have!)
Since when is shadowing (or "overriding" in its various forms)
"perceived as bad"? - I've always seen it as a useful feature.
And never heard anyone complaining about it.
In decades I also
don't recall that subtile (or obvious) errors had been reported
because of that. (Are you, yet again, just making things up for
the argument or have you any different observations from your
personal coding practice?)
On 28/09/2026 21:26, bart wrote:
On 28/09/2026 17:49, David Brown wrote:
Lots of programs have little or no use for "print", or they need
something significantly different (showing messages in a dialog box,
printing them to logs or serial ports, etc.
So they /are/ using Print, which still has a variety of uses:
No, they are not.
They are doing /related/ tasks, but not the kind of thing you get from a "print" statement in BASIC.
If "print" is a fixed, special built-in feature of the language, then it
is not flexible enough to handle different situations.
-a If instead you
make the core language powerful enough to write "print" as a function
(which you can then put in the standard library for convenience), then people needing different related tools can make their own.
BASIC is made to be simple to learn for beginners, and not for large, serious, long-term programs.-a And it's great for its task.-a But it is inflexible and not scalable.
Oh, and modern C++ provides :
-a-a-a-aimport std;
-a-a-a-astd::println("i = {}, reUi = {}", i, std::sqrt(i));
With C11, I can write my own print/println macros so that I can write :
-a-a-a-aprintln("i = ", i, ", reUi = ", sqrt(i));
These are all type-safe, by the way.
And with the C++ version, when you make "i" a complex number, it works
the same.-a When you make a square matrix class and make "i" a matrix,
you can write formatters (for the "cout" and "print/println/format" versions) for printing out your matrices.-a You can write a "sqrt"
function for your matrices.-a (The C11 macros are less flexible - you
need to know the types when the macros are defined.)
Yes, BASIC - and your language - are simple for simple programs in
specific use-cases and specific environments.
More like 50 years. But yes, when things were simple: see my examples
above. So what the hell happened?
The world moved on, and you didn't.
When I was a teenager, I really enjoyed programming in BASIC, and wrote
a lot of cool little programs on various computers.-a And there is no
doubt that some things then were a lot simpler than writing the same
thing in C.-a But the language and tools are totally unsuitable to work I
do now.
On Tue, 29 Sep 2026 03:02:47 +0200, fir wrote:
Lawrence DrCOOliveiro pisze:
On Mon, 28 Sep 2026 12:42:31 +0200, fir wrote:
its not breaking down, depend how you define breaking down for me
for exampla sinf cosf or pow can be said are breaking don if thay
count to much bits
Your code breaks down because it cannot produce a result which is
perfectly representable within the implementation range.
LOL, im not sure if i understand this above sentence but for me code
is broken if its too slow not when it present exact same graphics
just faster
DoesnrCOt correctness of the code figure into your thinking?
On Mon, 28 Sep 2026 11:45:21 +0100, bart wrote:
If C's obscure 'hypot' function does that job, then great.
Nothing obscure about it. Every language with a decent maths library
has it. To name but a few:
<https://cppreference.com/cpp/numeric/math/hypot> <https://docs.python.org/3/library/math.html#math.hypot> <https://crates.io/crates/core_maths/0.1.1/code/src/lib.rs> <https://github.com/openjdk/jdk/blob/master/src/java.base/share/classes/java/lang/Math.java>
Why? Because <https://en.wikipedia.org/wiki/IEEE_754>. WerCOve already discussed elsewhere why implementing it correctly is somewhat
nontrivial, because the obvious na|>ve implementation is prone to be
... somewhat fragile.
On 29/09/2026 08:45, David Brown wrote:
On 28/09/2026 21:26, bart wrote:
On 28/09/2026 17:49, David Brown wrote:
Lots of programs have little or no use for "print", or they need
something significantly different (showing messages in a dialog box,
printing them to logs or serial ports, etc.
So they /are/ using Print, which still has a variety of uses:
No, they are not.
They are doing /related/ tasks, but not the kind of thing you get from
a "print" statement in BASIC.
Well, BASIC has some other limitations (like no functions). But one of
its purposes was for use from a terminal, and there PRINT is simple to use.
My claim is that all these tasks can be done with Print, and it is
useful to have it as a built-in feature.
If "print" is a fixed, special built-in feature of the language, then
it is not flexible enough to handle different situations.
Such as? Come on, give me a challenge!
My first scripting language has Print with an option 'dev' like this:
-a print #dev, items..
'dev' could refer to the console, an open file, an LPT port, a COM port,
a graphics window, an image, or a string.
Yes, you can do all this a lot more awkwardly via functions, but so
what? I can also do arithmetic via functions:
-a-a a = ADD(b, MUL(c, c));
This can also be a lot more powerful and flexible (eg. you have
references to ADD or MUL and pass them to other functions), and they can implemented in libraries that people can override etc, but again so what?
Most people prefer to have them somewhat less flexible and built-in so
that they can do this:
-a a = b + c * d;
Here the language also takes care of overloads. I happen to think that
Print is as fundamental as this.
-a If instead you make the core language powerful enough to write
"print" as a function (which you can then put in the standard library
for convenience), then people needing different related tools can make
their own.
Oh, and modern C++ provides :
-a-a-a-a-aimport std;
-a-a-a-a-astd::println("i = {}, reUi = {}", i, std::sqrt(i));
So you agree that that "<<" business was an anomaly?
With C11, I can write my own print/println macros so that I can write :
-a-a-a-a-aprintln("i = ", i, ", reUi = ", sqrt(i));
These are all type-safe, by the way.
And with the C++ version, when you make "i" a complex number, it works
the same.-a When you make a square matrix class and make "i" a matrix,
you can write formatters (for the "cout" and "print/println/format"
versions) for printing out your matrices.-a You can write a "sqrt"
function for your matrices.-a (The C11 macros are less flexible - you
need to know the types when the macros are defined.)
OK, that's getting there. But how many advanced, complex (and inefficient-to-compile) language features are needed to arrive at this point?
Yes, BASIC - and your language - are simple for simple programs in
specific use-cases and specific environments.
There are about 250 different Basics now - some will be OK used at scale (eg. the latest VB).
The world moved on, and you didn't.
Well, I used to think that was a problem (and why I retired in 1999).
Now I don't.
I bet a lot of people are wishing the world hadn't moved on so much, and it's barely got going.
On 28/09/2026 21:26, bart wrote:
On 28/09/2026 17:49, David Brown wrote:
On 28/09/2026 17:52, bart wrote:
Yes, I know, most languages prefer to have things in libraries
rather than in the core.
So perhaps it's a good idea?
IS it a good idea? Or is it just what is commonly done and people go
along with it?
Putting functions in standard libraries is commonly done because it is a good idea.
Very occasionally, in some field of thought, someone will come along
with a crazy idea that is different from the way everyone else does
things, and their new way is revolutionary and changes the field
forever.-a [...]
[...]
No, they usually can't. Functions generally take a fixed number of
parameters, and in a typed language, they are also usually a fixed type.
Lots of languages have various methods for doing otherwise.-a Variadic functions, typeless parameters, function overloads, generic functions - these are all common in programming languages.-a They don't need built- ins.-a With greater freedom of use comes less compile-time checking -
that's an inevitable tradeoff to some extent.
[...]
Yes, BASIC - and your language - are simple for simple programs ]...]
When I was a teenager, I really enjoyed programming in BASIC, and wrote
a lot of cool little programs on various computers.-a And there is no
doubt that some things then were a lot simpler than writing the same
thing in C.-a [...]
On Mon, 28 Sep 2026 14:38:09 +0100, bart wrote:
On 28/09/2026 12:56, David Brown wrote:
"hypot" - short for "hypotenuse" but easier to spell - is not
obscure. It is a common name and part of the IEEE 754 standard.-a It
makes a lot of sense for a language that is often used with code
that requires conformance to that standard, to have support for the
standard's required and recommended functions in its standard
library.-a As Lawrence showed, proper implementations of such
functions is not just a matter of copying the pure mathematical
formula.
He showed a way to avoid overflowing (with inputs above 10**19) if
you can't be bothered to use a more appropriate type.
I knew somewhat would try to make this claim, sooner or later. So
hererCOs a long-double version -- I donrCOt think GCC supports any floating-point formats with greater range or precision than this!
/*
Comparison of the na|>ve calculation of a triangle
hypotenuse with the standard-library hypot(3) function.
*/
#include <math.h>
#include <values.h>
#include <stdio.h>
static long double len2(long double x,long double y) { return sqrtl(x*x+y*y);}
static void compare_for
(
long double x
)
{
fprintf
(
stdout,
"for %.7Le: len2 = %.7Le, hypot = %.7Le\n",
x, len2(x, x), hypotl(x, x)
);
} /*compare_for*/
int main(void)
{
compare_for(LDBL_MAX / 2.0);
compare_for(2.0 / LDBL_MAX);
return
0;
} /*main*/
Output:
ldo@theon:c_try> ./naive_hypot_long_double
for 5.9486575e+4931: len2 = inf, hypot = 8.4126721e+4931
for 1.6810516e-4932: len2 = 0.0000000e+00, hypot = 2.3773659e-4932
So the library routine is still capable of producing meaningful results, while the na|>ve implementation still breaks down.
Any more nitpicks?
On 29/09/2026 08:03, Janis Papanagnou wrote:
On 2026-09-28 16:12, David Brown wrote:
You can see the same thing in file systems: in older Windows shells, it
will first look up a file ABC in the current directory. In newer ones
and on Linux, that is not allowed, you have to do ./ABC or .\ABC to >explicitly refer to the local version.
On 29/09/2026 08:08, Lawrence DrCOOliveiro wrote:
On Mon, 28 Sep 2026 14:38:09 +0100, bart wrote:
On 28/09/2026 12:56, David Brown wrote:
"hypot" - short for "hypotenuse" but easier to spell - is not
obscure. It is a common name and part of the IEEE 754 standard.-a It
makes a lot of sense for a language that is often used with code
that requires conformance to that standard, to have support for the
standard's required and recommended functions in its standard
library.-a As Lawrence showed, proper implementations of such
functions is not just a matter of copying the pure mathematical
formula.
He showed a way to avoid overflowing (with inputs above 10**19) if
you can't be bothered to use a more appropriate type.
I knew somewhat would try to make this claim, sooner or later. So
hererCOs a long-double version -- I donrCOt think GCC supports any
floating-point formats with greater range or precision than this!
/*
Comparison of the na|>ve calculation of a triangle
hypotenuse with the standard-library hypot(3) function.
*/
#include <math.h>
#include <values.h>
#include <stdio.h>
static long double len2(long double x,long double y) { return sqrtl(x*x+y*y);}
static void compare_for
(
long double x
)
{
fprintf
(
stdout,
"for %.7Le: len2 = %.7Le, hypot = %.7Le\n",
x, len2(x, x), hypotl(x, x)
);
} /*compare_for*/
int main(void)
{
compare_for(LDBL_MAX / 2.0);
compare_for(2.0 / LDBL_MAX);
return
0;
} /*main*/
Output:
ldo@theon:c_try> ./naive_hypot_long_double
for 5.9486575e+4931: len2 = inf, hypot = 8.4126721e+4931
for 1.6810516e-4932: len2 = 0.0000000e+00, hypot = 2.3773659e-4932
So the library routine is still capable of producing meaningful results,
while the na|>ve implementation still breaks down.
Any more nitpicks?
Yes: you're being incredibly pedantic and picky for no reason other than
to be argumentative and superior.
These big numbers are ridiculous. If you want to play this game, then
I've just got my bignum library to work out the hypotenuse given these
two sides:
A = 3e1'000'000'000'000'000'000
B = 4e1'000'000'000'000'000'000
(The is, 3 and 4 each followed by a million million million zeros.)
bart <bc@freeuk.com> writes:
On 29/09/2026 08:08, Lawrence DrCOOliveiro wrote:
On Mon, 28 Sep 2026 14:38:09 +0100, bart wrote:
On 28/09/2026 12:56, David Brown wrote:
"hypot" - short for "hypotenuse" but easier to spell - is not
obscure. It is a common name and part of the IEEE 754 standard.-a It >>>>> makes a lot of sense for a language that is often used with code
that requires conformance to that standard, to have support for the
standard's required and recommended functions in its standard
library.-a As Lawrence showed, proper implementations of such
functions is not just a matter of copying the pure mathematical
formula.
He showed a way to avoid overflowing (with inputs above 10**19) if
you can't be bothered to use a more appropriate type.
I knew somewhat would try to make this claim, sooner or later. So
hererCOs a long-double version -- I donrCOt think GCC supports any
floating-point formats with greater range or precision than this!
/*
Comparison of the na|>ve calculation of a triangle
hypotenuse with the standard-library hypot(3) function.
*/
#include <math.h>
#include <values.h>
#include <stdio.h>
static long double len2(long double x,long double y) { return sqrtl(x*x+y*y);}
static void compare_for
(
long double x
)
{
fprintf
(
stdout,
"for %.7Le: len2 = %.7Le, hypot = %.7Le\n",
x, len2(x, x), hypotl(x, x)
);
} /*compare_for*/
int main(void)
{
compare_for(LDBL_MAX / 2.0);
compare_for(2.0 / LDBL_MAX);
return
0;
} /*main*/
Output:
ldo@theon:c_try> ./naive_hypot_long_double
for 5.9486575e+4931: len2 = inf, hypot = 8.4126721e+4931
for 1.6810516e-4932: len2 = 0.0000000e+00, hypot = 2.3773659e-4932 >>>
So the library routine is still capable of producing meaningful results, >>> while the na|>ve implementation still breaks down.
Any more nitpicks?
Yes: you're being incredibly pedantic and picky for no reason other than
to be argumentative and superior.
These big numbers are ridiculous. If you want to play this game, then
I've just got my bignum library to work out the hypotenuse given these
two sides:
A = 3e1'000'000'000'000'000'000
B = 4e1'000'000'000'000'000'000
(The is, 3 and 4 each followed by a million million million zeros.)
The nice thing about computing the hypotenuse, is that you
can simply scale the values of A&B down before computing C
to get the correct answer.
I believe many implementations already do that internally
to avoid over/underflow cases.
Lawrence DrCOOliveiro pisze:
On Tue, 29 Sep 2026 03:02:47 +0200, fir wrote:
Lawrence DrCOOliveiro pisze:
On Mon, 28 Sep 2026 12:42:31 +0200, fir wrote:
its not breaking down, depend how you define breaking down for me
for exampla sinf cosf or pow can be said are breaking don if thay
count to much bits
Your code breaks down because it cannot produce a result which is
perfectly representable within the implementation range.
LOL, im not sure if i understand this above sentence but for me code
is broken if its too slow not when it present exact same graphics
just faster
DoesnrCOt correctness of the code figure into your thinking?
what correctnes?
On 29/09/2026 13:54, bart wrote:
My claim is that all these tasks can be done with Print, and it is
useful to have it as a built-in feature.
Built-in print is great for "Hello, world!" level programs, and a bit
beyond that - but it quickly fails for larger needs.
And yet some sort of friendlier Print feature is generally provided by a language, on top of a set of I/O routines.Such as? Come on, give me a challenge!
I gave some already.
Other things include formatted output to log files, formatting of
different types (not just built-in ones), saving logs in eeprom, using different languages for the fixed parts of the strings.-a Basically, anything that the toolchain writer and/or language designer didn't think
of in the first place.
formatting of different types (not just built-in ones)
, using
different languages for the fixed parts of the strings.
My first scripting language has Print with an option 'dev' like this:
-a-a print #dev, items..
'dev' could refer to the console, an open file, an LPT port, a COM
port, a graphics window, an image, or a string.
That's only the things /you/ thought about at the time.-a It doesn't
cover what other people think of later.
Here the language also takes care of overloads. I happen to think that
Print is as fundamental as this.
In your limited bubble, that's maybe fine.-a I'm not saying it is a bad choice for /your/ language - it's a bad choice for most scalable general-purpose languages.
And with the C++ version, when you make "i" a complex number, it
OK, that's getting there. But how many advanced, complex (and
inefficient-to-compile) language features are needed to arrive at this
point?
It needs _Generic, and variadic macros.
On 29/09/2026 14:56, David Brown wrote:
On 29/09/2026 13:54, bart wrote:
My claim is that all these tasks can be done with Print, and it is
useful to have it as a built-in feature.
Built-in print is great for "Hello, world!" level programs, and a bit
beyond that - but it quickly fails for larger needs.
That is nonsense.
And yet some sort of friendlier Print feature is generally provided by a language, on top of a set of I/O routines.Such as? Come on, give me a challenge!
I gave some already.
Other things include formatted output to log files, formatting of
different types (not just built-in ones), saving logs in eeprom, using
different languages for the fixed parts of the strings.-a Basically,
anything that the toolchain writer and/or language designer didn't
think of in the first place.
For example Lua has print() as well as io.write. I think Python also has 'io', and 'sys', and 'os'.
So they recognise that providing the simpler Print feature as well adds something.
So do I! I just go further and make it built-in to make even more
convenient and with nicer syntax.
What other destinations can you think of? Bear in mind that in Linux,
most such things seems to be part of the file system, and that is
already covered.
And with the C++ version, when you make "i" a complex number, it
OK, that's getting there. But how many advanced, complex (and
inefficient-to-compile) language features are needed to arrive at
this point?
It needs _Generic, and variadic macros.
I was thinking of C++. But _Generic and variadic macros in C (add them
to variadic functions) I would class as a hack.
On 29/09/2026 19:15, bart wrote:
There is /nothing/ wrong with making a simple "print" function.
There is a lot wrong with making it a special language feature, instead
of a normal function (or other language construct - object, template, >generic, whatever) that is defined in the standard library, using the >language itself.
If you can't make a suitable "print" facility that way, your language is >weak and limited. It might be okay for some purposes, but not for
general usage. (And if you /can/ make it part of the standard library,
you /should/ make it part of the standard library - even if your
language then imports that library by default.)
What other destinations can you think of? Bear in mind that in Linux,
most such things seems to be part of the file system, and that is
already covered.
Not everything you might want to do in Linux is part of the file system
- far from it.
David Brown <david.brown@hesbynett.no> writes:
On 29/09/2026 19:15, bart wrote:<snip>
There is /nothing/ wrong with making a simple "print" function.
There is a lot wrong with making it a special language feature, instead
of a normal function (or other language construct - object, template, >>generic, whatever) that is defined in the standard library, using the >>language itself.
If you can't make a suitable "print" facility that way, your language is >>weak and limited. It might be okay for some purposes, but not for
general usage. (And if you /can/ make it part of the standard library, >>you /should/ make it part of the standard library - even if your
language then imports that library by default.)
Agreed.
What other destinations can you think of? Bear in mind that in Linux,
most such things seems to be part of the file system, and that is
already covered.
Not everything you might want to do in Linux is part of the file system
- far from it.
Some examples often used in server code:
- The host log framework (e.g. syslog) is a common destination
- A network TCP/UDP port
- A custom multiplexer to send the output to multiple destinations
There is a lot to be said for the terseness of *printf formatting, >particularly with compilers that check the type correctness of the printf >varargs list.
On 29/09/2026 07:38, Lawrence DrCOOliveiro wrote:
Why? Because <https://en.wikipedia.org/wiki/IEEE_754>. WerCOve
already discussed elsewhere why implementing it correctly is
somewhat nontrivial, because the obvious na|>ve implementation is
prone to be ... somewhat fragile.
What exactly is incorrect about the naive method? That it stops
working at a lower magnitude than hypot()?
hypot() will also stop working at a high enough magnitude; so
according to you, that is also incorrect?
Lawrence DrCOOliveiro pisze:
DoesnrCOt correctness of the code figure into your thinking?
what correctnes?
On Tue, 29 Sep 2026 14:36:34 +0100, bart wrote:
On 29/09/2026 07:38, Lawrence DrCOOliveiro wrote:
Why? Because <https://en.wikipedia.org/wiki/IEEE_754>. WerCOve
already discussed elsewhere why implementing it correctly is
somewhat nontrivial, because the obvious na|>ve implementation is
prone to be ... somewhat fragile.
What exactly is incorrect about the naive method? That it stops
working at a lower magnitude than hypot()?
hypot() will also stop working at a high enough magnitude; so
according to you, that is also incorrect?
Feel free to demonstrate the point at which the library function stops working.
On Tue, 29 Sep 2026 15:02:43 +0100, bart wrote:
On 29/09/2026 08:08, Lawrence DrCOOliveiro wrote:
So the library routine is still capable of producing meaningful
results, while the na|>ve implementation still breaks down.
Any more nitpicks?
Yes: you're being incredibly pedantic and picky for no reason other
than to be argumentative and superior.
YourCOre the one failing to appreciate the point, that it takes smarts
to design proper numeric algorithms that work within the practical *efficient* limits of computer arithmetic.
These big numbers are ridiculous. If you want to play this game,
then I've just got my bignum library ...
So those numbers are rCLridiculousrCY, yet your only way to counter
them is to be more rCLridiculousrCY?
On 28/09/2026 16:15, James Kuyper wrote:
On 28/09/2026 12:45, bart wrote:
On 28/09/2026 09:25, David Brown wrote:sqrt(x*x +
It also has a "hypot" function that returns, approximately,
idea aty*y).So why was hypot() ever added? Somebody thought it was a good
one time to add a such a one-line function?It was part of the major expansion to the <math.h> library that occurred
in C99. It was added because of the "without undue overflow or
underflow." requirement. Achieving that result makes it a bit more
complicated than just a one-line function. Also, even most people who
are well aware of that problem are unaware of how best to avoid it. See
<https://en.wikipedia.org/wiki/Pythagorean_addition#Calculation_order>
for more details.
I think most will be vaguely aware of such problems, but usually they
don't matter because they only happen with unlikely, extreme inputs.
One simple way around in this case, is to use 64-bit floats for the calculation, even if the inputs are 32-bits.
That might kick the can down the road enough that overflows will
virtually never occur (eg. it might need inputs over 10**150, and that I think is impossible if inputs were promoted from 32 bits).
I'm less familiar with underflows, ie. values smaller than around
10e-308, but I think the same applies.
The technique demonstrated in LD'O's post I think buys you one more bit
of exponent range (although the article you linked to seems to suggest
you can go beyond that with extra scaling).
When such things used to be important to me, I tried to avoid doing the square-root part anyway, for example I would compare one set of x*x +
y*y with another. In that case it is necessary to express the full magnitude.
If the values represent length, then another approach would be a choice
of units. I liked using mm, but if expressed in metres, then I think
that's another 10 extra bits of binary exponent range, unless the issue
is underflow, then it might make it worse!
In any case, it was NEVER a problem (well, until someone zoomed in
enough within my CAD product that they hit the limitations of the
floating point representation. Things would get jerky).
On 29/09/2026 23:49, Lawrence DrCOOliveiro wrote:
On Tue, 29 Sep 2026 14:36:34 +0100, bart wrote:
On 29/09/2026 07:38, Lawrence DrCOOliveiro wrote:
Why? Because <https://en.wikipedia.org/wiki/IEEE_754>. WerCOve
already discussed elsewhere why implementing it correctly is
somewhat nontrivial, because the obvious na|>ve implementation is
prone to be ... somewhat fragile.
What exactly is incorrect about the naive method? That it stops
working at a lower magnitude than hypot()?
hypot() will also stop working at a high enough magnitude; so
according to you, that is also incorrect?
Feel free to demonstrate the point at which the library function stops
working.
Take your example using hypotl() and remove the '/ 2.0'. (Then the
answer needs to be about 1.4142 * LDBL_MAX.)
Or maybe your triangle has a, b sides bigger than LDBL_MAX, or an
earlier calculation has already overflowed.
On 29/09/2026 19:15, bart wrote:
On 29/09/2026 14:56, David Brown wrote:
On 29/09/2026 13:54, bart wrote:
My claim is that all these tasks can be done with Print, and it is
useful to have it as a built-in feature.
Built-in print is great for "Hello, world!" level programs, and a bit
beyond that - but it quickly fails for larger needs.
That is nonsense.
And yet some sort of friendlier Print feature is generally provided bySuch as? Come on, give me a challenge!
I gave some already.
Other things include formatted output to log files, formatting of
different types (not just built-in ones), saving logs in eeprom,
using different languages for the fixed parts of the strings.
Basically, anything that the toolchain writer and/or language
designer didn't think of in the first place.
a language, on top of a set of I/O routines.
For example Lua has print() as well as io.write. I think Python also
has 'io', and 'sys', and 'os'.
So they recognise that providing the simpler Print feature as well
adds something.
So do I! I just go further and make it built-in to make even more
convenient and with nicer syntax.
There is /nothing/ wrong with making a simple "print" function.
There is a lot wrong with making it a special language feature, instead
of a normal function (or other language construct - object, template, generic, whatever) that is defined in the standard library, using the language itself.
If you can't make a suitable "print" facility that way, your language is weak and limited.
-a It might be okay for some purposes, but not for
general usage.-a (And if you /can/ make it part of the standard library,
you /should/ make it part of the standard library - even if your
language then imports that library by default.)
What other destinations can you think of? Bear in mind that in Linux,
most such things seems to be part of the file system, and that is
already covered.
Not everything you might want to do in Linux is part of the file system
- far from it.-a And not all programs run on Windows or Linux.
/I/ am not the one implicitly claiming to know all possible
destinations, uses or combinations so that it's fine to nail it into a language special feature.
You class everything that is not part of your beloved language as a
"hack".
-a You'll forgive me for not taking your opinion or
classifications seriously.
There is a lot to be said for the terseness of *printf formatting,
particularly with compilers that check the type correctness of the printf
varargs list.
I'd say the real winning example is `snprintf`, where one can
format directly into a character array. It is difficult to
understate the utility this; but if `print` were built into the
language, you'd lose it, unless you also had a `sprint` builtin.
On 29/09/2026 08:08, Lawrence DrCOOliveiro wrote:
So the library routine is still capable of producing meaningful
results, while the na|>ve implementation still breaks down.
Any more nitpicks?
Yes: you're being incredibly pedantic and picky for no reason other
than to be argumentative and superior.
These big numbers are ridiculous. If you want to play this game,
then I've just got my bignum library ...
So tell me again what is the upper limit when using hypotl()?
On Tue, 29 Sep 2026 14:20:23 +0200, fir wrote:
Lawrence DrCOOliveiro pisze:
DoesnrCOt correctness of the code figure into your thinking?
what correctnes?
We have here a standard library function, already implemented, that
provides better-quality results than your somewhat simplistic attempt.
Why should we bother with your code at all?
On 29/09/2026 23:49, Lawrence DrCOOliveiro wrote:
On Tue, 29 Sep 2026 14:36:34 +0100, bart wrote:
On 29/09/2026 07:38, Lawrence DrCOOliveiro wrote:
Why? Because <https://en.wikipedia.org/wiki/IEEE_754>. WerCOve
already discussed elsewhere why implementing it correctly is
somewhat nontrivial, because the obvious na|>ve implementation is
prone to be ... somewhat fragile.
What exactly is incorrect about the naive method? That it stops
working at a lower magnitude than hypot()?
hypot() will also stop working at a high enough magnitude; so
according to you, that is also incorrect?
Feel free to demonstrate the point at which the library function
stops working.
Take your example using hypotl() and remove the '/ 2.0'. (Then the
answer needs to be about 1.4142 * LDBL_MAX.)
Or maybe your triangle has a, b sides bigger than LDBL_MAX, or an
earlier calculation has already overflowed.
I always find it odd when people strive to keep a core language to a
few dozen keywords to reduce 'cognitive load', but are fine with
needing to use a library that exports a thousand identifiers, all in
the same namespace.
Lawrence DrCOOliveiro pisze:
why you ask me all that nonsense quiestions?
On Tue, 29 Sep 2026 14:20:23 +0200, fir wrote:
Lawrence DrCOOliveiro pisze:
DoesnrCOt correctness of the code figure into your thinking?
what correctnes?
We have here a standard library function, already implemented, that
provides better-quality results than your somewhat simplistic
attempt. Why should we bother with your code at all?
What exactly is incorrect about the naive method? That it stops
working at a lower magnitude than hypot()?
hypot() will also stop working at a high enough magnitude; so
according to you, that is also incorrect?
On 29/09/2026 08:03, Janis Papanagnou wrote:
On 2026-09-28 16:12, David Brown wrote:
On 28/09/2026 15:38, bart wrote:
- Always available without needing those annoying #includes (and is
-a-a it math.h or float.h? I can never remember).
Other C programmers manage that without effort.
I seem to recall that on his platform there's no man-pages.
(Or that he, maybe, dislikes looking into the documentation?
Sometime he gives that impression.)
(Funny how shadowing or overriding is usually perceived as bad,
until you want to shadow something like 'sin' then it's a must-have!)
Since when is shadowing (or "overriding" in its various forms)
"perceived as bad"? - I've always seen it as a useful feature.
And never heard anyone complaining about it.
It can be useful, it can also introduce subtle bugs if done inadvertently.
For example you are using a global name inside a function but also
happen to define a local of that name, so the global one is hidden.
Of you forget to define a local variable and accidentally overwrite, or
just use, the global version.
You can see the same thing in file systems: [...]
On 28/09/2026 07:45, Lawrence DrCOOliveiro wrote:
[...]
You mean a reasonable looking result for quite unreasonable inputs?
Because it's common to work with triangles whose sides are 170141173319264429905852091742258462720 units long!
The simple function squares its arguments, so the upper limit for first
test would be sqrt(FLT_MAX)/2.0 (since it also adds the two squares).
In that case both versions give the same result. For second test, where
you are working with triangles with non-zero sides smaller than
Plancks's Constant, I haven't dealt with.
Sure, the official version can deal with a wider range, but try it with FLT_MAX and both fail.
In practice, for inputs this huge, it makes sense to switch to 'double'.
Then it will also work better for arbitrary expressions that happen to
use squares and other powers.
So I think this overhead for 'hypot' is pointless, given that, in
general, for any 'x' or type float, then x*x /anywhere in a program/
will overflow when x is bigger than sqrt(FLT_MAX).
On 29/09/2026 23:58, Lawrence DrCOOliveiro wrote:
On Tue, 29 Sep 2026 15:02:43 +0100, bart wrote:
On 29/09/2026 08:08, Lawrence DrCOOliveiro wrote:
So the library routine is still capable of producing meaningful
results, while the na|>ve implementation still breaks down.
Any more nitpicks?
Yes: you're being incredibly pedantic and picky for no reason
other than to be argumentative and superior.
YourCOre the one failing to appreciate the point, that it takes
smarts to design proper numeric algorithms that work within the
practical *efficient* limits of computer arithmetic.
OK, so give me a 'smart' square(x) routine where x can go all the
way to the MAX value.
These big numbers are ridiculous. If you want to play this game,
then I've just got my bignum library ...
So those numbers are rCLridiculousrCY, yet your only way to counter
them is to be more rCLridiculousrCY?
Yes; they're all ridiculous. You're criticising some line-length
routine because it goes wrong when deltas reach 10**19 (f32), or
some 10**153 (f64) or 10**4000 or whatever (f80).
Mine I think will go wrong at 10**5000000000000000000 or something.
But IT DOESN'T MATTER.
You're also looking at this wrong way: the author of len2() (ie. the
'naive' version) wrote it with his applications in mind, where its
spec was perfectly adequate for the job.
As the author of a library function, you don't know to what applications
it will be used for, so you don't make assumptions.
Also you're not going to get paid much for one line of code so you
might as well go to town.
In article <WvUuS.292$M0U7.280@fx10.iad>,
Scott Lurndal <slp53@pacbell.net> wrote:
There is a lot to be said for the terseness of *printf formatting,
particularly with compilers that check the type correctness of the printf
varargs list.
I'd say the real winning example is `snprintf`, where one can
format directly into a character array. It is difficult to
understate the utility this; but if `print` were built into the
language, you'd lose it, unless you also had a `sprint` builtin.
On 29/09/2026 19:24, David Brown wrote:
On 29/09/2026 19:15, bart wrote:
On 29/09/2026 14:56, David Brown wrote:
On 29/09/2026 13:54, bart wrote:
My claim is that all these tasks can be done with Print, and it is
useful to have it as a built-in feature.
Built-in print is great for "Hello, world!" level programs, and a
bit beyond that - but it quickly fails for larger needs.
That is nonsense.
And yet some sort of friendlier Print feature is generally providedSuch as? Come on, give me a challenge!
I gave some already.
Other things include formatted output to log files, formatting of
different types (not just built-in ones), saving logs in eeprom,
using different languages for the fixed parts of the strings.
Basically, anything that the toolchain writer and/or language
designer didn't think of in the first place.
by a language, on top of a set of I/O routines.
For example Lua has print() as well as io.write. I think Python also
has 'io', and 'sys', and 'os'.
So they recognise that providing the simpler Print feature as well
adds something.
So do I! I just go further and make it built-in to make even more
convenient and with nicer syntax.
There is /nothing/ wrong with making a simple "print" function.
There is a lot wrong with making it a special language feature,
instead of a normal function (or other language construct - object,
template, generic, whatever) that is defined in the standard library,
using the language itself.
If you can't make a suitable "print" facility that way, your language
is weak and limited.
That's your opinion. You like such features, you like DIY languages, and
you like lots of moving pieces. In general, you like complexity.
You class everything that is not part of your beloved language as a
"hack".
In the case of C, then I've seen enough system header files to
justifiably call them hacks. In fact I'll go further and call them ugly hacks. That's how C seems to work.
-a You'll forgive me for not taking your opinion or classifications
seriously.
That's fine. I don't take your dismissal of built-in Print (and Read) seriously either.
Interesting. - As teenager I also wrote lots of fancy BASIC programs.As a kid, I used to love making BASIC programs that would create other programs that could be run from EXEC in prodos. Fun times.
But as soon as Pascal was available that was a lot more fun (for me),
and a bit step forward! With "C" things degraded, though. (Again, for
me.)
On Wed, 30 Sep 2026 02:57:09 +0200, fir wrote:
Lawrence DrCOOliveiro pisze:
why you ask me all that nonsense quiestions?
On Tue, 29 Sep 2026 14:20:23 +0200, fir wrote:
Lawrence DrCOOliveiro pisze:
DoesnrCOt correctness of the code figure into your thinking?
what correctnes?
We have here a standard library function, already implemented, that
provides better-quality results than your somewhat simplistic
attempt. Why should we bother with your code at all?
ThatrCOs a Donald-Trump-type answer -- attack the questioner as an
attempt to deflect from the issue at hand.
Code is not something you write just because it feels good to type in
all those cryptic symbols. ItrCOs got to do something useful, and furthermore, do it correctly.
On Tue, 29 Sep 2026 14:36:34 +0100, bart wrote:
What exactly is incorrect about the naive method? That it stops
working at a lower magnitude than hypot()?
It stops working at a MUCH lower magnitude. The naive implementation overflows if either argument > sqrt(DBL_MAX).
until the exact answer is > DBL_MAX. hypot() also avoids unnecessary
loss of precision when the arguments are very small, though I'm not as
sure how to characterize that aspect of it.
hypot() will also stop working at a high enough magnitude; so
according to you, that is also incorrect?
It basically won't stop working until the correct answer is no longer representable.
On 2026-09-29 12:11, bart wrote:I do without block-scopes.
Would you prefer a language without hierarchical blocks, scopes,
and shadowing?! (rhetoric)
Of you forget to define a local variable and accidentally overwrite,
or just use, the global version.
This is obviously your personal problem;
No, please do explain how it is different.You can see the same thing in file systems: [...]
That is something completely different; you are shifting the goalpost!
(I won't explain you the PATH concept here, or why it is very useful.
And some things have already been explained elsethread by Scott.)
On 30/09/2026 03:09, James Kuyper wrote:
On Tue, 29 Sep 2026 14:36:34 +0100, bart wrote:
What exactly is incorrect about the naive method? That it stops
working at a lower magnitude than hypot()?
It stops working at a MUCH lower magnitude. The naive implementation
overflows if either argument > sqrt(DBL_MAX).
Well, so what? You can say that about lots of different expressions and functions!
If you're the library implementer of something called 'hypot' and don't
know the range of likely inputs, then you try to make it as bomb-proof
as possible.
If you are writing your own for any reason (and here it was to determine
the length of a vector), then it only has to work for the likely values within in your application.
It is a non-issue as far as I'm concerned.
This is why I don't see the obsession with 'hypot'.
On 29/09/2026 23:37, Dan Cross wrote:
In article <WvUuS.292$M0U7.280@fx10.iad>,
Scott Lurndal <slp53@pacbell.net> wrote:
There is a lot to be said for the terseness of *printf formatting,
particularly with compilers that check the type correctness of the
printf varargs list.
I'd say the real winning example is `snprintf`, where one can
format directly into a character array. It is difficult to
understate the utility this; but if `print` were built into the
language, you'd lose it, unless you also had a `sprint` builtin.
snprintf is the printf family member I use most, and occasionally
vsnprintf.
Other people will likely make heavy use of fprintf too.
And I often use the return value of printf (or rather, snprintf) to
see if I've cut the output short.
So a special language feature for "print" would have to have either
multiple additional special builtins, or a ridiculously complicated
one that supports everything in one statement type that differs from
all normal functions in the language.
And that's just the start. People like to write their own functions "log_printf", or "debug_printf", with varieties of additional
features that suit their needs - while still retaining the
printf-style formatting and the compiler checks of argument types and
number. Extended standard libraries and OS-specific libraries go
further, such as having locking systems to avoid mixing output from
different threads, or cut-down versions without floating point for
small microcontrollers. A quick glance at newlib's documentation
shows 34 functions with "printf" in the name. Most people only use a
few of them, but all of them are useful to someone.
On 9/29/2026 7:01 AM, Janis Papanagnou wrote:
[...]As a kid, I used to love making BASIC programs that would create other programs that could be run from EXEC in prodos. Fun times.
[...]
Here is a more self-contained version of my generator. It asks you how
many vertices to enter. Builds CTTEST.BAS, then you can just EXEC
CTTEST.BAS to run it. Here is my code. Just for fun. The generated code draws a bunch of polys using the table LT. Btw, can you get it to work
on your end?
[ snip BASIC program ]
On 2026-09-28 16:12, David Brown wrote:There exist coding standard/style guides that prohibit it. Not just
On 28/09/2026 15:38, bart wrote:
- Always available without needing those annoying #includes (and is
aa it math.h or float.h? I can never remember).
Other C programmers manage that without effort.
I seem to recall that on his platform there's no man-pages.
(Or that he, maybe, dislikes looking into the documentation?
Sometime he gives that impression.)
(Funny how shadowing or overriding is usually perceived as bad,
until you want to shadow something like 'sin' then it's a
must-have!)
Since when is shadowing (or "overriding" in its various forms)
"perceived as bad"?
- I've always seen it as a useful feature.It just means that you didn't get out much.
And never heard anyone complaining about it.
In decades I alsoI had seen one yesterday. This particular time it was in context of C++
don't recall that subtile (or obvious) errors had been reported
because of that.
(Are you, yet again, just making things up for
the argument or have you any different observations from your
personal coding practice?)
Janis
On 29/09/2026 23:58, Lawrence DrCOOliveiro wrote:
On Tue, 29 Sep 2026 15:02:43 +0100, bart wrote:
On 29/09/2026 08:08, Lawrence DrCOOliveiro wrote:
So the library routine is still capable of producing meaningful
results, while the na|>ve implementation still breaks down.
Any more nitpicks?
Yes: you're being incredibly pedantic and picky for no reason other
than to be argumentative and superior.
YourCOre the one failing to appreciate the point, that it takes smarts
to design proper numeric algorithms that work within the practical *efficient* limits of computer arithmetic.
OK, so give me a 'smart' square(x) routine where x can go all the way
to the MAX value.
On Wed, 30 Sep 2026 00:13:23 +0100
bart <bc@freeuk.com> wrote:
On 29/09/2026 23:58, Lawrence DrCOOliveiro wrote:
On Tue, 29 Sep 2026 15:02:43 +0100, bart wrote:
On 29/09/2026 08:08, Lawrence DrCOOliveiro wrote:
So the library routine is still capable of producing meaningful
results, while the na|>ve implementation still breaks down.
Any more nitpicks?
Yes: you're being incredibly pedantic and picky for no reason
other than to be argumentative and superior.
YourCOre the one failing to appreciate the point, that it takes
smarts to design proper numeric algorithms that work within the
practical *efficient* limits of computer arithmetic.
OK, so give me a 'smart' square(x) routine where x can go all the
way to the MAX value.
Come on. You are certainly good enough programmer to figure it out
yourself. It should not take more than few minutes.
If you want hint, it is in the followup.
On Tue, 29 Sep 2026 15:02:43 +0100, bart wrote:Pay attention that GNU C is a compiler + comiler support library
On 29/09/2026 08:08, Lawrence DrCOOliveiro wrote:
So the library routine is still capable of producing meaningful
results, while the na|>ve implementation still breaks down.
Any more nitpicks?
Yes: you're being incredibly pedantic and picky for no reason other
than to be argumentative and superior.
YourCOre the one failing to appreciate the point, that it takes smarts
to design proper numeric algorithms that work within the practical *efficient* limits of computer arithmetic.
These big numbers are ridiculous. If you want to play this game,
then I've just got my bignum library ...
So those numbers are rCLridiculousrCY, yet your only way to counter
them is to be more rCLridiculousrCY?
Remember, the GNU C routine is capable of giving meaningful results
over the entire representable range of the real type, without having
to take the lazy (and slow) way out of resorting to higher-precision/magnitude arithmetic.
On Tue, 29 Sep 2026 09:03:37 +0200
Janis Papanagnou <janis_papanagnou+ng@hotmail.com> wrote:
On 2026-09-28 16:12, David Brown wrote:
On 28/09/2026 15:38, bart wrote:
- Always available without needing those annoying #includes (and is
-a-a it math.h or float.h? I can never remember).
Other C programmers manage that without effort.
I seem to recall that on his platform there's no man-pages.
(Or that he, maybe, dislikes looking into the documentation?
Sometime he gives that impression.)
(Funny how shadowing or overriding is usually perceived as bad,
until you want to shadow something like 'sin' then it's a
must-have!)
Since when is shadowing (or "overriding" in its various forms)
"perceived as bad"?
There exist coding standard/style guides that prohibit it. Not just
MISRA, which I hold at low regard, but some well-thought guids too.
There are popular compilers that warn about it.
- I've always seen it as a useful feature.
And never heard anyone complaining about it.
It just means that you didn't get out much.
Lawrence DrCOOliveiro pisze:
On Wed, 30 Sep 2026 02:57:09 +0200, fir wrote:
Lawrence DrCOOliveiro pisze:
why you ask me all that nonsense quiestions?
On Tue, 29 Sep 2026 14:20:23 +0200, fir wrote:
Lawrence DrCOOliveiro pisze:
DoesnrCOt correctness of the code figure into your thinking?
what correctnes?
We have here a standard library function, already implemented, that
provides better-quality results than your somewhat simplistic
attempt. Why should we bother with your code at all?
ThatrCOs a Donald-Trump-type answer -- attack the questioner as an
attempt to deflect from the issue at hand.
Code is not something you write just because it feels good to type in
all those cryptic symbols. ItrCOs got to do something useful, and
furthermore, do it correctly.
why you ask me idiotic questions and not answer mine?
On 30/09/2026 06:02, Janis Papanagnou wrote:
On 2026-09-29 12:11, bart wrote:
Would you prefer a language without hierarchical blocks, scopes,
and shadowing?! (rhetoric)
I do without block-scopes.
Of you forget to define a local variable and accidentally overwrite,
or just use, the global version.
This is obviously your personal problem;
Fuck you and your personal vendetta.
It is a problem for ANYBODY; people make mistakes: they forget, they inadvertently comment out, they make typos, they choose a local that is
also a needed global.
Those errors are generally not reported so long as the program is still valid.
Of course, in your world everyone except me is perfect: you never make
any such errors!
I'm not arguing against shadowing, just pointing out some issues.
Here's one of many internet quotes:
"Variable shadowing happens when a local variable or parameter uses the
same name as a variable in an outer scope. This causes the inner
variable to hide (rCLshadowrCY) the outer one, leading to bugs that can break your code in subtle ways rCo costing companies millions."
And another:
"Variable shadowing itself is not inherently bad. The trouble comes when
it happens unintentionally,"
So again, fuck you for your CONSTANT FUCKING PERSONAL INSULTS.
No, please do explain how it is different.You can see the same thing in file systems: [...]
That is something completely different; you are shifting the goalpost!
(I won't explain you the PATH concept here, or why it is very useful.
And some things have already been explained elsethread by Scott.)
To me it looks the same: a compiler uses some name-resolution scheme
that works across a hierarchy, so does a file system.
A file system may choose not to automatically search in the local
context first: what are the reasons, and could those reasons apply to
scoped variables too?
On Wed, 30 Sep 2026 14:15:45 +0300
Michael S <already5chosen@yahoo.com> wrote:
On Wed, 30 Sep 2026 00:13:23 +0100
bart <bc@freeuk.com> wrote:
On 29/09/2026 23:58, Lawrence DrCOOliveiro wrote:
On Tue, 29 Sep 2026 15:02:43 +0100, bart wrote:
On 29/09/2026 08:08, Lawrence DrCOOliveiro wrote:
So the library routine is still capable of producing meaningful
results, while the na|>ve implementation still breaks down.
Any more nitpicks?
Yes: you're being incredibly pedantic and picky for no reason
other than to be argumentative and superior.
YourCOre the one failing to appreciate the point, that it takes
smarts to design proper numeric algorithms that work within the
practical *efficient* limits of computer arithmetic.
OK, so give me a 'smart' square(x) routine where x can go all the
way to the MAX value.
Come on. You are certainly good enough programmer to figure it out
yourself. It should not take more than few minutes.
If you want hint, it is in the followup.
frexp
On Tue, 29 Sep 2026 09:03:37 +0200
Janis Papanagnou <janis_papanagnou+ng@hotmail.com> wrote:
On 2026-09-28 16:12, David Brown wrote:
On 28/09/2026 15:38, bart wrote:
- Always available without needing those annoying #includes (and is
-a-a it math.h or float.h? I can never remember).
Other C programmers manage that without effort.
I seem to recall that on his platform there's no man-pages.
(Or that he, maybe, dislikes looking into the documentation?
Sometime he gives that impression.)
(Funny how shadowing or overriding is usually perceived as bad,
until you want to shadow something like 'sin' then it's a
must-have!)
Since when is shadowing (or "overriding" in its various forms)
"perceived as bad"?
There exist coding standard/style guides that prohibit it. Not just
MISRA, which I hold at low regard, but some well-thought guids too.
There are popular compilers that warn about it.
- I've always seen it as a useful feature.
And never heard anyone complaining about it.
It just means that you didn't get out much.
In decades I also
don't recall that subtile (or obvious) errors had been reported
because of that.
I had seen one yesterday. This particular time it was in context of C++ member variables and of inheritance. But I certainly had seen similar
bugs in C. Even made them myself.
I stated elsewhere that I often worked with 'x*x + y*y' without
bothering with the square root, so here that cleverness won't help.
You mean when I point out that you are hallucinating, presenting your personal opinions as facts,
To me it looks the same: a compiler uses some name-resolution scheme
that works across a hierarchy, so does a file system.
But they are factually completely different.
(I don't believe you will be able to change your habit or even become enlightened, but... - well, we'll see.)
On 30/09/2026 12:18, Michael S wrote:I don't see exactly what it is that you don't see. Remember: we are
On Wed, 30 Sep 2026 14:15:45 +0300
Michael S <already5chosen@yahoo.com> wrote:
On Wed, 30 Sep 2026 00:13:23 +0100
bart <bc@freeuk.com> wrote:
On 29/09/2026 23:58, Lawrence DrCOOliveiro wrote:
On Tue, 29 Sep 2026 15:02:43 +0100, bart wrote:
On 29/09/2026 08:08, Lawrence DrCOOliveiro wrote:
So the library routine is still capable of producing meaningful
results, while the na|>ve implementation still breaks down.
Any more nitpicks?
Yes: you're being incredibly pedantic and picky for no reason
other than to be argumentative and superior.
YourCOre the one failing to appreciate the point, that it takes
smarts to design proper numeric algorithms that work within the
practical *efficient* limits of computer arithmetic.
OK, so give me a 'smart' square(x) routine where x can go all the
way to the MAX value.
Come on. You are certainly good enough programmer to figure it out
yourself. It should not take more than few minutes.
If you want hint, it is in the followup.
frexp
I don't see how that helps.
My made-up square function has a
signature like (T)->T, and T will have a particular T.MAX value.
So, what is the maximum input that can yield a result that can still
be represented within a type T? Presumably it is +/- sqrt(T.MAX).
The broader point is that pretty much any arithmetic involving floats
can overflow the range if the magnitudes are large enough (or small
enough with divide etc).
You can still work with this, since the ranges of f32 and especially
f64 are generous enough. (And if using the x87 FPU, intermediates use
f80.)
In the very, very specific case of hypot, then being able to work
with as large a range as possible via clever tricks is great, but
there is no great practical need.
Certainly not enough to dismiss the 'naive' solution out of hand,
especially if it is faster.
I stated elsewhere that I often worked with 'x*x + y*y' withoutIt can help even here but in less obvious ways.
bothering with the square root, so here that cleverness won't help.
Well, inheritance is not as shadowing; you can explicitly qualify the
access to inherited attributes!
Or how did these problems look like? - And how do you solve it? - By renaming, say, hierarchical index variables 'i' to 'i1', 'i2', etc.?
Janis
On 30/09/2026 13:14, Janis Papanagnou wrote:
You mean when I point out that you are hallucinating, presenting your
personal opinions as facts,
About shadowing? Michael S made similar remarks to mine. Perhaps he's hallucinating too.
On 30/09/2026 14:45, bart wrote:
On 30/09/2026 13:14, Janis Papanagnou wrote:
You mean when I point out that you are hallucinating, presenting
your personal opinions as facts,
About shadowing? Michael S made similar remarks to mine. Perhaps
he's hallucinating too.
Michael wrote that /sometimes/ shadowing hides bugs that might
otherwise have been noticed by the programmer and/or trigger a
compilation error. And some people and coding standards actively
avoid shadowing.
That's all fair.
And it also shows that it is personal opinion - even when multiple
people happen to share the same opinion. Janis's opinions on
shadowing are no more or less factual than yours, and no more or less
valid. You can dislike shadowing if you want, you can disable it in
your language if you want, use "gcc -Wshadow" if you want. But be
careful about turning your preferences and personal experiences into generalisations and assuming they apply to others. (I have been
known to do that myself from time to time - it does not mean it is a
good thing!)
(I don't believe Michael gave his own preferences for whether or not
to try to avoid shadowing. I'm guessing he aims to pick his
identifier names in a way that makes his code as clear as he can
reasonably make it, unless he is required to follow a style guide
with rules on the matter.)
Support for shadowing is the norm for languages with scoped
identifiers
- identifiers in inner scopes can shadow those of outer scopes.
Things can be complicated when there are multiple types of scope in a language, but shadowing is pretty much essential for scalability of a language, even though it can usually be avoided.
gcc has warnings "-Wshadow-compatible-local" and "-Wshadow=local"
which warn on local variables shadowing each other, which can be a
good compromise for what to avoid without risking false positives.
But it's a personal style choice.
On Wed, 30 Sep 2026 15:30:29 +0200
David Brown <david.brown@hesbynett.no> wrote:
On 30/09/2026 14:45, bart wrote:
On 30/09/2026 13:14, Janis Papanagnou wrote:
You mean when I point out that you are hallucinating, presenting
your personal opinions as facts,
About shadowing? Michael S made similar remarks to mine. Perhaps
he's hallucinating too.
Michael wrote that /sometimes/ shadowing hides bugs that might
otherwise have been noticed by the programmer and/or trigger a
compilation error. And some people and coding standards actively
avoid shadowing.
That's all fair.
And it also shows that it is personal opinion - even when multiple
people happen to share the same opinion. Janis's opinions on
shadowing are no more or less factual than yours, and no more or less
valid. You can dislike shadowing if you want, you can disable it in
your language if you want, use "gcc -Wshadow" if you want. But be
careful about turning your preferences and personal experiences into
generalisations and assuming they apply to others. (I have been
known to do that myself from time to time - it does not mean it is a
good thing!)
(I don't believe Michael gave his own preferences for whether or not
to try to avoid shadowing. I'm guessing he aims to pick his
identifier names in a way that makes his code as clear as he can
reasonably make it, unless he is required to follow a style guide
with rules on the matter.)
Support for shadowing is the norm for languages with scoped
identifiers
- identifiers in inner scopes can shadow those of outer scopes.
Generally yes, but there exist variations.
For example, in C# local variable in the inner block is not allowed to
to have the same name as local variable in the outer score.
Rust is extreme in opposite direction - shadowing is allowed even
without creation of the new block. Although in this case shadowing is,
may be, not the best name.
Things can be complicated when there are multiple types of scope in a
language, but shadowing is pretty much essential for scalability of a
language, even though it can usually be avoided.
gcc has warnings "-Wshadow-compatible-local" and "-Wshadow=local"
which warn on local variables shadowing each other, which can be a
good compromise for what to avoid without risking false positives.
But it's a personal style choice.
On 30/09/2026 16:14, Michael S wrote:
Rust is extreme in opposite direction - shadowing is allowed even
without creation of the new block. Although in this case shadowing
is, may be, not the best name.
I have always thought it would be nice in C and C++, to be able to re-declare variables (especially const "variables") without having to
be able to introduce new blocks :
const int data = get_next();
do_first_thing(data);
const int data = get_next();
do_second_thing(data);
(The semantics would be basically as though a new block was
introduced before the pair of lines. Then let the compiler's
lifetime analysis handle efficient re-use of registers and stack
slots.)
While it could lead to confusing code sometimes, I think it could
also be helpful in code that has repetitive patterns. As it is, you
need to either have new names, make the variable non-const, or
include extra blocks around the sections. I'd be quite happy if this
were restricted to "const" objects.
Is that the sort of thing Rust allows here?
On 30/09/2026 14:45, bart wrote:
On 30/09/2026 13:14, Janis Papanagnou wrote:
You mean when I point out that you are hallucinating, presenting your
personal opinions as facts,
About shadowing? Michael S made similar remarks to mine. Perhaps he's
hallucinating too.
Michael wrote that /sometimes/ shadowing hides bugs that might otherwise have been noticed by the programmer and/or trigger a compilation error.
And some people and coding standards actively avoid shadowing.
That's all fair.
And it also shows that it is personal opinion - even when multiple
people happen to share the same opinion.-a Janis's opinions on shadowing
are no more or less factual than yours, and no more or less valid.-a You
can dislike shadowing if you want,
It can be useful, it can also introduce subtle bugs if doneinadvertently.
I interpret it that as that you are telling me that *you* introduced"subtle bugs". (Okay, we know you, so that is not too surprising. But
Of you forget to define a local variable and accidentally overwrite,or just use, the global version.
This is obviously your personal problem; operating on something youhaven't declared is not a problem of shadowing.
And never heard anyone complaining about it.
In decades I also
don't recall that subtile (or obvious) errors had been reported
because of that. (Are you, yet again, just making things up for
the argument or have you any different observations from your
personal coding practice?)
you can disable it in your language
if you want,
On 2026-09-30 12:35, bart wrote:
On 30/09/2026 06:02, Janis Papanagnou wrote:
On 2026-09-29 12:11, bart wrote:
Would you prefer a language without hierarchical blocks, scopes,
and shadowing?! (rhetoric)
I do without block-scopes.
We know you are doing a lot things and omitting yet more things than
other experienced CS folks.
I wonder that you still think the Sun isWhy don't you ask the creators of the two languages I mentioned?
rotating around the Earth.
On 30/09/2026 14:30, David Brown wrote:
On 30/09/2026 14:45, bart wrote:
On 30/09/2026 13:14, Janis Papanagnou wrote:
And it also shows that it is personal opinion - even when multiple
people happen to share the same opinion.-a Janis's opinions on
shadowing are no more or less factual than yours, and no more or less
valid.-a You can dislike shadowing if you want,
I didn't give my opinions on it. I pointed out some issues with it.
you can disable it in your language if you want,
I don't like that inadvertent shadowing that leads to odd bugs isn't reported. But that is how it has worked for decades.
(However, one feature I have which is out-of-order definitions, together with the ability to omit having a main() wrapper around top-level
executable statement, is very susceptible to such errors. So that has
been banned on one language and in another is only used for throwaway programs.)
Clashes between the same imported name /are/ detected, so that I know to
do something about it. Another approach would be to silently use the
first match.
(I don't know what languages do that other than Python using 'from'
imports. I don't know enough C++ to try it out via 'using'.)
On Wed, 30 Sep 2026 14:31:40 +0200
Janis Papanagnou <janis_papanagnou+ng@hotmail.com> wrote:
Or how did these problems look like? - And how do you solve it? - By
renaming, say, hierarchical index variables 'i' to 'i1', 'i2', etc.?
There was a member variable in the base class and member variable with
the same name in derived class.
The programmer accessed (wrote to) a member of derived when his actual intention was to access the one of base. Then he wondered why the value
in the base instance is wrong.
Since it was just a mistake, a fix was easy - removing the offending
member from declaration of derived class. But finding the bug was not
easy.
On 2026-09-30 15:12, Michael S wrote:
On Wed, 30 Sep 2026 14:31:40 +0200
Janis Papanagnou <janis_papanagnou+ng@hotmail.com> wrote:
Or how did these problems look like? - And how do you solve it? - By
renaming, say, hierarchical index variables 'i' to 'i1', 'i2', etc.?
There was a member variable in the base class and member variable with
the same name in derived class.
Yes, I figured as much so far, I assumed so.
I fear we could dispute well about (mis-)designs with attributes of the
same name in hierarchical class definitions, what one wants to model by
that.
Or, you know, you could avoid wasting everybodyrCOs time, shut up, and
use the existing wonderful library of readily available,
well-documented, standards-compliant open-source routines that already
do the job so well.
fir pisze:
you know there are a lacking tiny functions in c-lib
(by c-lib i mean those standard c includes all know)
AND if people use many maybe there is a need to standarize it
byslef? if you need some could be ggood candidates for standarisation
maybe write it here (i mean whole body of such function)
we could and should discuss them
maybe something liek this?
int mini(int a,int b) { return a<b?a:b; }
int maxi(int a,int b) { return a>b?a:b; }
float minf(float a,float b) { return a<b?a:b; }
float maxf(float a,float b) { return a>b?a:b; }
int absi(int x) { return x<0?-x:x; }
float absf(float x) { return x<0?-x:x; }
float signf(float x) { return x>0?1:x<0?-1:0; }
int signi(int x) { return x>0?1:x<0?-1:0; }
//above controversial?
int clampi(int x,int a,int b) { return x<a?a:x>b?b:x; }
float clampf(float x,float a,float b) { return x<a?a:x>b?b:x; }
int betweeni(int x,int a,int b) {-a return x>=a && x<=b; }
float lerp(float a,float b,float t) { return a+(b-a)*t; }
float inv_lerp(float a,float b,float x) { return (x-a)/(b-a); }
float remap(float x,float a,float b,float c,float d) { return c+(x- a)*(d-c)/(b-a); }
float rad(float x) { return x*PI/180.0f; }
float deg(float x) { return x*180.0f/PI; }
//thise above i dont quite use
float dist2_square(float x1,float y1,float x2,float y2) {-a-a float x=x2- x1,y=y2-y1;-a-a-a-a return x*x+y*y; }
float dist2(float x1,float y1,float x2,float y2) {-a-a-a return sqrtf(dist2(x1,y1,x2,y2));}
float len2_square(float x,float y) {-a-a-a return x*x+y*y; }
float len2(float x,float y) {-a return sqrtf(x*x+y*y);}
float dot2(float ax,float ay,float bx,float by){-a-a return ax*bx+ay*by;} float cross2(float ax,float ay,float bx,float by){-a-a-a return ax*by-ay*bx;} void-a norm2(float *x,float *y) {-a float d=sqrtf(*x**x+*y**y);-a-a if(d>0) { *x/=d;-a *y/=d; }}
float dist2_to_line(float px,float py,float ax,float ay,float bx,float by){-a-a-a return fabsf(cross2(bx-ax,by-ay,px-ax,py-ay)) / sqrtf(dist2_square(ax,ay,bx,by));}
// hare names may be controversial
the fact is imo though people should generallu decide and use one set of such names imo
there is also more functions to put here
On 30/09/2026 17:54, bart wrote:
(However, one feature I have which is out-of-order definitions,
together with the ability to omit having a main() wrapper around top-
level executable statement, is very susceptible to such errors. So
that has been banned on one language and in another is only used for
throwaway programs.)
Out-of-order definitions within a scope is susceptible to a lot of
risks, unless it is quite restricted.-a In particular, I would restrict
it to constant "things" - constant objects and functions, and perhaps types.-a I would hate to figure out what is going on with "x = 2;"
followed by "int x = 3;" in the same scope.-a (Maybe you don't allow initialisation in variable definitions?)
Clashes between the same imported name /are/ detected, so that I know
to do something about it. Another approach would be to silently use
the first match.
Noisy errors on clashes are a good idea if there is no clear and
consistent ordering.
(I don't know what languages do that other than Python using 'from'
imports. I don't know enough C++ to try it out via 'using'.)
The broader point is that pretty much any arithmetic involving
floats can overflow the range if the magnitudes are large enough (or
small enough with divide etc).
On 30/09/2026 17:26, David Brown wrote:
On 30/09/2026 17:54, bart wrote:
(However, one feature I have which is out-of-order definitions,
together with the ability to omit having a main() wrapper around top-
level executable statement, is very susceptible to such errors. So
that has been banned on one language and in another is only used for
throwaway programs.)
Out-of-order definitions within a scope is susceptible to a lot of
risks, unless it is quite restricted.-a In particular, I would restrict
it to constant "things" - constant objects and functions, and perhaps
types.-a I would hate to figure out what is going on with "x = 2;"
followed by "int x = 3;" in the same scope.-a (Maybe you don't allow
initialisation in variable definitions?)
Names can be declared anywhere in a scope, even all at the end.
That is uncommon for manually written code, but it is highly useful for machine-generated code, when you don't have all the info needed for a declaration until the body of a function has been generated.
If there is a runtime initialisation for a variable, then that will be
done at the declaration point. If that declaration is encountered again,
it will be reinitialised.
C works the same way, except the name is not in scope until after the declaration.
This gives the side-effect of allowing two identifiers with the same
name within the scope:
-aint abc=100;-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a // [1]
-aint main() {
-a-a-a-a printf("%d\n", abc);-a-a-a-a-a-a // abc [1]
-a-a-a-a char* abc="200";-a-a-a-a-a-a-a-a-a-a // [2]
-a-a-a-a printf("%s\n", abc);-a-a-a-a-a-a // abc [2]
-a}
This can give some odd effects: move that second declaration after the second printf, or comment it out, and it will go wrong. If it still compiles, you now have a bug.
(The problem I mentioned is this in my systems language:
-a-a proc F(int n) =
-a-a-a-a-a-a for i in 1..n do print "*" end
-a-a-a-a-a-a println
-a-a end
-a-a for i in 1..5 do F(i) end
For-loop indices are auto-declared if no variable of that name is in
scope. The second 'i' is thus declared to be 'int', at module scope,
visible everywhere.
Inside F(), since no local 'i' has been declared, it will use that outer
'i' and overwrite the caller's 'i' when it runs that loop.
Python has a similar problem, but it is not as bad since, if F tries to modify 'i', it assumes it is a local.)
Clashes between the same imported name /are/ detected, so that I know
to do something about it. Another approach would be to silently use
the first match.
Noisy errors on clashes are a good idea if there is no clear and
consistent ordering.
(I don't know what languages do that other than Python using 'from'
imports. I don't know enough C++ to try it out via 'using'.)
I've now tested C++, and with 'namespaces' and 'using', ambiguities are reported by g++.
(My scheme is more about modules, which also create a namespace; I've
not attempted C++ modules.)
On 30/09/2026 03:09, James Kuyper wrote:
On Tue, 29 Sep 2026 14:36:34 +0100, bart wrote:
What exactly is incorrect about the naive method? That itstops > working at a lower magnitude than hypot()?
It stops working at a MUCH lower magnitude. The naive
implementation overflows if either argument > sqrt(DBL_MAX).
Well, so what? You can say that about lots of different expressions
and functions!
Here is a more self-contained version of my generator. It asks you
how many vertices to enter. Builds CTTEST.BAS, then you can just
EXEC CTTEST.BAS to run it. Here is my code. Just for fun. The
generated code draws a bunch of polys using the table LT.
| Sysop: | Amessyroom |
|---|---|
| Location: | Fayetteville, NC |
| Users: | 74 |
| Nodes: | 6 (0 / 6) |
| Uptime: | 121:16:32 |
| Calls: | 1,194 |
| Files: | 1,352 |
| Messages: | 290,208 |