Discussion:
on allowing "int a" definition everywhere
(too old to reply)
fir
2024-08-20 16:48:17 UTC
Permalink
got some thought today thet simply probably allowing
to define "int a" everywhere could be just simply a good
c (or other language) design decision

there are here places when its not allowed like

if(int a==2) {} or

foo(1,2,int a); or f= a*int b*c

and soem must write

int a;
if(a==2) {} or

int a;
foo(1,2,a);

int b;
f= a*b*c

but is probably pointles to disallow that it simply
probably should be allowed..

some could say that local variables need initialisation
but no problem to also write initialisation imo

if((int a=2)==2)

it may look weird but this ewirdness is side thing
(not part of this idea) and the idea is imo most probably
right
Thiago Adams
2024-08-20 17:03:28 UTC
Permalink
initializer inside if is already in C++, and it will probably be on C2Y.
fir
2024-08-20 17:18:48 UTC
Permalink
Post by Thiago Adams
initializer inside if is already in C++, and it will probably be on C2Y.
can you show an example how it look like?

what with definition in espression liek

foo((int a=2*int b=10) etc

It loks weird but I also COME TO CONCLUSION TODAY
THAT in new language we must drop the "pure text" text set
we need bold and possibly loloristation so instead

int x = 2

you could just bold x and write =2

bold x = 2

and simply bold mean symbol definition

this opens a new wariety of nice code looking,
by colorisation some coud differentiate if it is int or float
etc
fir
2024-08-20 17:21:34 UTC
Permalink
Post by fir
Post by Thiago Adams
initializer inside if is already in C++, and it will probably be on C2Y.
can you show an example how it look like?
what with definition in espression liek
foo((int a=2*int b=10) etc
It loks weird but I also COME TO CONCLUSION TODAY
THAT in new language we must drop the "pure text" text set
we need bold and possibly loloristation so instead
int x = 2
you could just bold x and write =2
bold x = 2
and simply bold mean symbol definition
this opens a new wariety of nice code looking,
by colorisation some coud differentiate if it is int or float
etc
i mean i thinked a lot how it make look good old way but after real doze
of thinking my conclusion would be all is worse than simply adding at
least text bolding
Thiago Adams
2024-08-20 17:34:04 UTC
Permalink
Post by fir
Post by Thiago Adams
initializer inside if is already in C++, and it will probably be on C2Y.
can you show an example how it look like?
#include <stdio.h>

int main()
{
if (FILE* f = fopen("file.txt", "r"); f)
{
/*...*/
fclose(f);
}

if (FILE* f = fopen("file.txt", "r"))
{
/*...*/
fclose(f);
}
}

https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3267.htm

https://en.cppreference.com/w/cpp/language/if
fir
2024-08-20 20:18:30 UTC
Permalink
Post by Thiago Adams
Post by fir
Post by Thiago Adams
initializer inside if is already in C++, and it will probably be on C2Y.
can you show an example how it look like?
#include <stdio.h>
int main()
{
if (FILE* f = fopen("file.txt", "r"); f)
{
/*...*/
fclose(f);
}
if (FILE* f = fopen("file.txt", "r"))
{
/*...*/
fclose(f);
}
}
https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3267.htm
https://en.cppreference.com/w/cpp/language/if
ok
Blue-Maned_Hawk
2024-08-21 04:42:46 UTC
Permalink
Post by Thiago Adams
initializer inside if is already in C++, and it will probably be on C2Y.
If it's for consistency with how for loops permit declarations, i would
_much_ prefer that they just outlaw that to induce consistency.

(Really, i'd ideally want things to just stay as they are, since
declarations in for loops are simply too useful for macros.)
--
Blue-Maned_Hawk│shortens to Hawk│/blu.mɛin.dʰak/│he/him/his/himself/Mr.
blue-maned_hawk.srht.site
X11 works in mysterious ways.
Thiago Adams
2024-08-21 11:17:52 UTC
Permalink
Post by Blue-Maned_Hawk
Post by Thiago Adams
initializer inside if is already in C++, and it will probably be on C2Y.
If it's for consistency with how for loops permit declarations, i would
_much_ prefer that they just outlaw that to induce consistency.
(Really, i'd ideally want things to just stay as they are, since
declarations in for loops are simply too useful for macros.)
I like the ability to declare things inside if.

if (FILE* f = fopen("file.txt", "r"))
{
/*...*/
fclose(f);
}

Because it makes the scope of f, associated with the pointed object
lifetime.

For instance, if you try to use f

if (FILE* f = fopen("file.txt", "r"))
{
/*...*/
fclose(f);
}
fwrite(f, ..) ;// ERROR
Bart
2024-08-21 12:34:51 UTC
Permalink
Post by Thiago Adams
Post by Blue-Maned_Hawk
Post by Thiago Adams
initializer inside if is already in C++, and it will probably be on C2Y.
If it's for consistency with how for loops permit declarations, i would
_much_  prefer that they just outlaw that to induce consistency.
(Really, i'd ideally want things to just stay as they are, since
declarations in for loops are simply too useful for macros.)
I like the ability to declare things inside if.
if (FILE* f = fopen("file.txt", "r"))
{
  /*...*/
  fclose(f);
}
Because it makes the scope of f, associated with the pointed object
lifetime.
For instance, if you try to use f
if (FILE* f = fopen("file.txt", "r"))
{
  /*...*/
  fclose(f);
}
fwrite(f, ..) ;// ERROR
Run-time or compile-time error?

It won't be a compile-time error if there is another 'f' visible in that
outer scope.

And it won't be one here either:

if (FILE* f = fopen("file.txt", "r"))
{
/*...*/
fclose(f);
fwrite(f, ..) ;// ERROR
}

Meanwhile, I'd have a serious problem with the extra clutter this
causes. Since you are not reporting an fopen failure, I'd write this as:

FILE* f;

f = fopen("file.txt", "r");
if (f) {
// ...
fclose(f);
}

However I'd be more likely check for failure first.

Since I did a recent survery where, on a average, functions only had 3
local variables (in a selection of apps), I've been even more sceptical
of block-scoped variables.
Thiago Adams
2024-08-21 13:01:12 UTC
Permalink
Post by Bart
Post by Thiago Adams
Post by Blue-Maned_Hawk
Post by Thiago Adams
initializer inside if is already in C++, and it will probably be on C2Y.
If it's for consistency with how for loops permit declarations, i would
_much_  prefer that they just outlaw that to induce consistency.
(Really, i'd ideally want things to just stay as they are, since
declarations in for loops are simply too useful for macros.)
I like the ability to declare things inside if.
if (FILE* f = fopen("file.txt", "r"))
{
   /*...*/
   fclose(f);
}
Because it makes the scope of f, associated with the pointed object
lifetime.
For instance, if you try to use f
if (FILE* f = fopen("file.txt", "r"))
{
   /*...*/
   fclose(f);
}
fwrite(f, ..) ;// ERROR
Run-time or compile-time error?
Compile time. f is not visible outside.
Post by Bart
It won't be a compile-time error if there is another 'f' visible in that
outer scope.
 if (FILE* f = fopen("file.txt", "r"))
 {
    /*...*/
    fclose(f);
    fwrite(f, ..) ;// ERROR
 }
For this type of error you need my static analyzer. (cake) :D

http://thradams.com/cake/playground.html?code=I3ByYWdtYSBzYWZldHkgZW5hYmxlCiNpbmNsdWRlIDxzdGRpby5oPgppbnQgbWFpbigpCnsKICAgRklMRSogX093bmVyIF9PcHQgZjsKICAgaWYgKCBmID0gZm9wZW4oImZpbGUudHh0IiwgInIiKSkKICAgewogICAgY2hhciBhW109ImFiIjsKICAgIGZjbG9zZShmKTsgICAgIAogICAgZndyaXRlKGEsIDEsIDIsIGYpOyAgICAgCiAgIH0KfQo%3D&to=-1&options=
Post by Bart
Meanwhile, I'd have a serious problem with the extra clutter this
  FILE* f;
  f = fopen("file.txt", "r");
  if (f) {
     // ...
     fclose(f);
  }
However I'd be more likely check for failure first.
It is something optional to use.
Post by Bart
Since I did a recent survery where, on a average, functions only had 3
local variables (in a selection of apps), I've been even more sceptical
of block-scoped variables.
Michael S
2024-08-21 13:54:54 UTC
Permalink
On Wed, 21 Aug 2024 10:01:12 -0300
Post by Thiago Adams
For this type of error you need my static analyzer. (cake) :D
Unnecessary. MSVC -W4 gives a warning.

#include <cstdio>

void foo()
{
FILE* f = fopen("file1.txt", "r");
if (FILE* f = fopen("file2.txt", "r")) {
fclose(f);
}
if (f)
fclose(f);
}


scopes.cpp(6): warning C4456: declaration of 'f' hides previous local
declaration scopes.cpp(5): note: see declaration of 'f'
Thiago Adams
2024-08-21 14:21:46 UTC
Permalink
Post by Michael S
On Wed, 21 Aug 2024 10:01:12 -0300
Post by Thiago Adams
For this type of error you need my static analyzer. (cake) :D
Unnecessary. MSVC -W4 gives a warning.
#include <cstdio>
void foo()
{
FILE* f = fopen("file1.txt", "r");
if (FILE* f = fopen("file2.txt", "r")) {
fclose(f);
}
if (f)
fclose(f);
}
scopes.cpp(6): warning C4456: declaration of 'f' hides previous local
declaration scopes.cpp(5): note: see declaration of 'f'
The warning cake gives is "use after free" or use after fclose.
Blue-Maned_Hawk
2024-08-22 08:40:30 UTC
Permalink
Post by Thiago Adams
Post by Blue-Maned_Hawk
Post by Thiago Adams
initializer inside if is already in C++, and it will probably be on C2Y.
If it's for consistency with how for loops permit declarations, i would
_much_ prefer that they just outlaw that to induce consistency.
(Really, i'd ideally want things to just stay as they are, since
declarations in for loops are simply too useful for macros.)
I like the ability to declare things inside if.
if (FILE* f = fopen("file.txt", "r"))
{
/*...*/ fclose(f);
}
Because it makes the scope of f, associated with the pointed object
lifetime.
For instance, if you try to use f
if (FILE* f = fopen("file.txt", "r"))
{
/*...*/ fclose(f);
}
fwrite(f, ..) ;// ERROR
You can already do that in C23:

if (…) {
FILE * f = fopen("file.txt", "r");
/* … */
fclose(f);
}
fwrite(f, …); /* Some kind of error happens. */

Or, if you need it to exist before the controlling expression:

for (bool x = true; x; x = false) for (FILE * f = fopen("file.txt", "r");
x; x = false) if (…) {
/* … */
fclose(f);
}
fwrite(f, …);

Therefore, your example does not work as evidence in favor of declarations
in if statement controlling expressions because it's already possible in
other ways.
--
Blue-Maned_Hawk│shortens to Hawk│/blu.mɛin.dʰak/│he/him/his/himself/Mr.
blue-maned_hawk.srht.site
Banned in the UK for several years!
Keith Thompson
2024-08-22 09:21:56 UTC
Permalink
[...]
Post by Blue-Maned_Hawk
Post by Thiago Adams
I like the ability to declare things inside if.
if (FILE* f = fopen("file.txt", "r"))
{
/*...*/ fclose(f);
}
Because it makes the scope of f, associated with the pointed object
lifetime.
For instance, if you try to use f
if (FILE* f = fopen("file.txt", "r"))
{
/*...*/ fclose(f);
}
fwrite(f, ..) ;// ERROR
Are you suggesting that there's some relevant new feature in C23?
I don't believe there is.
Post by Blue-Maned_Hawk
if (…) {
FILE * f = fopen("file.txt", "r");
/* … */
fclose(f);
}
fwrite(f, …); /* Some kind of error happens. */
I presume the "…" is meant to stand in for some arbitary code, not that
the ellipsis is part of the C23 syntax.

That's not at all the same thing. In Thiago's code, the body
of the if statement is not executed if the fopen() call fails.
Note that fclose(f) has undefined behavior of f==NULL.
Post by Blue-Maned_Hawk
for (bool x = true; x; x = false) for (FILE * f = fopen("file.txt", "r");
x; x = false) if (…) {
/* … */
fclose(f);
}
fwrite(f, …);
Therefore, your example does not work as evidence in favor of declarations
in if statement controlling expressions because it's already possible in
other ways.
I'm not going to wade through that, but *of course* you can write code
that does what Thiago's code is intended to do. The point of allowing
declarations in if conditions is for convenience, the same reason
they're allowed in for loops starting in C99.

The original code:

if (FILE* f = fopen("file.txt", "r"))
{
/*...*/ fclose(f);
}

doesn't allow for taking some non-trivial action of the fopen() call
fails, but if a declaration in an if condition is visible in the else
clause, you could write something like:

if (FILE* f = fopen("file.txt", "r")) {
/*...*/
fclose(f);
}
else {
perror("file.txt");
exit(EXIT_FAILURE); // or try something else
}
--
Keith Thompson (The_Other_Keith) Keith.S.Thompson+***@gmail.com
void Void(void) { Void(); } /* The recursive call of the void */
Ben Bacarisse
2024-08-22 10:29:45 UTC
Permalink
Post by Thiago Adams
if (FILE* f = fopen("file.txt", "r"))
I think the proposal would be a declaration to precede an expression:

if (FILE* f = fopen("file.txt", "r"); f)
Post by Thiago Adams
{
/*...*/ fclose(f);
}
doesn't allow for taking some non-trivial action of the fopen() call
fails, but if a declaration in an if condition is visible in the else
if (FILE* f = fopen("file.txt", "r")) {
/*...*/
fclose(f);
}
else {
perror("file.txt");
exit(EXIT_FAILURE); // or try something else
}
What's the significance of the declared name being in scope in the else
clause here?
--
Ben.
Keith Thompson
2024-08-22 18:12:54 UTC
Permalink
Post by Thiago Adams
Post by Thiago Adams
if (FILE* f = fopen("file.txt", "r"))
if (FILE* f = fopen("file.txt", "r"); f)
I don't think so, or at least I don't think it's only that.

In C++17, the syntax for an if statement is (leaving some stuff out):

if ( init-statement[opt] condition ) statement

where an init-statement is an expression statement or a simple
declaration (which includes a trailing semicolon), and a condition is an
expression or a declarator with an initialization. So these are
equivalent in C++:

if (FILE* f = fopen("file.txt", "r"))
if (FILE* f = fopen("file.txt", "r"); f)
Post by Thiago Adams
Post by Thiago Adams
{
/*...*/ fclose(f);
}
doesn't allow for taking some non-trivial action of the fopen() call
fails, but if a declaration in an if condition is visible in the else
if (FILE* f = fopen("file.txt", "r")) {
/*...*/
fclose(f);
}
else {
perror("file.txt");
exit(EXIT_FAILURE); // or try something else
}
What's the significance of the declared name being in scope in the else
clause here?
My brain seems to have taken a detour while I was writing that.

fopen() returns either a valid pointer or NULL; if it fails, there's no
extra information in the pointer itself. But if a function's result on
failure includes information about how it failed, accessing the value in
the else clause is useful. (And C++ supports this.)
--
Keith Thompson (The_Other_Keith) Keith.S.Thompson+***@gmail.com
void Void(void) { Void(); } /* The recursive call of the void */
Kaz Kylheku
2024-08-22 18:37:09 UTC
Permalink
Post by Ben Bacarisse
What's the significance of the declared name being in scope in the else
clause here?
else is a part of the if statement. Everything under the statement
should have visibility to its lexical variable(s).

Otherwise, code like this is prohibited:

if (double x = fun(y); x < 0)
return x * x;
else
return x * y;
--
TXR Programming Language: http://nongnu.org/txr
Cygnal: Cygwin Native Application Library: http://kylheku.com/cygnal
Mastodon: @***@mstdn.ca
Ben Bacarisse
2024-08-22 23:39:16 UTC
Permalink
Post by Kaz Kylheku
Post by Ben Bacarisse
What's the significance of the declared name being in scope in the else
clause here?
else is a part of the if statement. Everything under the statement
should have visibility to its lexical variable(s).
Yes, but the key point was "here". It's obviously important in general,
but the claim was that it mattered for the example given.
--
Ben.
Bart
2024-08-22 10:00:28 UTC
Permalink
Post by Blue-Maned_Hawk
Post by Thiago Adams
Post by Blue-Maned_Hawk
Post by Thiago Adams
initializer inside if is already in C++, and it will probably be on C2Y.
If it's for consistency with how for loops permit declarations, i would
_much_ prefer that they just outlaw that to induce consistency.
(Really, i'd ideally want things to just stay as they are, since
declarations in for loops are simply too useful for macros.)
I like the ability to declare things inside if.
if (FILE* f = fopen("file.txt", "r"))
{
/*...*/ fclose(f);
}
Because it makes the scope of f, associated with the pointed object
lifetime.
For instance, if you try to use f
if (FILE* f = fopen("file.txt", "r"))
{
/*...*/ fclose(f);
}
fwrite(f, ..) ;// ERROR
if (…) {
FILE * f = fopen("file.txt", "r");
/* … */
fclose(f);
}
fwrite(f, …); /* Some kind of error happens. */
for (bool x = true; x; x = false) for (FILE * f = fopen("file.txt", "r");
x; x = false) if (…) {
/* … */
fclose(f);
}
fwrite(f, …);
I wonder, if I laid it out it properly:

for (bool x = true; x; x = false)
for (FILE * f = fopen("file.txt", "r"); x; x = false)
if (…) {
/* … */
fclose(f);
}
fwrite(f, …);

Nope; I still haven't the faintest idea what this is supposed to do. I
suspect that it doesn't actually run or need those two nested loops.

I assume the (...) tests the value of 'f'? If so then perhaps this is a
shorter way of expressing the same thing:

{
FILE * f = fopen("file.txt", "r");
if (f) {
/* … */
fclose(f);
}
}
fwrite(f, …);
Thiago Adams
2024-08-22 11:10:34 UTC
Permalink
Post by Bart
I assume the (...) tests the value of 'f'? If so then perhaps this is a
    {
        FILE * f = fopen("file.txt", "r");
        if (f) {
            /* … */
            fclose(f);
        }
    }
    fwrite(f, …);
Yes, this is the equivalent code.

C++ allows two forms. One with explicit check and another one with
implicit check.


if (FILE* f = fopen("file.txt", "r"); f) /*f is checked explicitly*/
{
/*...*/
fclose(f);
}

if (FILE* f = fopen("file.txt", "r")) /*f is checked implicitly*/
{
/*...*/
fclose(f);
}

I also have considered for cake to have a extra part that is "defer" part.

if (FILE* f = fopen("file.txt", "r"); f; fclose(f))
{
}

But if 'defer' were added to C2Y, we could then do the following:

if (FILE* f = fopen("file.txt", "r"); f; )
{
defer fclose(f);
/*...*/
}


Sometimes, too much syntactic sugar is not good because it creates too
many variants.
Blue-Maned_Hawk
2024-08-22 17:06:03 UTC
Permalink
<snip/>
Sometimes, too much syntactic sugar is not good because it creates too
many variants.
I agree with this. One exemplar of such a claim that comes first to my
mind is Perl: postfix statements, optional syntax, ambiguous precedence,
and exceptions to all rules, it's got all the shit. (Though it does
strictly mandate braces in compound statements, which i quite like.)
--
Blue-Maned_Hawk│shortens to Hawk│/blu.mɛin.dʰak/│he/him/his/himself/Mr.
blue-maned_hawk.srht.site
(as new—only one hundred year's use)
fir
2024-08-23 10:47:55 UTC
Permalink
Post by Blue-Maned_Hawk
Post by Blue-Maned_Hawk
Post by Thiago Adams
Post by Blue-Maned_Hawk
Post by Thiago Adams
initializer inside if is already in C++, and it will probably be on C2Y.
If it's for consistency with how for loops permit declarations, i would
_much_ prefer that they just outlaw that to induce consistency.
(Really, i'd ideally want things to just stay as they are, since
declarations in for loops are simply too useful for macros.)
I like the ability to declare things inside if.
if (FILE* f = fopen("file.txt", "r"))
{
/*...*/ fclose(f);
}
Because it makes the scope of f, associated with the pointed object
lifetime.
For instance, if you try to use f
if (FILE* f = fopen("file.txt", "r"))
{
/*...*/ fclose(f);
}
fwrite(f, ..) ;// ERROR
if (…) {
FILE * f = fopen("file.txt", "r");
/* … */
fclose(f);
}
fwrite(f, …); /* Some kind of error happens. */
for (bool x = true; x; x = false) for (FILE * f = fopen("file.txt", "r");
x; x = false) if (…) {
/* … */
fclose(f);
}
fwrite(f, …);
for (bool x = true; x; x = false)
for (FILE * f = fopen("file.txt", "r"); x; x = false)
if (…) {
/* … */
fclose(f);
}
fwrite(f, …);
Nope; I still haven't the faintest idea what this is supposed to do. I
suspect that it doesn't actually run or need those two nested loops.
I assume the (...) tests the value of 'f'? If so then perhaps this is a
{
FILE * f = fopen("file.txt", "r");
if (f) {
/* … */
fclose(f);
}
}
fwrite(f, …);
btw maybe not so much relevent as what you write but
if to think the convention


foir(int i=0; i<100; i++)
{
//,,,
}

to amke int i scope relevant to only inner of the loop seem just
logically wrong

on assembly lebel you got outside of the loop inside of the loop
and loop code itself


loop:
....

cmp ecx, 100
jl loop


tehnically the loop as it can be breal it is more like that the loop
counter may be just the result needed in the outside - so logical bug in
c was here spotted
Bart
2024-08-23 11:25:32 UTC
Permalink
Post by fir
btw maybe not so much relevent as what you write but
if to think the convention
foir(int i=0; i<100; i++)
{
  //,,,
}
to amke int i scope relevant to only inner of the loop seem just
logically wrong
Actually it's one of the few places it makes sense!

But I don't like this idiom for several reasons. Sure, it can be
convenient to write:

for(int i=0; i<100; i++)

without having to make an annoying detour to the top of the function to
write that declaration for i. But then you need a second loop, and a
third, and how you have to repeat a declaration each time:

for(int i=0; i<200; i++)

Better to do it once and forget about it.

Then, it allows nested loops like this:

for (int i = 0; i<A; ++i)
for (int i = 0; i<B; ++i)
for (int i = 0; i<C; ++i)

All those i's are different! Only the last is accessible in the inner loop.
fir
2024-08-23 11:32:08 UTC
Permalink
Post by Bart
Post by fir
btw maybe not so much relevent as what you write but
if to think the convention
foir(int i=0; i<100; i++)
{
//,,,
}
to amke int i scope relevant to only inner of the loop seem just
logically wrong
Actually it's one of the few places it makes sense!
But I don't like this idiom for several reasons. Sure, it can be
for(int i=0; i<100; i++)
without having to make an annoying detour to the top of the function to
write that declaration for i. But then you need a second loop, and a
for(int i=0; i<200; i++)
Better to do it once and forget about it.
for (int i = 0; i<A; ++i)
for (int i = 0; i<B; ++i)
for (int i = 0; i<C; ++i)
All those i's are different! Only the last is accessible in the inner loop.
i never used nor even seen this with 3 i..for me as i said "loop" iteslf
not neccessary belongs to inside of the loop more like the outside..
here liek this this is misleading that the i is one thing - until
someone knows its just internat thing (but i as i said disagree it
should be intennal)
fir
2024-08-23 15:57:17 UTC
Permalink
Post by fir
Post by Bart
Post by fir
btw maybe not so much relevent as what you write but
if to think the convention
foir(int i=0; i<100; i++)
{
//,,,
}
to amke int i scope relevant to only inner of the loop seem just
logically wrong
Actually it's one of the few places it makes sense!
But I don't like this idiom for several reasons. Sure, it can be
for(int i=0; i<100; i++)
without having to make an annoying detour to the top of the function to
write that declaration for i. But then you need a second loop, and a
for(int i=0; i<200; i++)
Better to do it once and forget about it.
for (int i = 0; i<A; ++i)
for (int i = 0; i<B; ++i)
for (int i = 0; i<C; ++i)
All those i's are different! Only the last is accessible in the inner loop.
i never used nor even seen this with 3 i..for me as i said "loop" iteslf
not neccessary belongs to inside of the loop more like the outside..
here liek this this is misleading that the i is one thing - until
someone knows its just internat thing (but i as i said disagree it
should be intennal)
overally it is a question of loop should have its ovn scope at all
- and after this question stated im seem liek more to be closer to
teh optiuon that not
Lawrence D'Oliveiro
2024-08-21 03:30:17 UTC
Permalink
got some thought today thet simply probably allowing to define "int a"
everywhere could be just simply a good c (or other language) design
decision
Somehow along the line from BCPL to B to C, one useful feature was lost:
the ability to have a value-returning statement block inside an
expression.
Ben Bacarisse
2024-08-21 08:19:21 UTC
Permalink
Post by Lawrence D'Oliveiro
got some thought today thet simply probably allowing to define "int a"
everywhere could be just simply a good c (or other language) design
decision
the ability to have a value-returning statement block inside an
expression.
It was lost in the BCPL to B transition.
--
Ben.
Ben Bacarisse
2024-08-21 09:11:20 UTC
Permalink
Post by Ben Bacarisse
Post by Lawrence D'Oliveiro
got some thought today thet simply probably allowing to define "int a"
everywhere could be just simply a good c (or other language) design
decision
the ability to have a value-returning statement block inside an
expression.
It was lost in the BCPL to B transition.
Interestingly, it's an old idea the existed in both of C's main
progenitors, and yet is still got lost.

BCPL was influenced by CPL, so BCPL's valof/resultis expression is
similar to CPL's result of {... result := ...} form. But Ritchie also
cites Algol 68 as an influence on C, and in Algol 68 /all/ blocks have a
value (but the type is sometimes void).

Thompson must have thought it not worth preserving in B, and no one
thought to put it back into C when thinking about Algol 68.
--
Ben.
fir
2024-08-25 10:40:39 UTC
Permalink
Post by Lawrence D'Oliveiro
got some thought today thet simply probably allowing to define "int a"
everywhere could be just simply a good c (or other language) design
decision
the ability to have a value-returning statement block inside an
expression.
if so thats probably sad, though i dont know how it looked like
Lawrence D'Oliveiro
2024-08-27 06:52:46 UTC
Permalink
Post by fir
Post by Lawrence D'Oliveiro
Somehow along the line from BCPL to B to C, one useful feature was
lost: the ability to have a value-returning statement block inside an
expression.
if so thats probably sad, though i dont know how it looked like
The construct looks like

VALOF $( ... «stmts»; RESULTIS «return-value» $)
fir
2024-08-27 08:46:52 UTC
Permalink
Post by Lawrence D'Oliveiro
Post by fir
Post by Lawrence D'Oliveiro
Somehow along the line from BCPL to B to C, one useful feature was
lost: the ability to have a value-returning statement block inside an
expression.
if so thats probably sad, though i dont know how it looked like
The construct looks like
VALOF $( ... «stmts»; RESULTIS «return-value» $)
it is good to things return value and good to be able to combine it

as i sait for example i consider such loops

10'x //ten tiem execute x

print (10'x+=x)/10

would be equivalent of

for(int i=0; i<10; i++) x+=x;
print(x/10)

(and its still c, just with shorted syntax not python et sort)
fir
2024-08-27 09:03:51 UTC
Permalink
Post by fir
Post by Lawrence D'Oliveiro
Post by fir
Post by Lawrence D'Oliveiro
Somehow along the line from BCPL to B to C, one useful feature was
lost: the ability to have a value-returning statement block inside an
expression.
if so thats probably sad, though i dont know how it looked like
The construct looks like
VALOF $( ... «stmts»; RESULTIS «return-value» $)
it is good to things return value and good to be able to combine it
as i sait for example i consider such loops
10'x //ten tiem execute x
print (10'x+=x)/10
would be equivalent of
for(int i=0; i<10; i++) x+=x;
print(x/10)
(and its still c, just with shorted syntax not python et sort)
as to this loop as i said i had no ide how to make indexes like i
in this form but what comes to my mind now is maybe something lika


10'print("x")

10i'print(i)


480y' 640x' set_pixel(x,y, 0xffff00)

those i,x,y in loop 'headers' could be possibly subscripted
like 2 in typical H20 (2 is subscripted

eventually one can go

10' print((x 0)++)

where x 0 is initialisation of int x to zero
fir
2024-08-27 09:08:13 UTC
Permalink
Post by fir
Post by fir
Post by Lawrence D'Oliveiro
Post by fir
Post by Lawrence D'Oliveiro
Somehow along the line from BCPL to B to C, one useful feature was
lost: the ability to have a value-returning statement block inside an
expression.
if so thats probably sad, though i dont know how it looked like
The construct looks like
VALOF $( ... «stmts»; RESULTIS «return-value» $)
it is good to things return value and good to be able to combine it
as i sait for example i consider such loops
10'x //ten tiem execute x
print (10'x+=x)/10
would be equivalent of
for(int i=0; i<10; i++) x+=x;
print(x/10)
(and its still c, just with shorted syntax not python et sort)
as to this loop as i said i had no ide how to make indexes like i
in this form but what comes to my mind now is maybe something lika
10'print("x")
10i'print(i)
480y' 640x' set_pixel(x,y, 0xffff00)
those i,x,y in loop 'headers' could be possibly subscripted
like 2 in typical H20 (2 is subscripted
eventually one can go
10' print((x 0)++)
where x 0 is initialisation of int x to zero
overally not bad, i could somewhat accept that loop
(yu wouldnt belive how hard is come to that syntax conclusions,
literally takes years, and not 5 years more like 15)
fir
2024-08-27 09:47:21 UTC
Permalink
Post by fir
Post by fir
Post by fir
Post by Lawrence D'Oliveiro
Post by fir
Post by Lawrence D'Oliveiro
Somehow along the line from BCPL to B to C, one useful feature was
lost: the ability to have a value-returning statement block inside an
expression.
if so thats probably sad, though i dont know how it looked like
The construct looks like
VALOF $( ... «stmts»; RESULTIS «return-value» $)
it is good to things return value and good to be able to combine it
as i sait for example i consider such loops
10'x //ten tiem execute x
print (10'x+=x)/10
would be equivalent of
for(int i=0; i<10; i++) x+=x;
print(x/10)
(and its still c, just with shorted syntax not python et sort)
as to this loop as i said i had no ide how to make indexes like i
in this form but what comes to my mind now is maybe something lika
10'print("x")
10i'print(i)
480y' 640x' set_pixel(x,y, 0xffff00)
those i,x,y in loop 'headers' could be possibly subscripted
like 2 in typical H20 (2 is subscripted
eventually one can go
10' print((x 0)++)
where x 0 is initialisation of int x to zero
overally not bad, i could somewhat accept that loop
(yu wouldnt belive how hard is come to that syntax conclusions,
literally takes years, and not 5 years more like 15)
its digression but still i got problem what to do with
function definition esp returning values


take for example div(11,5) function which returns 2 (11/5) as
a main result but should also eventually return 1 (11%5) as a second
prt of result


the thinking is now maybe something like that (if using old syntax)

int div( int a, int b)
{
static int result = a/b,
static int remainder = a%b

return result;

}

x = div(20/7); //gives result

x y = (result, remainder) div(20/7); //gives both
x y = (remainder, result) div(20/7); //gives both but in different order
y = (remainder) div(20/7); //gives only the remainder


could also be used to skip a part of results

v2 = (x,y) cross(A,B) //when full result is x y z

also imo a given function if longer could ghave a bumch of local
variables and this way you eventually acces set of some you want so
it may be handy
fir
2024-08-27 09:52:03 UTC
Permalink
Post by fir
Post by fir
Post by fir
Post by fir
Post by Lawrence D'Oliveiro
Post by fir
Post by Lawrence D'Oliveiro
Somehow along the line from BCPL to B to C, one useful feature was
lost: the ability to have a value-returning statement block inside an
expression.
if so thats probably sad, though i dont know how it looked like
The construct looks like
VALOF $( ... «stmts»; RESULTIS «return-value» $)
it is good to things return value and good to be able to combine it
as i sait for example i consider such loops
10'x //ten tiem execute x
print (10'x+=x)/10
would be equivalent of
for(int i=0; i<10; i++) x+=x;
print(x/10)
(and its still c, just with shorted syntax not python et sort)
as to this loop as i said i had no ide how to make indexes like i
in this form but what comes to my mind now is maybe something lika
10'print("x")
10i'print(i)
480y' 640x' set_pixel(x,y, 0xffff00)
those i,x,y in loop 'headers' could be possibly subscripted
like 2 in typical H20 (2 is subscripted
eventually one can go
10' print((x 0)++)
where x 0 is initialisation of int x to zero
overally not bad, i could somewhat accept that loop
(yu wouldnt belive how hard is come to that syntax conclusions,
literally takes years, and not 5 years more like 15)
its digression but still i got problem what to do with
function definition esp returning values
take for example div(11,5) function which returns 2 (11/5) as
a main result but should also eventually return 1 (11%5) as a second
prt of result
the thinking is now maybe something like that (if using old syntax)
int div( int a, int b)
{
static int result = a/b,
static int remainder = a%b
return result;
}
x = div(20/7); //gives result
x y = (result, remainder) div(20/7); //gives both
x y = (remainder, result) div(20/7); //gives both but in different order
y = (remainder) div(20/7); //gives only the remainder
also could be used in fact with builtin operators

x = (remainder) 100/9;
x = (carry) 100+229;
x = (zero) 100+229;
x = (sign) 100+229;

etc (as such operator call could be understand as set some of its inner
local variables)
Post by fir
could also be used to skip a part of results
v2 = (x,y) cross(A,B) //when full result is x y z
also imo a given function if longer could ghave a bumch of local
variables and this way you eventually acces set of some you want so
it may be handy
fir
2024-08-27 11:56:47 UTC
Permalink
Post by fir
Post by fir
10' print((x 0)++)
where x 0 is initialisation of int x to zero
overally not bad, i could somewhat accept that loop
(yu wouldnt belive how hard is come to that syntax conclusions,
literally takes years, and not 5 years more like 15)
one of the worst things is find good function definition
but at least this 10' loop proves consciencity or
how it is caled (being short) its possible


right now i think if function maybe shouldnt note ret values in header (?)

this is by analogy for structure

s {} is structure and f {} is function

(its the same bcouse structure can have data fields and function can
have code elements - they bot may have mix

so if so if

s { float x,y,z } not return values so function maybe also should not

tyopu will nedd a keyword in function body though like res/result or return

s { result float x,y,z }


it could also define something like input maybe

s { input int a; result int b; } x;

x = 19; //comes into e

int y = x; //b comes here

or

s { input int a; b=0a; result int b; } x;

print( x(80)) //outs -80


i dont know if this is reasonable


also idea is to maybe turn "int" and "float " into runes

int should be "runic" I and float should be runic F

so

foo(int a, int b, float c) {}

can be written


foo aI bI cF {}

where I F are not normal but runic - this makes pleasant short and
clarifies things but im not sure if this is finally godd - but worth
consideration
fir
2024-08-27 18:04:29 UTC
Permalink
Post by fir
Post by fir
Post by fir
Post by Lawrence D'Oliveiro
Post by fir
Post by Lawrence D'Oliveiro
Somehow along the line from BCPL to B to C, one useful feature was
lost: the ability to have a value-returning statement block inside an
expression.
if so thats probably sad, though i dont know how it looked like
The construct looks like
VALOF $( ... «stmts»; RESULTIS «return-value» $)
it is good to things return value and good to be able to combine it
as i sait for example i consider such loops
10'x //ten tiem execute x
print (10'x+=x)/10
would be equivalent of
for(int i=0; i<10; i++) x+=x;
print(x/10)
(and its still c, just with shorted syntax not python et sort)
as to this loop as i said i had no ide how to make indexes like i
in this form but what comes to my mind now is maybe something lika
10'print("x")
10i'print(i)
480y' 640x' set_pixel(x,y, 0xffff00)
those i,x,y in loop 'headers' could be possibly subscripted
like 2 in typical H20 (2 is subscripted
eventually one can go
10' print((x 0)++)
where x 0 is initialisation of int x to zero
overally not bad, i could somewhat accept that loop
(yu wouldnt belive how hard is come to that syntax conclusions,
literally takes years, and not 5 years more like 15)
i wanted to compore how many chars my thin c skin conventions would
make (but not having funic F for wloat or runic U for unsigned) i put `
and the spare is not great becouse c is quite thin - hovever it uses a
lot of what i call 'decorators i eman not necessary ().; which could
be changed to spaces, it not spares chars but somewhat spares ink

on fictional snippet (probebly not working)

void draw_line( float x, float y, float x2, float y2, unsigned color)
{
float
wx=dist(x,x2),wy=dist(y,y2); int m=wx<wy?wx:wy;
float dx=wx/m,dy=wy/m;for(int
i=0;i<(int)m;i++)set_pixel(x+=dx,y+=dy,color);
}

thin skin

draw_line`x`y`x2`y2`color
{
`wx=dist x x2,`wy=dist y y2,`M=(wx<wy?wx!wy)
`dx=wx/m,`dy=wy/m, M'set_pixel x+=dx y+=dy color;
}
fir
2024-08-27 18:44:19 UTC
Permalink
Post by fir
Post by fir
Post by fir
Post by fir
Post by Lawrence D'Oliveiro
Post by fir
Post by Lawrence D'Oliveiro
Somehow along the line from BCPL to B to C, one useful feature was
lost: the ability to have a value-returning statement block inside an
expression.
if so thats probably sad, though i dont know how it looked like
The construct looks like
VALOF $( ... «stmts»; RESULTIS «return-value» $)
it is good to things return value and good to be able to combine it
as i sait for example i consider such loops
10'x //ten tiem execute x
print (10'x+=x)/10
would be equivalent of
for(int i=0; i<10; i++) x+=x;
print(x/10)
(and its still c, just with shorted syntax not python et sort)
as to this loop as i said i had no ide how to make indexes like i
in this form but what comes to my mind now is maybe something lika
10'print("x")
10i'print(i)
480y' 640x' set_pixel(x,y, 0xffff00)
those i,x,y in loop 'headers' could be possibly subscripted
like 2 in typical H20 (2 is subscripted
eventually one can go
10' print((x 0)++)
where x 0 is initialisation of int x to zero
overally not bad, i could somewhat accept that loop
(yu wouldnt belive how hard is come to that syntax conclusions,
literally takes years, and not 5 years more like 15)
i wanted to compore how many chars my thin c skin conventions would
make (but not having funic F for wloat or runic U for unsigned) i put `
and the spare is not great becouse c is quite thin - hovever it uses a
lot of what i call 'decorators i eman not necessary ().; which could
be changed to spaces, it not spares chars but somewhat spares ink
on fictional snippet (probebly not working)
void draw_line( float x, float y, float x2, float y2, unsigned color)
{
float
wx=dist(x,x2),wy=dist(y,y2); int m=wx<wy?wx:wy;
float dx=wx/m,dy=wy/m;for(int
i=0;i<(int)m;i++)set_pixel(x+=dx,y+=dy,color);
}
thin skin
draw_line`x`y`x2`y2`color
{
`wx=dist x x2,`wy=dist y y2,`M=(wx<wy?wx!wy)
`dx=wx/m,`dy=wy/m, M'set_pixel x+=dx y+=dy color;
}
though eventualy it canm be written shorter i guess

draw_line`x`y`x2`y2`color:
`m = min 'wx=abs x2-x 'wy=abs y2-y) ' set_pixel x+=wx/m y+=wy/m color;
;

not to say it lookin specially good but welll..
Bart
2024-08-27 18:59:13 UTC
Permalink
Post by fir
Post by fir
on fictional snippet (probebly not working)
void draw_line( float x, float y, float x2, float y2, unsigned color)
{
     float
      wx=dist(x,x2),wy=dist(y,y2); int m=wx<wy?wx:wy;
      float dx=wx/m,dy=wy/m;for(int
i=0;i<(int)m;i++)set_pixel(x+=dx,y+=dy,color);
}
thin skin
draw_line`x`y`x2`y2`color
{
     `wx=dist x x2,`wy=dist y y2,`M=(wx<wy?wx!wy)
     `dx=wx/m,`dy=wy/m, M'set_pixel x+=dx y+=dy color;
}
though eventualy it canm be written shorter i guess
 `m = min 'wx=abs x2-x 'wy=abs y2-y) ' set_pixel x+=wx/m y+=wy/m color;
 ;
not to say it lookin specially good but welll..
There are ways to have more compact syntax without it turning weird,
leaving out types, and using backtick separators and other strange
punctuation (or is that lone ')' a typo?).

Start with this version:

void draw_line( float x, float y, float x2, float y2, unsigned color)
{
float
wx=dist(x,x2),wy=dist(y,y2); int m=wx<wy?wx:wy;
float
dx=wx/m,dy=wy/m;for(inti=0;i<(int)m;i++)set_pixel(x+=dx,y+=dy,color);
}

For example:

void draw_line(f32 x, y, x2, y2; u32 colour) {
f32 wx = dist(x, y2), wy = dist(y, y2)
int m = min(wx, wy)
repeat m {
set_pixel(x += wx/m, y += wy/m, colour)
}
}

Summary:

- Allow shared types in parameter lists
- Auto semicolon insertion
- Built-in 'min/max' operators
- New repeat-n-times loop
- Shorter type names
fir
2024-08-27 19:36:05 UTC
Permalink
Post by Bart
Post by fir
Post by fir
on fictional snippet (probebly not working)
void draw_line( float x, float y, float x2, float y2, unsigned color)
{
float
wx=dist(x,x2),wy=dist(y,y2); int m=wx<wy?wx:wy;
float dx=wx/m,dy=wy/m;for(int
i=0;i<(int)m;i++)set_pixel(x+=dx,y+=dy,color);
}
thin skin
draw_line`x`y`x2`y2`color
{
`wx=dist x x2,`wy=dist y y2,`M=(wx<wy?wx!wy)
`dx=wx/m,`dy=wy/m, M'set_pixel x+=dx y+=dy color;
}
though eventualy it canm be written shorter i guess
`m = min 'wx=abs x2-x 'wy=abs y2-y) ' set_pixel x+=wx/m y+=wy/m color;
;
not to say it lookin specially good but welll..
There are ways to have more compact syntax without it turning weird,
leaving out types, and using backtick separators and other strange
punctuation (or is that lone ')' a typo?).
void draw_line( float x, float y, float x2, float y2, unsigned color)
{
float
wx=dist(x,x2),wy=dist(y,y2); int m=wx<wy?wx:wy;
float
dx=wx/m,dy=wy/m;for(inti=0;i<(int)m;i++)set_pixel(x+=dx,y+=dy,color);
}
void draw_line(f32 x, y, x2, y2; u32 colour) {
f32 wx = dist(x, y2), wy = dist(y, y2)
int m = min(wx, wy)
repeat m {
set_pixel(x += wx/m, y += wy/m, colour)
}
}
- Allow shared types in parameter lists
- Auto semicolon insertion
- Built-in 'min/max' operators
- New repeat-n-times loop
- Shorter type names
yes there were typos and mistakes
its more like

draw_line`x1`y1`x2`y2`color:
`m = min abs x2-x1 abs y2-y1 ' set_pixel x1+=(x2-x1)/m y1+=(y2-y1)/m
color;
;

with some 'cheats as i both float and unsigned gere note by ` but ascii
has to narow charset amd i dont know unicode enough (though probably i
could look into unicode and chose some

• draw_line`x1`y1`x2`y2`color:
`m= x2‾x1 ˩ y2‾y1 ' set_pixel x1+=(x2-x1)/m y1+=(y2-y1)/m color;

fir
2024-08-27 20:02:15 UTC
Permalink
Post by fir
Post by Bart
Post by fir
Post by fir
on fictional snippet (probebly not working)
void draw_line( float x, float y, float x2, float y2, unsigned color)
{
float
wx=dist(x,x2),wy=dist(y,y2); int m=wx<wy?wx:wy;
float dx=wx/m,dy=wy/m;for(int
i=0;i<(int)m;i++)set_pixel(x+=dx,y+=dy,color);
}
thin skin
draw_line`x`y`x2`y2`color
{
`wx=dist x x2,`wy=dist y y2,`M=(wx<wy?wx!wy)
`dx=wx/m,`dy=wy/m, M'set_pixel x+=dx y+=dy color;
}
though eventualy it canm be written shorter i guess
`m = min 'wx=abs x2-x 'wy=abs y2-y) ' set_pixel x+=wx/m y+=wy/m color;
;
not to say it lookin specially good but welll..
There are ways to have more compact syntax without it turning weird,
leaving out types, and using backtick separators and other strange
punctuation (or is that lone ')' a typo?).
void draw_line( float x, float y, float x2, float y2, unsigned color)
{
float
wx=dist(x,x2),wy=dist(y,y2); int m=wx<wy?wx:wy;
float
dx=wx/m,dy=wy/m;for(inti=0;i<(int)m;i++)set_pixel(x+=dx,y+=dy,color);
}
void draw_line(f32 x, y, x2, y2; u32 colour) {
f32 wx = dist(x, y2), wy = dist(y, y2)
int m = min(wx, wy)
repeat m {
set_pixel(x += wx/m, y += wy/m, colour)
}
}
- Allow shared types in parameter lists
- Auto semicolon insertion
- Built-in 'min/max' operators
- New repeat-n-times loop
- Shorter type names
yes there were typos and mistakes
its more like
`m = min abs x2-x1 abs y2-y1 ' set_pixel x1+=(x2-x1)/m y1+=(y2-y1)/m
color;
;
with some 'cheats as i both float and unsigned gere note by ` but ascii
has to narow charset amd i dont know unicode enough (though probably i
could look into unicode and chose some
`m= x2‾x1 ˩ y2‾y1 ' set_pixel x1+=(x2-x1)/m y1+=(y2-y1)/m color;

there are some unicode characters that could be handy for example this
bullet ••••• above is good
this ˩ ˩ ˩ ˩ ˩ is also ok ...i would need probably to chose somethink
like 20-30 potentially best to add - but today my eyesight quite bad so
some other day
fir
2024-08-27 21:42:19 UTC
Permalink
Post by fir
Post by fir
Post by Bart
Post by fir
Post by fir
on fictional snippet (probebly not working)
void draw_line( float x, float y, float x2, float y2, unsigned color)
{
float
wx=dist(x,x2),wy=dist(y,y2); int m=wx<wy?wx:wy;
float dx=wx/m,dy=wy/m;for(int
i=0;i<(int)m;i++)set_pixel(x+=dx,y+=dy,color);
}
thin skin
draw_line`x`y`x2`y2`color
{
`wx=dist x x2,`wy=dist y y2,`M=(wx<wy?wx!wy)
`dx=wx/m,`dy=wy/m, M'set_pixel x+=dx y+=dy color;
}
though eventualy it canm be written shorter i guess
`m = min 'wx=abs x2-x 'wy=abs y2-y) ' set_pixel x+=wx/m y+=wy/m color;
;
not to say it lookin specially good but welll..
There are ways to have more compact syntax without it turning weird,
leaving out types, and using backtick separators and other strange
punctuation (or is that lone ')' a typo?).
void draw_line( float x, float y, float x2, float y2, unsigned color)
{
float
wx=dist(x,x2),wy=dist(y,y2); int m=wx<wy?wx:wy;
float
dx=wx/m,dy=wy/m;for(inti=0;i<(int)m;i++)set_pixel(x+=dx,y+=dy,color);
}
void draw_line(f32 x, y, x2, y2; u32 colour) {
f32 wx = dist(x, y2), wy = dist(y, y2)
int m = min(wx, wy)
repeat m {
set_pixel(x += wx/m, y += wy/m, colour)
}
}
- Allow shared types in parameter lists
- Auto semicolon insertion
- Built-in 'min/max' operators
- New repeat-n-times loop
- Shorter type names
yes there were typos and mistakes
its more like
`m = min abs x2-x1 abs y2-y1 ' set_pixel x1+=(x2-x1)/m y1+=(y2-y1)/m
color;
;
with some 'cheats as i both float and unsigned gere note by ` but ascii
has to narow charset amd i dont know unicode enough (though probably i
could look into unicode and chose some
`m= x2‾x1 ˩ y2‾y1 ' set_pixel x1+=(x2-x1)/m y1+=(y2-y1)/m color;

there are some unicode characters that could be handy for example this
bullet ••••• above is good
this ˩ ˩ ˩ ˩ ˩ is also ok ...i would need probably to chose somethink
like 20-30 potentially best to add - but today my eyesight quite bad so
some other day
some probably most suitable to use


¡¦¨«¬¯°±²³´¶·¸¹º»¿¼½¾ª§ˆˇˉ˘˙˙˚˚˛˜˝;΄΅΄΅·ψ–――‗‘’‚“”„†‡•…‰‹›‼‾⁄ⁿ←↑→↓↔↕↨∆∂∏∑−∙√∞∟∩∫≈≠≡≤≥⌂⌐⌠⌡─░▒▓■▬▲►▼◄◊○◘◙☺☻☼♀♂♠♣♥♦♪♫
Lawrence D'Oliveiro
2024-09-02 03:32:43 UTC
Permalink
Post by Bart
void draw_line(f32 x, y, x2, y2; u32 colour) {
- Allow shared types in parameter lists ...
A bit easier if you flip it around and use Pascal-style syntax:

procedure draw_line(x, y, x2, y2 : f32; colour : u32)

See how much more natural that is?
Bart
2024-09-02 09:53:33 UTC
Permalink
Post by Lawrence D'Oliveiro
Post by Bart
void draw_line(f32 x, y, x2, y2; u32 colour) {
- Allow shared types in parameter lists ...
procedure draw_line(x, y, x2, y2 : f32; colour : u32)
See how much more natural that is?
It becomes a bit less natural when you want to initialise a variable at
the same time, or want define a default value for a parameter.

Pascal didn't allow either of those. Current languages that use 'var
x:T' style tend to put such an expression after the type: 'var x:T = expr'.

That's ugly and unwieldy (with the type spec slap in the middle),
becoming even more so when declaring several variables with the same
type: where do those expressions go?
Kaz Kylheku
2024-09-03 06:12:31 UTC
Permalink
Post by Bart
Post by Lawrence D'Oliveiro
Post by Bart
void draw_line(f32 x, y, x2, y2; u32 colour) {
- Allow shared types in parameter lists ...
procedure draw_line(x, y, x2, y2 : f32; colour : u32)
See how much more natural that is?
It becomes a bit less natural when you want to initialise a variable at
the same time, or want define a default value for a parameter.
Pascal didn't allow either of those.
Ada does, with a very natural extension of the same syntax. Even allows
passing arguments by keyword, too.
Twit boy, "natural", in the context of languages, refers to some
combination of "extremely complicated, haphazardly evolved,
undocumented, incompletely understood, and full of ambiguities
and shifting contexts leading to miscommunication".

You don't want any whiff of the natural in any artificial language
used in computing.
--
TXR Programming Language: http://nongnu.org/txr
Cygnal: Cygwin Native Application Library: http://kylheku.com/cygnal
Mastodon: @***@mstdn.ca
Lawrence D'Oliveiro
2024-09-03 04:54:10 UTC
Permalink
Post by Bart
Post by Lawrence D'Oliveiro
Post by Bart
void draw_line(f32 x, y, x2, y2; u32 colour) {
- Allow shared types in parameter lists ...
procedure draw_line(x, y, x2, y2 : f32; colour : u32)
See how much more natural that is?
It becomes a bit less natural when you want to initialise a variable at
the same time, or want define a default value for a parameter.
Pascal didn't allow either of those.
Ada does, with a very natural extension of the same syntax. Even allows
passing arguments by keyword, too.

Note that even C++ has now had to allow function return types to be
specified at the end of the prototype instead of up front, because type
interdependencies don’t work very well otherwise.
Michael S
2024-09-03 09:20:04 UTC
Permalink
On Tue, 3 Sep 2024 04:54:10 -0000 (UTC)
Post by Bart
Post by Lawrence D'Oliveiro
Post by Bart
void draw_line(f32 x, y, x2, y2; u32 colour) {
- Allow shared types in parameter lists ...
procedure draw_line(x, y, x2, y2 : f32; colour : u32)
See how much more natural that is?
It becomes a bit less natural when you want to initialise a
variable at the same time, or want define a default value for a
parameter.
Pascal didn't allow either of those.
Ada does, with a very natural extension of the same syntax.
I didn't write Ada program for many years (although probably for less
years than you), but I regularly write VHDL, which syntax is heavily
inspired by Ada. My experience with it can in short be summarized as
"Bart is correct".
VHDL declaration + initialization syntax works not too badly as long as
you want to declare one signal (or constant or variable). It does not
work when you try to combine declaration of two signals of the same
type. It's so unnatural that I don't even know if it's at all allowed.

Now, Bart seems to think that ability to combine several declarations of
the same type is important. Here I disagree. At best, it's occasionally
nice.
Even
allows passing arguments by keyword, too.
By keyword? Do you mean call with named parameters association?
Note that even C++ has now had to allow function return types to be
specified at the end of the prototype instead of up front, because
type interdependencies don’t work very well otherwise.
Likely happened after I stopped following.

fir
2024-08-27 19:09:19 UTC
Permalink
Post by fir
Post by fir
Post by fir
Post by fir
Post by fir
Post by Lawrence D'Oliveiro
Post by fir
Post by Lawrence D'Oliveiro
Somehow along the line from BCPL to B to C, one useful feature was
lost: the ability to have a value-returning statement block inside an
expression.
if so thats probably sad, though i dont know how it looked like
The construct looks like
VALOF $( ... «stmts»; RESULTIS «return-value» $)
it is good to things return value and good to be able to combine it
as i sait for example i consider such loops
10'x //ten tiem execute x
print (10'x+=x)/10
would be equivalent of
for(int i=0; i<10; i++) x+=x;
print(x/10)
(and its still c, just with shorted syntax not python et sort)
as to this loop as i said i had no ide how to make indexes like i
in this form but what comes to my mind now is maybe something lika
10'print("x")
10i'print(i)
480y' 640x' set_pixel(x,y, 0xffff00)
those i,x,y in loop 'headers' could be possibly subscripted
like 2 in typical H20 (2 is subscripted
eventually one can go
10' print((x 0)++)
where x 0 is initialisation of int x to zero
overally not bad, i could somewhat accept that loop
(yu wouldnt belive how hard is come to that syntax conclusions,
literally takes years, and not 5 years more like 15)
i wanted to compore how many chars my thin c skin conventions would
make (but not having funic F for wloat or runic U for unsigned) i put `
and the spare is not great becouse c is quite thin - hovever it uses a
lot of what i call 'decorators i eman not necessary ().; which could
be changed to spaces, it not spares chars but somewhat spares ink
on fictional snippet (probebly not working)
void draw_line( float x, float y, float x2, float y2, unsigned color)
{
float
wx=dist(x,x2),wy=dist(y,y2); int m=wx<wy?wx:wy;
float dx=wx/m,dy=wy/m;for(int
i=0;i<(int)m;i++)set_pixel(x+=dx,y+=dy,color);
}
thin skin
draw_line`x`y`x2`y2`color
{
`wx=dist x x2,`wy=dist y y2,`M=(wx<wy?wx!wy)
`dx=wx/m,`dy=wy/m, M'set_pixel x+=dx y+=dy color;
}
though eventualy it canm be written shorter i guess
`m = min 'wx=abs x2-x 'wy=abs y2-y) ' set_pixel x+=wx/m y+=wy/m color;
;
not to say it lookin specially good but welll..
well in fact it maybe could be more like

draw_line`x1`y1`x2`y2`color:
`m = min abs x2-x1 abs y2-y1 ' set_pixel x1+=(x2-x1)/m y1+=(y2-y1)/m
color;
fir
2024-08-29 07:24:53 UTC
Permalink
Post by fir
on fictional snippet (probebly not working)
void draw_line( float x, float y, float x2, float y2, unsigned color)
{
float
wx=dist(x,x2),wy=dist(y,y2); int m=wx<wy?wx:wy;
float dx=wx/m,dy=wy/m;for(int
i=0;i<(int)m;i++)set_pixel(x+=dx,y+=dy,color);
}
i thought on it yet and concluded code for that shopuld look more like

point {ints x y}
line {points p q}
draw line(color c)
{
point a = p
int m = max abs(q-p) ' a+=(q-p)/m, Setpixel a, c
}


explanation:

point {ints x y}

this is structure "point" definition ,
ints is int[] but it also has named elements so int[0[ is x and int[1]
is y (such is very handy as structure may be seen as array and array as
structure.. so more fractal touch added (if it is proper name fractal
touch as maybe not im not sure)

line {points p q}

same this is structure named "line" defined

draw line(color c)

this is function header though line here is a type so its
a bit new in that aspect possibly

point a = p

instantiates point structure entity named a and copies p into it

as p is point in line and p is int2 type and int2 has defined assigning
to other int2 so this is automatic

int m = max abs(q-p)

same here q-p are int2 - int2 they are defined to retuirn int2
abs is defined on int2 to return two int2 values then max is defined
on int2 to return one int

m' is loop (loop m times)
this a+=(q-p)/m, is calculation, i know it will not work as
it shopuld work on floats but for simplicity of example as i was thinkin
on ints i will stay it with ints

overally this is kinda closer to C2 syntax i need
fir
2024-08-29 07:37:11 UTC
Permalink
Post by fir
Post by fir
on fictional snippet (probebly not working)
void draw_line( float x, float y, float x2, float y2, unsigned color)
{
float
wx=dist(x,x2),wy=dist(y,y2); int m=wx<wy?wx:wy;
float dx=wx/m,dy=wy/m;for(int
i=0;i<(int)m;i++)set_pixel(x+=dx,y+=dy,color);
}
i thought on it yet and concluded code for that shopuld look more like
point {ints x y}
line {points p q}
draw line(color c)
{
point a = p
int m = max abs(q-p) ' a+=(q-p)/m, Setpixel a, c
}
point {ints x y}
this is structure "point" definition ,
ints is int[] but it also has named elements so int[0[ is x and int[1]
is y (such is very handy as structure may be seen as array and array as
structure.. so more fractal touch added (if it is proper name fractal
touch as maybe not im not sure)
i noticed it today that

int a,b,c

in old c is wrong it should be ints

ints a b c

moreover as obave written the acces shpould be by fielda but also array way

here this a b c is like nonamed structure so you cant acces it array way
but put it into name

point {ints a b c}

and then you can acces both ways
Post by fir
line {points p q}
same this is structure named "line" defined
draw line(color c)
this is function header though line here is a type so its
a bit new in that aspect possibly
point a = p
instantiates point structure entity named a and copies p into it
as p is point in line and p is int2 type and int2 has defined assigning
to other int2 so this is automatic
int m = max abs(q-p)
same here q-p are int2 - int2 they are defined to retuirn int2
abs is defined on int2 to return two int2 values then max is defined
on int2 to return one int
m' is loop (loop m times)
this a+=(q-p)/m, is calculation, i know it will not work as
it shopuld work on floats but for simplicity of example as i was thinkin
on ints i will stay it with ints
overally this is kinda closer to C2 syntax i need
Lawrence D'Oliveiro
2024-09-03 04:56:27 UTC
Permalink
draw_line`x`y`x2`y2`color {
It’s quite clunky to have to specify x- and y-coordinates separately,
instead of being able to construct and pass a single “vector” value.

Similarly, it is handy to have a “colour” type, which can specify the
parameters in various spaces, not just RGB.
Blue-Maned_Hawk
2024-08-27 12:28:51 UTC
Permalink
Post by Lawrence D'Oliveiro
Post by fir
Post by Lawrence D'Oliveiro
Somehow along the line from BCPL to B to C, one useful feature was
lost: the ability to have a value-returning statement block inside an
expression.
if so thats probably sad, though i dont know how it looked like
The construct looks like
VALOF $( ... «stmts»; RESULTIS «return-value» $)
So a la GNUC's statement-expressions? I've heard talks that C2y is likely
to be the revision that adds lambdas to C¹, so perhaps we'll get it back…
over half a century later.



¹In addition to subsuming statement-expressions, this would also subsume
multiple other extensions, particularly GCC's local functions and Clang's
Blocks.
--
Blue-Maned_Hawk│shortens to Hawk│/blu.mɛin.dʰak/│he/him/his/himself/Mr.
blue-maned_hawk.srht.site
BSD made an attempt to standardize this. It didn't work.
Tim Rentsch
2024-08-28 01:45:46 UTC
Permalink
Post by Blue-Maned_Hawk
Post by Lawrence D'Oliveiro
Post by fir
Post by Lawrence D'Oliveiro
Somehow along the line from BCPL to B to C, one useful feature was
lost: the ability to have a value-returning statement block inside an
expression.
if so thats probably sad, though i dont know how it looked like
The construct looks like
VALOF $( ... <<stmts>>; RESULTIS <<return-value>> $)
So a la GNUC's statement-expressions? I've heard talks that C2y is likely
to be the revision that adds lambdas to C[1], so perhaps we'll get it back?
over half a century later.
?
[1]In addition to subsuming statement-expressions, this would also subsume
multiple other extensions, particularly GCC's local functions and Clang's
Blocks.
Not exactly. There are things that can be done inside a
statement-expression that are not available inside nested
functions or lambdas.
Keith Thompson
2024-08-28 02:23:10 UTC
Permalink
Tim Rentsch <***@z991.linuxsc.com> writes:
[...]
Post by Tim Rentsch
Not exactly. There are things that can be done inside a
statement-expression that are not available inside nested
functions or lambdas.
And you're not going to tell us what those things are.
--
Keith Thompson (The_Other_Keith) Keith.S.Thompson+***@gmail.com
void Void(void) { Void(); } /* The recursive call of the void */
Ben Bacarisse
2024-08-28 14:28:14 UTC
Permalink
Post by Keith Thompson
[...]
Post by Tim Rentsch
Not exactly. There are things that can be done inside a
statement-expression that are not available inside nested
functions or lambdas.
And you're not going to tell us what those things are.
Apparently not.

But one thing occurs to me... you can break (or jump) out of a statement
expression:

for (int i = 0; i < 10; i++)
printf("%d\n", ({ if (i > 5) break; i; }));

You can't do this with a lambda or nested function.
--
Ben.
Tim Rentsch
2024-08-28 15:37:35 UTC
Permalink
Post by Ben Bacarisse
Post by Keith Thompson
[...]
Post by Tim Rentsch
Not exactly. There are things that can be done inside a
statement-expression that are not available inside nested
functions or lambdas.
And you're not going to tell us what those things are.
Apparently not.
But one thing occurs to me... you can break (or jump) out of a statement
for (int i = 0; i < 10; i++)
printf("%d\n", ({ if (i > 5) break; i; }));
You can't do this with a lambda or nested function.
Right. More generally, control transfers to outside the scope of
a statement-expression are allowed. That includes break, continue,
goto, and importantly return, which returns from the function
containing the statement-expression.
Tim Rentsch
2024-08-28 15:22:05 UTC
Permalink
Post by Keith Thompson
[...]
Post by Tim Rentsch
Not exactly. There are things that can be done inside a
statement-expression that are not available inside nested
functions or lambdas.
And you're not going to tell us what those things are.
As a rule I don't have a lot of sympathy for people who are
too lazy to think for themselves. I'm sorry to say that
class includes you a lot more often than would appear to be
warrented.
Keith Thompson
2024-08-28 20:06:07 UTC
Permalink
Post by Tim Rentsch
Post by Keith Thompson
[...]
Post by Tim Rentsch
Not exactly. There are things that can be done inside a
statement-expression that are not available inside nested
functions or lambdas.
And you're not going to tell us what those things are.
As a rule I don't have a lot of sympathy for people who are
too lazy to think for themselves. I'm sorry to say that
class includes you a lot more often than would appear to be
warrented.
You seem not to be aware of how you come across.

Things like this make you appear arrogant. You repeatedly make terse
and subtle statements (which are often, but not always, correct) that
would be trivial for you to expand on when you make them. Instead, you
in effect assign homework to the rest of us.

It turns out that it's possible to jump out of a statement expression.
It was not obvious that that's permitted. I very rarely use statement
expressions (among other things, they're non-standard), so I haven't
studied them in any detail. But you expect me to think for myself and
infer that *obviously* they can be used that way. I don't know how long
it would have taken me to figure that out if I had been motivated to
spend the time on it (it is mentioned in gcc's documentation) , but I'm
reasonably sure it would not have been worth the effort. And it would
not have surprised me if gcc prohibited jumping out of a statement
expression.

I see from the rest of this thread that I'm not the only one who feels
this way. Consider the possibility that the problem is not with
everyone else.
--
Keith Thompson (The_Other_Keith) Keith.S.Thompson+***@gmail.com
void Void(void) { Void(); } /* The recursive call of the void */
Tim Rentsch
2024-08-28 16:31:56 UTC
Permalink
Post by Keith Thompson
[...]
Post by Tim Rentsch
Not exactly. There are things that can be done inside a
statement-expression that are not available inside nested
functions or lambdas.
And you're not going to tell us what those things are.
Let me add something to my last response. I think you're doing
a disservice to the community by always explaining everything
in great detail. Sometimes, sure; perhaps even mostly. But
not always. People need to learn to think. You must have heard
the proverb about giving a man a fish versus teaching a man to
fish. You just keep doling out fish. I want people to learn to
think so they can fish for themselves.

One difference between you and me is that I almost never respond
to a posting of yours that is part of a conversation with someone
else to complain about your answer. And I don't engage in such
behavior even though I think that what you're doing is worse than
what I'm doing. I'm fed up with your high and mighty attitude.
David Brown
2024-08-28 17:39:18 UTC
Permalink
Post by Tim Rentsch
Post by Keith Thompson
[...]
Post by Tim Rentsch
Not exactly. There are things that can be done inside a
statement-expression that are not available inside nested
functions or lambdas.
And you're not going to tell us what those things are.
Let me add something to my last response. I think you're doing
a disservice to the community by always explaining everything
in great detail. Sometimes, sure; perhaps even mostly. But
not always. People need to learn to think. You must have heard
the proverb about giving a man a fish versus teaching a man to
fish. You just keep doling out fish. I want people to learn to
think so they can fish for themselves.
As someone who has learned a lot over the years from people in this
group, I think /you/ are doing the disservice with your patronising
attitude and your treatment of everyone else as though they were your
first-year students trying to cheat on their homework. And it is made
hugely worse by your habit of posting a teaser then disappearing for a
month or more before dragging up old threads that everyone else has put
aside.

Remember, this is comp.lang.c - it is /not/ help.me.learn.to.learn.

Keith answers people's questions, and gives constructive help. When
people want to learn more and think deeper, he is happy to encourage
that - questioning their assumptions or giving more information. But I
don't think Keith needs me defending him here - his reputation in this
group is outstanding with pretty much every regular.

You are possibly the regular in this group with the most technical
knowledge of C, its standards and its history. But in term of helping
people, you are frustratingly poor. If your aim is to encourage people
to think and learn for themselves, you are regularly a failure. If your
aim is to make people think you are a self-righteous prick, you have
done a much better job.
Post by Tim Rentsch
One difference between you and me is that I almost never respond
to a posting of yours that is part of a conversation with someone
else to complain about your answer. And I don't engage in such
behavior even though I think that what you're doing is worse than
what I'm doing. I'm fed up with your high and mighty attitude.
The irony of that last sentence is incredible. With your negligible
level of self-awareness, you should give up programming and enter politics.
James Kuyper
2024-08-28 18:34:24 UTC
Permalink
Post by Tim Rentsch
Post by Keith Thompson
[...]
Post by Tim Rentsch
Not exactly. There are things that can be done inside a
statement-expression that are not available inside nested
functions or lambdas.
And you're not going to tell us what those things are.
Let me add something to my last response. I think you're doing
a disservice to the community by always explaining everything
in great detail. Sometimes, sure; perhaps even mostly. But
not always. People need to learn to think. You must have heard
the proverb about giving a man a fish versus teaching a man to
fish. You just keep doling out fish. I want people to learn to
think so they can fish for themselves.
You don't teach people to fish - you tell them: "There's fish out there
somewhere, figure out for yourself where they are and how to catch them."

On those rare occasions when you've revealed what it is you were talking
about, it has often been something that I would never have figured out,
no matter how much time I spent thinking about it, because figuring it
out would have required me to think in a way that I considered
incorrect. I might have been wrong to think that, but I could not have
discovered my error without you explaining yourself, which you routinely
fail to do

Refusing to explain yourself also serves to shield you from criticism
that your explanation is incorrect, and I think that is it's main
benefit to you. My suspicion that your reasons are incorrect is the
thing that makes it so frustrating to me when you refuse to provide them.
Post by Tim Rentsch
One difference between you and me is that I almost never respond
to a posting of yours that is part of a conversation with someone
else to complain about your answer. And I don't engage in such
behavior even though I think that what you're doing is worse than
what I'm doing. I'm fed up with your high and mighty attitude.
Keith's criticisms of your comments seem unlikely to ever produce an
improvement in your behavior, because you clearly don't see it as
needing improvement. However, they do serve to warn other, less
knowledgeable people that they are not as stupid as you try to make them
think they are - your answers are in fact just as incomplete and
unhelpful as they naively appear to be.
Keith Thompson
2024-08-28 20:06:55 UTC
Permalink
Tim Rentsch <***@z991.linuxsc.com> writes:
[...]
Post by Tim Rentsch
I'm fed up with your high and mighty attitude.
Funny.
--
Keith Thompson (The_Other_Keith) Keith.S.Thompson+***@gmail.com
void Void(void) { Void(); } /* The recursive call of the void */
Loading...