https://github.com/BartoszMilewski/Okasaki/blob/master/Tripl...
https://github.com/BartoszMilewski/Okasaki/blob/master/Tripl...
Have you ever used STL? It is full of template classes! It is a LOT of code in there.
The author implemented a stream processing framework based on lazy evaluation and an interface taken straight out of functional programming (Haskell) approach.
Tidy it up, make it more robust and why wouldn't it be industry strength and ready for production code?
#include <lazy_streams>
//3 lines of code to implement the original problem
What would be wrong with that?I think C++ more than (m)any other language(s) sufferes from not-invented-here syndrome. If something is not in core language or STL then it might as well not exist -- people will always do their own thing from scratch. Or you grab some behemoth library like Boost which should cater to all your needs.
In contrast in Haskell/OCaml/Clojure (probably others too but those I'm most familiar with) one can download a tiny library that allows to radically change the control flow of the program.
What's demonstrated here is one such thing. It is based on sound principles (monads, functors...) and lazy streams which is a very well researched topic.
Sure, this is C++ we are talking about and there sure will be dragons somewhere. But if Bartosz ever dedicates his time to make a full fledged and tested library I will be damn sure to use it!
But seriously, while this is toy example, it demonstrates what perhaps will be viable for standard library or for the future language features. Have you tried to read STL implementation code? - it's pretty incomprehensible, but it's still extremely useful library.
A coroutine is created once and it yields control to its "caller" each time it produces an item. To implement a coroutine, you only need to save its stack (local variables, instruction pointer).
He created a lazy stream: instead of yielding control for each item produced, it makes a linked list of items where each node is created on demand.
Thus, coroutines only return the "next" item, while streams compute and store the history of the whole computation.
You could, but the control is still driven by printNTriples. What if you had to break early, before generating all N triples? In this simple case, you could use a return value from the callback to decide whether to continue or not.
In a more general case, you would you would encapsulate the state into a class (for example, the x,y,z,i locals from the original function would become instance memebers.)
I’ve been working in C++ for about ten years, since a couple years after I started programming. It’s certainly gotten better over time—particularly in terms of containers and ownership semantics—but it’s still not good exactly. For instance, it’s possible for mortals to write exception-safe code now, but still not memory-safe code.
I spend an inordinate of time language-lawyering for my coworkers to avoid future debugging hell, and though in my opinion I don’t even know the standard all that well, I’m certainly among maybe a few dozen people at my company who come close to knowing it in full.
It’s just an absurd source of artificial expertise that needs to die.
It seems to me that you barely have to think about memory ownership anymore ever since unique_ptr and shared_ptr came along.
Also, I think Rust has kind of nailed ownership semantics - makes my life a lot easier when the compiler assists me with those things.