https://futureofcoding.org/ logo
Title
g

guitarvydas

04/18/2023, 9:43 AM
Drawware using draw.io - recent submission to Handmade Jam that I was involved with https://handmade.network/p/374/odin0d/
k

Kartik Agaram

04/24/2023, 5:33 AM
Where does the string "hello world" come from when you run the program? I went back and reread your earlier writings (seeing running code often causes me to focus on a thing). Some reactions: • Components include two concerns: what code runs inside them, and what queues are wired up to them. I think having to duplicate the code inside every time you clone a component is a non-starter. You say, "deduplicating code is a compiler concern" (https://publish.obsidian.md/programmingsimplicity/2023-01-24-0D+Ideal+vs.+Reality) which feels handwavy. Compilers are rocket science, and if we don't have the compilers to do this (we don't have compilers to do a lot, and it isn't obvious to me that compilers can deduplicate arbitrary code without risking lots of performance regressions) then somebody still has to do it. • As a consequence it seems to me that components are strictly higher level than functions. You don't want to put raw code inside components. Stick a function call into the component, and now copying the component is cheap and you don't need a complicated compiler to make it cheap. This is fine. I wouldn't get too hung up on this. Like you said, use both. The interesting question here is when we should wrap a function in a component abstraction. • Calling these things zero-dependency is not quite accurate. As you define it, hardwiring the name of a function call is a dependency. But you have names of components like
echo
hard-wired into your example. Again, this is fine. I wouldn't get too hung up on this. The technical idea is sound. You just need a better name and positioning to avoid these distracting quibbles and focus the audience's attention on the core idea. • Request for example #1: How might you perform dependency injection with components? Pass something into a port that causes a component with that name to be invoked? Does this help make things more decoupled? Dependency injection does help decouple functions. • Request for example #2: Check out the example of run-length encoding at https://www.chiark.greenend.org.uk/~sgtatham/coroutines.html. I'm curious how this program would look with your approach. Might you need coroutines? A component can have multiple inputs and outputs in parallel. Can it have multiple outputs in series? So that pumping in one input results in multiple outputs? Then this question has me wondering if it should have multiple inputs in series as well. What might that mean? • You've mentioned before that this looks like hardware. One challenge with designing hardware circuits is getting just right the timing of signals coming into a piece of combinatorial circuit, and debugging the weird errors when we don't. We need the sequential latches just so to make the circuit more robust. But the latches add latency. I wonder if your approach shares this problem. What are the semantics of a component with two inputs that receives a signal/value on only one of them? You could block and wait for the other, or not. Both seem to have trade-offs, and I think I can construct subtle bugs both ways. • There are still some gaps before this can be the notation for concurrency. As you said, you need both functions and components to coexist. And you need a way to go between them: wrap a series of function calls in some queues to turn it into a component, or wrap a set of components into a function so you can give it a name/address to combine with multiple sets of queues. Functions provide abstraction. Copying components does not. On the whole, this needs a whole lot more examples. I'd forget the tooling initially and just hand-write a bunch of examples. Do they seem clear? Are there notational changes that might make them clearer? Etc.
g

guitarvydas

04/24/2023, 11:42 AM
Thank you for taking the time to read and to write detailed comments! Much appreciated.
I apologize for the delay in responding. I was incrementally trying to make this perfect, but am suffering from “life gets in the way” and now have decided to post a snapshot... Components are like Classes. The code is not duplicated. Instantiated, yes, duplicated, no. ... In 2023, though, compilers are “easy” to build. ... What is needed is a language(s) that gets out of the way during design then allows incremental optimization (aka “typing”, etc.) in places where performance matters (probably only about 5% of the code). ... End-users don’t care if developers use static typing or not. ... Optimization-first languages, like Python, Rust, Haskell, Odin, etc., deal only with ... 33% of the problem. ... Code as we know it, is just assembler for better languages. ... I think that dependency is a serious problem. I identify at least 3 ways that dependency creeps into current-day code. ... Note that this scheme tries to encapsulate names. ... These ideas are definitely related to coroutines. And, green threads, and, mutual multi-tasking, and, closures, and pipelines, and Actors, and State, and Duff’s device, and RATFOR, and Software Tools, and EE, etc. ... I argue that the over-use of synchrony, as in just about all current-day programming languages, leads to even weirder errors. ... Components provide better abstraction than functions. ... the true model of distributed programming is a couple of rPIs connected by a pair of wires. ... Thread libraries don’t implement the above model correctly. ... … was your first point. I choose to defer discussion of this point, since I think that it contains deeper meaning that needs to be addressed in a better way than I can at this time. ... The rest of this note is at: https://publish.obsidian.md/programmingsimplicity/2023-05-26-Response+regarding+Call-Return+Spaghetti
k

Kartik Agaram

05/31/2023, 3:06 PM
Oh don't feel like you have to respond to me. It's enough to be aware of my suggestions in future writings. Certainly feel free to ask me questions or show me new drafts. But comments should help you, not add more to your to-do list.
In 2023, though, compilers are “easy” to build.
Sure, but these are compilers for the sorts of languages you criticize. They use functions, are overly synchronous. I haven't seen any evidence they are able to deduplicate huge swathes of code in large parts of a program. The best they can do is fold together a few expressions within the same function.