3 ms·
It’s not an end goal, maybe, but if I’m writing a complex program and I want to print to the console for logging or debugging or status, I shouldn’t have to thi
by MatthiasPortzel 3y ago
It’s not an end goal, maybe, but if I’m writing a complex program and I want to print to the console for logging or debugging or status, I shouldn’t have to think about the design of that print-call. I would like to be able to focus on the main complexity of the program, rather than worry about boiler-plate complexity every time I want to print.
- avianlyric 3y agoYou seem to be making the assumption that in other languages calling print is a blocking function that guarantees the printing of a string. Which it isn’t. In python print adds your string to the stdout buffer, which eventually gets written out to the console. But it not guaranteed, if you want that guarantee you need to call flush on the stdout IO handler. Dada has taken the approach of making blocking IO operations explicit, rather than purely implicit. The result is that if you want to perform an IO operation, you need to explicitly say when you want to block, rather than allowing an elaborate stack of runtime buffers dictate what happens immediately, what happens later, and what going to block further code execution. In short this completely exists in other languages like Python, you’ve simply not be aware of it, or aware of the nuanced was in which it fails. But if your someone whose wasted hours wrestling with Python IO system, then you’ll appreciate the explicit nature of Dada’s IO system.
- gpderetta 3y agoWould waiting on a mutex or signaling a semaphore require explicit awaiting in Dada? What about faulting in an mmaped memory buffer?
- avianlyric 3y agoI honestly don’t understand why you seem to be getting so upset about this. Dada isn’t a real language, it’s a thought experiment. It’s whole purpose to ask exactly these questions, and discuss the consequences, so those learnings can be used to inform other languages. Arguing that a particular design choice is silly from a purely ergonomic or usage perspective is kind of absurd, given you literally can’t use the language at all. Maybe waiting for a mutex, signalling a semaphore, or waiting for page faults should require an await (although it’s literally impossible for a language to await a page fault without a lot cooperation from the OS). The whole point of Dada is you can make those design choices, then work through the consequences. Maybe it turns out they’re actually fantastic ideas, once you get past the surface level issues, or maybe they’re terrible ideas. But once again, Dada doesn’t actually exist! It’s a thought experiment to test all kinds of ideas, but without having to waste all the time and energy building those ideas to discover issues that could have been discovered by simply having a conversation.
- gpderetta 3y agoSorry for appearing that way, I'm genuinely not getting upset. I'm just passionate about this relatively minor corner of language design. Exactly because Dada is just a thought experiment it interesting to push the boundaries of such a model in various ways with low stakes. Constructively, I'm partial to full coroutine abstractions that hide the asynchronouness of functions or on the other side of the spectrum, to full effect systems. I think async is a necessary evil on some high performance languages (like rust, C++, certainly not python), but elevating it to an actually desirable from the ergonomic point of view seems just wrong.
- avianlyric 3y agoI think there is value in elevating it from an ergonomic point of view, especially when walking that boundary between concurrency and parallelism. Pure concurrency has the advantage that you can do away with a lot of complex and nuanced synchronism mechanisms, by virtue of the fact you’re not actually sharing memory between parallel lines of computation. Something that makes writing correct concurrent code quite a bit easier and friendlier. In that world have clear and explicit markers of when a function call might result in you yielding to the event loop, and thus memory values you read previously in your function might change, is very handy. Especially if there’s a nice mechanism to delay that yield until after you’ve completed all your important memory operations, and have confidence that your computed values are consistent. Coroutines are certainly a different approach to the same problem, so hide the blocking nature of functions in a neat way, but at the cost of requiring you to start using those complex synchronisation primitives, because any function call or operation might result in an implicit yield, and thus you can’t predict when memory values might change. My first introduction to async/await was the Twisted framework for Python. It wasn’t called async/await back then, the principles were identical. Twisted made it possible to write pretty high performance concurrent network code in python, in a way that was very understandable, and _safe_, without resorting to multi-threading or multi-processing. As a result I think the async/await in Python is actually a really good idea. When used correctly, it makes it possible to write really nice, performant, code in python, without resorting to parallelism, and all the pitfalls that come with that (I.e. synchronisation). Async/await provides a nice middle ground between full on parallelism, and single threaded blocking code with no ability to interleave IO operations.
- int_19h 3y agoIt's trivial to tell Python to block on all stdout writes, though. You don't have to do it on every call.