Path: ...!eternal-september.org!feeder3.eternal-september.org!news.eternal-september.org!.POSTED!not-for-mail From: BGB Newsgroups: comp.lang.c Subject: =?UTF-8?Q?Re=3A_technology_discussion_=E2=86=92_does_the_world_need?= =?UTF-8?B?IGEgIm5ldyIgQyA/?= Date: Thu, 11 Jul 2024 15:19:32 -0500 Organization: A noiseless patient Spider Lines: 85 Message-ID: References: <87h6d2uox5.fsf@nosuchdomain.example.com> <20240707164747.258@kylheku.com> <877cdur1z9.fsf@bsb.me.uk> <871q42qy33.fsf@bsb.me.uk> <87ed82p28y.fsf@bsb.me.uk> <87r0c1nzjj.fsf@bsb.me.uk> <86ikxd8czu.fsf@linuxsc.com> <20240710201454.0000527e@yahoo.com> <86wmls6n7n.fsf@linuxsc.com> MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 7bit Injection-Date: Thu, 11 Jul 2024 22:19:33 +0200 (CEST) Injection-Info: dont-email.me; posting-host="27003a1dc60b83723a1f6e7c0bda37f7"; logging-data="2750052"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX19Mw+KFyEDzERFmJjNAgui695nHeZYtXEU=" User-Agent: Mozilla Thunderbird Cancel-Lock: sha1:MNvUpFaHpRg+GH1qEsBxW6nPOsw= Content-Language: en-US In-Reply-To: <86wmls6n7n.fsf@linuxsc.com> Bytes: 5412 On 7/11/2024 9:02 AM, Tim Rentsch wrote: > Michael S writes: > >> On Wed, 10 Jul 2024 08:48:05 -0700 >> Tim Rentsch wrote: >> >>> bart writes: >>> >>>> I earlier asked this: >>>> >>>> "So if arrays aren't passed by value in C, and they aren't passed >>>> by reference, then how the hell ARE they passed?!" >>> >>> They aren't. C allows lots of things to be passed as an argument >>> to a function: several varieties of numeric values, structs, >>> unions, and pointers, including both pointers to object types and >>> pointers to function types. C does not have a way for a function >>> to take an argument that is either an array or a function. There >>> is a way to take pointers to those things, but not the things >>> themselves. Arrays and functions are second-class values in C. >> >> I'd like to see an example of the language that permits ahead-of-time >> compilation and has functions as first-class values. > > C is almost that language. Pointers to functions are first class > in C. If for every C function definition a pattern like this: > > static int > foo_implementation( int x ){ > return x > 0 ? -x : x; > } > > int (*foo)( int ) = foo_implementation; > > is used, and there are no other references to the _implementation > names, then "functions" like foo() are essentially first-class > functions. The "function" foo can be assigned into. It can be > called just like an actual C function. The type of a "function" > is not like an actual function type, and so for example how the > address-of operator works is different for "functions" than it is > for actual C functions. Also pre-declarations for "functions" > obviously need to be different than they would be for actual C > functions. If the necessary adjustments are made, we would have > a language with first-class "functions". > > Incidentally, whether a language has closures is orthogonal to > the question of whether functions are first class. Closures > might or might not be interoperable with functions (they are > in some languages, and not in others). But that needn't have > any bearing on whether functions (or closures) are first class. > > Note: strictly speaking a closure is a run-time value, not a > compile-time definition. I trust my readers are able to make > the needed linguistic accommodations. FWIW, there was a proposal to add C++ style lambdas to C23, but apparently didn't get in. I had added them though because my compiler had already had support for lambdas, albeit with a different syntax (and initially mostly for the other languages my compiler supports). The variant I added had re-added some features slightly closer to the C++ version though, being able to capture both by value and by reference, although with slightly different behaviors depending on these cases: No capture, behaves like an anonymous function, unbounded lifetime; Capture by reference, automatic lifetime only; Capture by value, unbounded lifetime, heap allocated. Mixed usage will behave as the by-reference case. In the latter cases, the lambda still results in an otherwise normal seeming function pointer; in the latter cases as a thunk located in a RWX (Read/Write/Execute) memory allocation (which loads its own address into a register and branches to the entry point of the function proper). The by-value capture case may be freed using "free()", but otherwise creating lambdas and not freeing them will result in a memory leak (the former two cases may not be manually freed). ....