Deutsch   English   Français   Italiano  
<vgbut3$17gjk$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: Bart <bc@freeuk.com>
Newsgroups: comp.lang.c
Subject: Re: else ladders practice
Date: Tue, 5 Nov 2024 02:11:46 +0000
Organization: A noiseless patient Spider
Lines: 118
Message-ID: <vgbut3$17gjk$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> <vgbfes$14km3$1@dont-email.me>
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8; format=flowed
Content-Transfer-Encoding: 8bit
Injection-Date: Tue, 05 Nov 2024 03:11:48 +0100 (CET)
Injection-Info: dont-email.me; posting-host="cf8ab2f706c64865e8fbf40d9cba7390";
	logging-data="1294964"; mail-complaints-to="abuse@eternal-september.org";	posting-account="U2FsdGVkX18p2Oy4dcVXYxpqTTVc7uWd"
User-Agent: Mozilla Thunderbird
Cancel-Lock: sha1:oVwPqZFkaJV1wwLDo4wGCeoJMEI=
Content-Language: en-GB
In-Reply-To: <vgbfes$14km3$1@dont-email.me>
Bytes: 6611

On 04/11/2024 21:48, David Brown wrote:
> On 04/11/2024 20:50, Bart wrote:
>> On 04/11/2024 16:35, David Brown wrote:
>>> On 03/11/2024 21:00, Bart wrote:
>>
>>> To my mind, this is a type of "multi-way selection" :
>>>
>>>      (const int []){ a, b, c }[n];
>>>
>>> I can't see any good reason to exclude it as fitting the descriptive 
>>> phrase.
>>
>>
>>> And if "a", "b" and "c" are not constant, but require evaluation of 
>>> some sort, it does not change things.  Of course if these required 
>>> significant effort to evaluate,
>>
>> Or you had a hundred of them.
>>
>>> or had side-effects, then you would most likely want a "multi-way 
>>> selection" construction that did the selection first, then the 
>>> evaluation - but that's a matter of programmer choice, and does not 
>>> change the terms.
>>
>>
>> You still don't get how different the concepts are.
> 
> Yes, I do.  I also understand how they are sometimes exactly the same 
> thing, depending on the language, and how they can often have the same 
> end result, depending on the details, and how they can often be 
> different, especially in the face of side-effects or efficiency concerns.
> 
> Look, it's really /very/ simple.
> 
> A) You can have a construct that says "choose one of these N things to 
> execute and evaluate, and return that value (if any)".
> 
> B) You can have a construct that says "here are N things, select one of 
> them to return as a value".
> 
> Both of these can reasonably be called "multi-way selection" constructs. 
>   Some languages can have one as a common construct, other languages may 
> have the other, and many support both in some way.  Pretty much any 
> language that allows the programmer to have control over execution order 
> will let you do both in some way, even if there is not a clear language 
> construct for it and you have to write it manually in code.
> 
> Mostly type A will be most efficient if there is a lot of effort 
> involved in putting together the things to select.  Type B is likely to 
> be most efficient if you already have the collection of things to choose 
> from (it can be as simple as an array lookup), if the creation of the 
> collection can be done in parallel (such as in some SIMD uses), or if 
> the cpu can generate them all before it has established the selection 
> index.
> 
> Sometimes type A will be the simplest and clearest in the code, 
> sometimes type B will be the simplest and clearest in the code.
> 
> Both of these constructs are "multi-way selections".
> 
> 
> Your mistake is in thinking that type A is all there is and all that 
> matters, possibly because you feel you have a better implementation for 
> it than C has.  (I think that you /do/ have a nicer switch than C, but 
> that does not justify limiting your thinking to it.)


You STILL don't get it. Suppose this wasn't about returning a value, but 
executing one piece of code from a conditional set of statements.

In C that might be using an if/else chain, or switch. Other languages 
might use a match statement.

Universally only one of those pieces of code will be evaluated. Unless 
you can point me to a language where, in IF C THEN A ELSE B, *both* A 
and B statements are executed.

Do you agree so far? If so call that Class I.

Do you also agree that languages have data stuctures, and those often 
have constructors that will build a data structure element by element? 
So all elements necessarily have to be evaluated. (Put aside selecting 
one for now; that is a separate matter).

Call that Class II.

What my languages do, is that ALL the constructs in Class I that are 
commonly used to execute one of N branches, can also return values. 
(Which can require each branch to yield a type compatible with all the 
others; another separate matter.)

Do you now see why it is senseless for my 'multi-way' selections to work 
any other way. It would mean that:

   x := if C then A else B fi

really could both evaluate A and B whatever the value of C! Whatever 
that IF construct does here, has to do the same even without that 'x :=' 
a the start.

Of course, I support the sorts of indexing, of an existing or 
just-created data structure, that belong in Class II.

Although it would not be particularly efficient to do this:

   (f1(), f2(), .... f100())[100]       # (1-based)

Since you will execute 100 functions rather than just one. But perhaps 
there is a good reason for it. In that is needed, then the construct exists.

Another diference between Class I (when used to yield values) and Class 
II, is that an out-of-bounds selector in Part II either yields a runtime 
error (or raises an exception), or may just go wrong in my lower-level 
language.

But in Class I, the selector is either range-checked or falls off the 
end of a test sequence, and a default value is provided.