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 connectionsPath: ...!eternal-september.org!feeder3.eternal-september.org!news.eternal-september.org!.POSTED!not-for-mail From: Kaz Kylheku <643-408-1753@kylheku.com> Newsgroups: comp.lang.c Subject: Re: technology discussion =?UTF-8?Q?=E2=86=92?= does the world need a "new" C ? Date: Thu, 11 Jul 2024 08:41:14 -0000 (UTC) Organization: A noiseless patient Spider Lines: 128 Message-ID: <20240711012852.856@kylheku.com> 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> <20240711111357.00007712@yahoo.com> Injection-Date: Thu, 11 Jul 2024 10:41:15 +0200 (CEST) Injection-Info: dont-email.me; posting-host="1c1b3c01db2e58828e57902abb355a3e"; logging-data="2510230"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1+q3/VNqkPVE7BNpt+Ajx8H2NPpwzU+e14=" User-Agent: slrn/pre1.0.4-9 (Linux) Cancel-Lock: sha1:HwNy4HDvZLpW7mHhLDX+CXO7JWg= Bytes: 5875 On 2024-07-11, Michael S wrote: > On Wed, 10 Jul 2024 21:28:15 +0200 > David Brown wrote: > >> On 10/07/2024 19:14, Michael S wrote: >> > 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. >> > >> >> Haskell is the first the comes to mind for me, but you could pick any >> compiled functional programming language. >> >> I am by no means a Haskell expert, and I am not at all familiar with >> the way the language is compiled. But it is quite clear that it is >> an example of a language that has functions as first-class objects, >> and which is ahead-of-time compiled. The example below defines an >> int-to-int function "doubler", and also a function-to-function >> function "doTwice", and a function quadrupler that is defined as the >> result of applying the higher-order function doTwice to doubler. >> These are all compiled to assembly. >> >> >> >> >> module Example where >> >> doubler :: Int -> Int >> doubler x = 2 * x >> >> doTwice :: (Int -> Int) -> (Int -> Int) >> doTwice f x = f (f x) >> >> quadrupler = doTwice doubler >> >> shouldBeEighty = quadrupler 20 >> >> >> >> You can write much the same in C++ using lambdas (which are objects >> and can be passed around and returned as such) and templates (which >> are needed because the type of lambdas is hidden). Unfortunately, >> this also means that the functions don't get individually generated >> functions in assembly: >> >> >> >> auto doubler = [](int x) -> int { return 2 * x; }; >> >> auto doTwice = [](auto f) -> auto >> { >> return [f](int x) -> int { return f(f(x)); }; >> }; >> >> auto quadrupler = doTwice(doubler); >> >> auto shouldBeEiqhty = quadrupler(20); >> > > I fail to see a material difference between first class function values > in Haskell and C++ and first class function pointer values in C: > > int doubler(int x) { > return x*2; > } > int doTwice(int (*foo)(int), int x) { > return foo(foo(x)); > } > int quadrupler(int x) { > return doTwice(doubler, x); > } > > I am willing to believe that the difference exists, but your example is > too basic to demonstrate it. First class functions could do something like this: // multiplier takes a coefficient and returns a pointer to // function int (*multiplier(int coefficient))(int) { // fantasy lambda syntax. Return type int is written after // parameter list. return lambda(int x) int { return coefficient * x; } } int (*doubler)(int) = multiplier(2); int x = doubler(42); // x becomes 84 Even though the lambda is returned out of multiplier, whose execution terminates, when the returned function is invoked, it can refer to the coefficient, which is captured in a lexical closure. With a C-like typedef, we can declutter the definition of mutiplier: typedef int (*int_int_fn)(int); int_int_fn multiplier(int coefficient) { return lambda(int x) int { return coefficient * x; } } -- TXR Programming Language: http://nongnu.org/txr Cygnal: Cygwin Native Application Library: http://kylheku.com/cygnal Mastodon: @Kazinator@mstdn.ca