Live data from Hacker News

Niklaus Wirth has died

twitter.com

371–380 of 412 posts

Re: Niklaus Wirth has died

#371
post #367

Earlier quoted context omitted.

Yeah thinking about it more I didn’t intend to imply a subset relationship. Coroutines are not only used to implement cooperative multitasking, for sure.

well, i mean, lua's 'coroutines' are full tasks with their own stacks, unlike, say, python's 'coroutines'. so arguably it isn't that one can be used to implement the other; it's that they're two names for the same thing lua's coroutines aren't automatically scheduled (there isn't a built-in run queue) but explicitly resumed, which is a difference from the usual cooperative-multitasking systems; arguably on that basis…

> arguably on that basis you could claim that they aren't quite 'cooperative multitasking' on their own

Right, I think this is where I am coming from. Generators, for example, can be implemented via coroutines, but I would not call a generator "cooperative multitasking."

That's very cool! Yeah, I have never done this myself, but in my understanding implementations in assembly can be very small.

> when i went to go look at that just now i was hoping to come up with some kind of crisp statement about the relative importance or complexity of the stack-switching functionality and the run-queue maintenance facility, but in fact there isn't a clear separation between them

That's fair, but I don't think that's the final say here, as you were building a system for cooperative multitasking explicitly, with no reason to try and separate the concerns. When a system is very simple, there's much less reason for separation.

Actually, this makes me realize why I probably have this bias for thinking of them separately: async/await in Rust. The syntax purely creates a generator, it is totally inert. You have to bring along your own executor (which contains a scheduler among other things). Separating the two cleanly was an explicit design goal.

Re: Niklaus Wirth has died

#373
post #366

Earlier quoted context omitted.

that definition is different from the definition i'm using; it covers both what i'm calling 'cooperative multitasking' and things like async/await, the npm event handler model, and python/clu iterators in the mac os 8 documentation, explaining how mac os 8 only has 'cooperative multitasking', the term is defined in the way i'm using it ( https://developer.apple.com/library/archive/documentation/Ca... ): > In programm…

> it covers both what i'm calling 'cooperative multitasking' and things like async/await, the npm event handler model, and python/clu iterators Those are implementation details. What's actually happening in all cases is my definition. > also could you please answer my request for clarification in Yes, your examples or the 5 million other implementations of event loops. You forgot to add gtk's for example :) > in the…

thanks! but here we were discussing specifically the distinction between the approaches to concurrency that require you to explicitly structure your code around yield points, like async/await, and the kinds that don't, like preemptive multitasking and what i'm calling cooperative multitasking. this is unnecessarily difficult to discuss coherently if you insist on applying the term 'cooperative multitasking' indiscriminately to both, which i've shown above is in violation of established usage, and refusing to suggest an alternative term

i'll see if i can flesh out the wikipedia article a bit

Re: Niklaus Wirth has died

#374
post #91

Earlier quoted context omitted.

yeah, i wish i had had the pleasure of meeting him. i reimplemented meta-ii 3½ years ago and would recommend it to anyone who is interested in the parsing problem. it's the most powerful non-turing-complete 'programming language' i've ever used http://www.canonical.org/~kragen/sw/dev3/meta5ixrun.py (i mean i would recommend reimplementing it, not using my reimplementation; it takes a few hours or days) after i wrote…

Ok, so I've been taking a crack at this. Can you help me understand something? On page 8, figure 5, the production for the entire program starts '.SYNTAX' .ID .OUT('ADR' *) ... but I'm having trouble understanding what the ADR code is supposed to do. By my understanding, that line should instead read something like '.SYNTAX' .ID .OUT('CLL *') .OUT('HLT') ... where HLT is some code that causes the machine to halt, or…

i think adr is the equivalent of '.long' in gcc or 'dw' in masm, though the description of the adr pseudo-operation is not very clear. it says it 'produces the address which is assigned to the given identifier as a constant'. on a stack/belt machine or an accumulator machine, 'produces' could conceivably mean 'pushes on the stack/belt' or 'overwrites the accumulator with', but the meta ii machine doesn't have an operand stack, belt, or accumulator; it has a return stack with local variables, an input card, an output card, and a success/failure switch, so it doesn't make sense to read 'produces' as a runtime action. moreover, 'adr' is not listed in the 'machine codes' section; it's listed along with 'end' in a separate 'constant and control codes' section, which makes it sound like a pseudo-operation like '.long'. i suspect 'end' tells the assembler to exit

i agree, it would make much more sense to say

    '.syntax' .id .out('cll ' *) .out('hlt')
and thus eliminate the otherwise-unused adr, or simply to put the main production of the grammar at the beginning of the grammar, which is what i did in meta5ix. i think they do define 'r' on an empty call stack as a machine halt, btw

they do mention this startup thing a bit in the text of the paper (p. d1.3-3)

> The first thing in any META II machine program is the address of the first instruction. During the initialization for the interpreter, this address is placed into the instruction counter.

so i think the idea is that their 'binary executable format' consists of the address of the entry point, followed by all the code, and the loader looks at the first word to see where to start running the code. this sounds stupid (because why wouldn't you just start running it at the beginning?) but elf, a.out, and pe all have similar features to allow you to set the entry point to somewhere in the middle of the executable code, which means you have total freedom in how you order the object files you're linking. so even though it's maybe unnecessary complexity in this context, it's well-established practice even 60 years later, and maybe it already was at the time, i don't know

i hope this is helpful! also i hope it's correct, but if not i hope it's at least helpful :)

Re: Niklaus Wirth has died

#375
sad. after learning basic on a zx81 my father found thrown out in the trashbin (i still have that machine today) my parents got me a 8088 PC. when my friends were playing games on those atari st and amiga machines, i was progrmaming in turbo pascal 3.0 i found from a cheap book that came with a 5"14 floppy. pascal is the first true language i learned and i would probably not be coding today without Niklaus. he changed my life, and he had a huge, huge impact on computing : pascal, oberon. delphi, and many more things. i will miss him dearly.

Re: Niklaus Wirth has died

#376

Earlier quoted context omitted.

It's pronounced with an ɪ like in "wit".

I think that the "i" sound like in "wit" does not exist in German. The Germans pronounce "i" like English speakers pronounce "ee".

And what's the difference? AFAICT it's pretty much exactly the same sound, except in one case it's longer, in the other shorter. Say "bit"... Then say it again, only looonger... And you get "beet". Say "wit", but longer, and you get "wheat".

Re: Niklaus Wirth has died

#377

Earlier quoted context omitted.

> Of course, the great man wasn't German. He was Swiss, more exactly from the city of Winterthur located in the canton (state) of Zürich. The canton's official language is German, however. Of course, people over there speak in a strong local dialect called "Züritüütsch".

Thank you for the correction. I assumed he spoke a variant of american-english. So how did he pronounce his own name? I've never heard his voice. > a strong local dialect called "Züritüütsch". Damn, I've never seen a word with three u-umlauts in it. How the hell do you pronounce two consecutive u-umlauts? "eu-eu"?

Umlauts aren't diphtongs; it's the same sound all the way through. GP used two consecutive ones in order to show that the sound is long. (And whaddoino, if the dialect has an official orthography, maybe that's how it's supposed to be spelled.)

Re: Niklaus Wirth has died

#378
post #367

Earlier quoted context omitted.

well, i mean, lua's 'coroutines' are full tasks with their own stacks, unlike, say, python's 'coroutines'. so arguably it isn't that one can be used to implement the other; it's that they're two names for the same thing lua's coroutines aren't automatically scheduled (there isn't a built-in run queue) but explicitly resumed, which is a difference from the usual cooperative-multitasking systems; arguably on that basis…

> arguably on that basis you could claim that they aren't quite 'cooperative multitasking' on their own Right, I think this is where I am coming from. Generators, for example, can be implemented via coroutines, but I would not call a generator "cooperative multitasking." That's very cool! Yeah, I have never done this myself, but in my understanding implementations in assembly can be very small. > when i went to go lo…

while python-style generators aren't cooperative multitasking (by the usual definition in which cooperative multitasking maintains a separate stack for each task), they can be implemented using cooperative multitasking, which is (arguably!) what happens if you use lua coroutines to implement generators

it certainly isn't the final say! it's just an analysis of how my own code turned out, not any kind of universal lesson

the implementation in monokokko, which reserves the r10 register to always point to the currently running task, is five instructions

            .thumb_func
    yield:  push {r4-r9, r11, lr}   @ save all callee-saved regs except r10
            str sp, [r10], #4       @ save stack pointer in current task
            ldr r10, [r10]          @ load pointer to next task
            ldr sp, [r10]           @ switch to next task's stack
            pop {r4-r9, r11, pc}    @ return into yielded context there
interestingly, what you say of rust's generators is also sort of true of monokokko

> The syntax purely creates a generator, it is totally inert. You have to bring along your own executor (which contains a scheduler among other things).

the above five instructions, or arguably just ldr r10, [r10], is the executor. the in-memory task object consists of the saved stack pointer, the link to the following task, and then whatever variables you have in thread-local storage. but from a different point of view you could say that the in-memory task object consists of the saved stack pointer, a pointer to executor-specific status information (which for this executor is the following task, or conceptually the linked list of all tasks), and then other thread-local variables. i think the difference if you were to implement this same executor with rust generators is just that you probably wouldn't make the linked list of all tasks an intrusive list?

Re: Niklaus Wirth has died

#379
post #258
post #140

Earlier quoted context omitted.

It hasn't won. Threads are alive and well and I rather expect async has probably already peaked and is back on track to be a niche that stays with us forever, but a niche nevertheless. Your opinion vs. my opinion, obviously. But the user reports of the experience in Rust is hardly even close to unanimous praise and I still say it's a mistake to sit down with an empty Rust program and immediately reach for "async" wit…

in the 02000s there was a lot of interest in software transactional memory as a programming interface that gives you the latency and throughput of preemptive multithreading with locks but the convenient programming interface of cooperative multitasking; in haskell it's still supported and performs well, but it has been largely abandoned in contexts like c#, because it kind of wants to own the whole world. it's diffic…

> in the 02000s there was...

So sometime between "02000" and "02999"?

Re: Niklaus Wirth has died

#380

Earlier quoted context omitted.

And these fancy new names aren't there just for hiding the event loop? :)

Sort of and sort of not. The key thing about 2023-era asynchronous versus 1995-era cooperative multitasking is code readability and conciseness. Under the hood, I'm expressing the same thing, but Windows 3.1 code was not fun to write. Python / JavaScript, once you wrap your head around it, is. The new semantics are very readable, and rapidly improving too. The old ones were impossible to make readable. You could argu…

> You could argue that it's just syntactic sugar, but it's bloody important syntactic sugar.

Yes, of course you could, since everything beyond, uh, paper tape, next-state table, and current pen-position (or whatever other pieces there are in a theoretical Turing machine) is basically syntactic sugar. Or, IOW, all programming languages higher than assembly are nothing but syntactic sugar. I like syntactic sugar.

(But OTOH, I'm a diabetic. Gotta watch out for that sugar.)

Post reply on HN