Warning: mysqli::__construct(): (HY000/1203): User howardkn already has more than 'max_user_connections' active connections in D:\Inetpub\vhosts\howardknight.net\al.howardknight.net\includes\artfuncs.php on line 21
Failed to connect to MySQL: (1203) User howardkn already has more than 'max_user_connections' active connections
Warning: mysqli::query(): Couldn't fetch mysqli in D:\Inetpub\vhosts\howardknight.net\al.howardknight.net\index.php on line 66
Article <vgipiq$2nji2$1@dont-email.me>
Deutsch   English   Français   Italiano  
<vgipiq$2nji2$1@dont-email.me>

View for Bookmarking (what is this?)
Look up another Usenet article

Path: ...!eternal-september.org!feeder2.eternal-september.org!news.eternal-september.org!.POSTED!not-for-mail
From: David Brown <david.brown@hesbynett.no>
Newsgroups: comp.lang.c
Subject: Re: else ladders practice
Date: Thu, 7 Nov 2024 17:23:54 +0100
Organization: A noiseless patient Spider
Lines: 356
Message-ID: <vgipiq$2nji2$1@dont-email.me>
References: <3deb64c5b0ee344acd9fbaea1002baf7302c1e8f@i2pn2.org>
 <vg0t3j$2ruor$1@dont-email.me>
 <78eabb4054783e30968ae5ffafd6b4ff2e5a5f17@i2pn2.org>
 <vg2g37$37mh3$1@dont-email.me> <6724CFD2.4030607@grunge.pl>
 <vg2llt$38ons$1@dont-email.me>
 <2491a699388b5891a49ef960e1ad8bb689fdc2ed@i2pn2.org>
 <b681ee05856e165c26a5c29bf42a8d9d53843d6d@i2pn2.org>
 <vg2ttn$3a4lk$1@dont-email.me> <vg33gs$3b8n5$1@dont-email.me>
 <vg358c$3bk7t$1@dont-email.me> <vg37nr$3bo0c$1@dont-email.me>
 <vg3b98$3cc8q$1@dont-email.me> <vg5351$3pada$1@dont-email.me>
 <vg62vg$3uv02$1@dont-email.me> <vg8a84$euka$1@dont-email.me>
 <vg8koq$gpsg$1@dont-email.me> <vgat50$112jp$1@dont-email.me>
 <vgb8if$13ioj$1@dont-email.me> <vgbhkt$155v2$1@dont-email.me>
 <vgfv5l$25hs6$1@dont-email.me> <vgg337$26880$1@dont-email.me>
 <vgggj2$28fqj$1@dont-email.me>
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8; format=flowed
Content-Transfer-Encoding: 8bit
Injection-Date: Thu, 07 Nov 2024 17:23:54 +0100 (CET)
Injection-Info: dont-email.me; posting-host="a9e6cefa048fc48fbed7d05ba22cb56e";
	logging-data="2870850"; mail-complaints-to="abuse@eternal-september.org";	posting-account="U2FsdGVkX19Fo3be2K9NBZV7VdH66PeLMaJxY7eh3eg="
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101
 Thunderbird/102.11.0
Cancel-Lock: sha1:6+VIhupBUEG4X3YmpMCA0ZpNo1U=
Content-Language: en-GB
In-Reply-To: <vgggj2$28fqj$1@dont-email.me>
Bytes: 16660

On 06/11/2024 20:38, Bart wrote:
> On 06/11/2024 15:47, David Brown wrote:
>> On 06/11/2024 15:40, Bart wrote:
> 
>> There are irrelevant differences in syntax, which could easily 
>> disappear entirely if a language supported a default initialisation 
>> value when a return gives no explicit value.  (i.e., "T foo() { 
>> return; }; T x = foo();" could be treated in the same way as "T x;" in 
>> a static initialisation context.)
> 
> You wrote:
> 
>    T foo () {return;}        # definition?
> 
>    T x = foo();              # call?
> 
> I'm not quite sure what you're saying here. That a missing return value 
> in non-void function would default to all-zeros?
> 

It would not necessarily mean all zeros, but yes, that's the idea.  You 
could easily say that returning from a non-void function without an 
explicit value, or falling off the end of it, returned the default value 
for the type in the same sense as you can have a default initialisation 
of non-stack objects in a language.  (In C, this pretty much always 
means all zeros - in a more advanced language with object support, it 
would typically mean default construction.)

Equally, you could say that in a void function, "return x;" simply casts 
"x" to void - just like writing "x;" as a statement does.

I'm not suggesting that either of these things are a particularly good 
idea - I am merely saying that with a minor syntactic change to the 
language (your language, C, or anything similar) most of the rest of the 
differences between your "proc" and your "func" disappear.

All you are left with is that "func" can be used in an expression, and 
"proc" cannot.  For me, that is not sufficient reason to distinguish 
them as concepts.

> Maybe. A rather pointless feature just to avoid writing '0', and which 
> now introduces a new opportunity for a silent error (accidentally 
> forgetting a return value).
> 

Sure.  As I say, I don't think it is a particularly good idea - at 
least, not as an addition to C (or, presumably, your language).

> It's not quite the same as a static initialisiation, which is zeroed 
> when a program starts.
> 

Of course.  (Theoretically in C, pointers are initialised to null 
pointers which don't have to be all zeros.  But I don't know of any 
implementation which has something different.)  I was just using that to 
show how some languages - like C - have a default value available.

> 
>> Then you list some things that may or may not happen, which are of 
>> course totally irrelevant.  If you list the differences between bikes 
>> and cars, you don't include "some cars are red" and "bikes are 
>> unlikely to be blue".
> 
> Yes; if you're using a vehicle, or planning a journey or any related 
> thing, it helps to remember if it's a bike or a car! At least here you 
> acknowledge the difference.
> 

There's a difference between cars and bikes - not between procs and funcs.

Remember, if you are going to make such a distinction between two 
concepts, it has to be absolute - "likely" or "unlikely" does not help. 
You can't distinguish between your procs and funcs by looking at the 
existence of side-effects, since a code block that has side-effects 
might return a value or might not.  It's like looking at a vehicle and 
seeing that it is red - it won't tell you if it is a bike or a car.

This is why I say distinguishing between "func" and "proc" by your 
criteria - the existence or absence of a return type - gives no useful 
information to the programmer or the compiler that can't be equally well 
given by writing a return type of "void".

> But I guess you find those likely/unlikely macros of gcc pointless too. 

How is that even remotely relevant to the discussion?  (Not that gcc has 
macros by those names.)

> If I know something is a procedure, then I also know it is likely to 
> change global state, that I might need to deal with a return value, and 
> a bunch of other stuff.

That's useless information - both to the programmer, and to the 
compiler.  (I am never sure which viewpoint you are taking - it would be 
helpful if you were clear there.)  If the compiler /knows/ global state 
cannot be changed, and the function only uses data from its input 
values, then it can do a lot with that information - shuffling around 
calls, removing duplicates, pre-calculating constant data at compile 
time, or whatever.  Similarly, if the programmer /knows/ global state 
cannot be changed in a function, then that can make it easier to 
understand what is going on in the code, or what is going wrong in it.

But if you only know that it is /likely/ to be one thing or the other, 
you know nothing of use.

> 
> Boldly separating the two with either FUNC or PROC denotations I find 
> helps tremendously. YM-obviously-V, but you can't have a go at me for my 
> view.
> 

I can have a go at you for not thinking!  I believe that if you think 
more carefully about this, you will understand how little your 
distinction helps anyone.  You might find the distinction I made - 
between being allowed to interact with global state (a "procedure") and 
having no possibility of interacting with global state (a "function") - 
to be useful.  In my distinction, there is no grey area of "likely" or 
"unlikely" - it is absolute, and therefore gives potentially useful 
information.  Of course it is then up to you to decide if it is worth 
the effort or not.

Let me tempt you with this - whatever syntax or terms you use here, 
you'll be able to brag that it is nicer than C23's "[[unsequenced]]" 
attribute for pure functions!

> If I really found it a waste of time, the distinction would have been 
> dropped decades ago.
> 

Why?  Once you've put it in the language, there is no motivation to drop 
it.  Pascal has the same procedure / function distinction you do.  Just 
because it adds little of use to language, does not mean that you'd want 
to drop it and make your tools incompatible between language versions.

>> It's a pointless distinction.  Any function or procedure can be 
>> morphed into the other form without any difference in the semantic 
>> meaning of the code, requiring just a bit of re-arrangement at the 
>> caller site:
>>
>>      int foo(int x) { int y = ...; return y; }
>>
>>      void foo(int * res, int x) { int y = ...; *res = y; }
>>
>>
>>      void foo(int x) { ... ; return; }
>>
>>      int foo(int x) { ... ; return 0; }
>>
> 
>> There is no relevance in the division here, which is why most 
>> languages don't make a distinction unless they do so simply for 
>> syntactic reasons.
> 
> As I said, you like to mix things up. You disagreed. I'm not surprised.
> 
> Here you've demonstrated how a function that returns results by value 
> can be turned into a procedure that returns a result by reference.
> 
> So now, by-value and by-reference are the same thing?

Returning something from a function by returning a value, or by having 
the caller pass a pointer (or mutable reference, if you prefer that 
term) and having the function pass its results via that pointer are not 
really very different.  Sure, there are details of the syntax and the 
ABI that will differ, but not the meaning of the code.
========== REMAINDER OF ARTICLE TRUNCATED ==========