Path: ...!eternal-september.org!feeder3.eternal-september.org!news.eternal-september.org!.POSTED!not-for-mail From: Bart Newsgroups: comp.lang.c Subject: Re: When Is A High/Low-Level Language Not A High/Low-Level Language? Date: Sun, 18 Aug 2024 01:45:48 +0100 Organization: A noiseless patient Spider Lines: 99 Message-ID: References: MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 8bit Injection-Date: Sun, 18 Aug 2024 02:45:47 +0200 (CEST) Injection-Info: dont-email.me; posting-host="3b7af9ffbc5b2dc8e00c9bad01337f22"; logging-data="2213409"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1/NuZsIc1Jm6SLw346oIp0F" User-Agent: Mozilla Thunderbird Cancel-Lock: sha1:yM/S5hrhqz3nbqtRRaJXnbdo6M4= Content-Language: en-GB In-Reply-To: Bytes: 4527 On 18/08/2024 01:23, Lawrence D'Oliveiro wrote: > On Sun, 18 Aug 2024 00:20:49 +0100, Bart wrote: > >> On 17/08/2024 23:11, Lawrence D'Oliveiro wrote: >>> >>> On Sat, 17 Aug 2024 11:19:30 +0100, Bart wrote: >>> >>>> ... what does this have to do with C, or anything at all? >>> >>> C is supposed to be the epitome of the low-level language that can do >>> bit-fiddling and unsafe type conversions and the like. This is an >>> example of an unsafe type conversion (offering a typesafe interface to >>> the caller, of course) done dynamically, in a language which is >>> generally considered to be “higher-level” than C. >>> >>> In sum: types as first-class objects + low-level bit-fiddling = a >>> combination unavailable in traditional “low-level” languages like C. >>> >>>> Apart from being an apallingly bit of code. >>> >>> How would you it less “apallingly”? >>> >>> (This sentence no verb. Also speling.) >> >> It's an adverb. Although there should have been two P's. > > Still not answering the question. > >>>> However I can't see the switch-expression; there is a Dict >>>> constructor, where all elements are evaluated, not just the one >>>> selected. That is not how 'switch' works. >>> >>> How does a switch-expression work, then? Can you give us an example? >> >> Take this Python code that has a similar dict constructor: >> >> def prnt(x): print(x); return len(x) >> >> i=3 a={1:prnt("One"), 2:prnt("Two"), 3:prnt("Three")}[i] >> >> print(a) >> >> It selects the third element keyed with '3', but the output is: >> >> One Two Three 5 >> >> So 'prnt' has been called 3 times instance of just once. (Also using a >> non-existent key gives an error.) > > So do it this way: > > a = \ > { > 1 : lambda : prnt("One"), > 2 : lambda : prnt("Two"), > 3 : lambda : prnt("Three"), > }[i]() > >> (Also using a non-existent key gives an error.) That gives you lazily called elements, but the lambdas still have to be evaluated! If you had 100 such lines, you'd still need to build a 100-element key-map (so executing 100 lots of LOAD_CONST and MAKE_FUNCTION) just so you can select one lambda. > > Want a default case for your switch? Easy: > > a = \ > { > 1 : lambda : prnt("One"), > 2 : lambda : prnt("Two"), > 3 : lambda : prnt("Three"), > }.get(i, lambda : «default»)() I wouldn't call that easy. What, using a totally different syntax? Plus it uses this new 'get' attribute. It's ugly. For the switch example I used, only these two bytecode instructions are executed, to get to the bit of code you want to evaluate: -----pushm i -----switch 3 , 1 (followed by a jumptable, but that is constant data, not executable code) If I have a loop calling your code with i ranging from 1 to 10 million (so usually it is invoking the default case, which I've changed to a numeric value), then CPython takes 5 seconds. The equivalent in my interpreter is 0.15 seconds. (PyPy will take 0.5 seconds; still slower, but such a measurement is not meaningful anyway; my version will still be fast in the context of a real program; PyPy mainly does its thing with loops.) So your Python solutions are both ugly, and slow, sorry.