3 ms·
> When people talk about "genericness", or "generic programming" in front of me, the first example they give to me is the parametric polymorphism of the STL. T
by jemfinch 16y ago
> When people talk about "genericness", or "generic programming" in front of me, the first example they give to me is the parametric polymorphism of the STL.
The STL embodies (and accomplishes) far more than parametric polymorphism. As far as I know there is no other language with as comprehensive a collection of container-independent algorithms in the standard library.
> The fact that template are Turing complete doesn't hide the restrictions they come with (like how they interact with inheritance). I know they have others goals than mere parametric polymorphism. I even admit that I don't understand these goals. I just say that one goal wasn't met: simple parametric polymorphism.
And you're still wrong. Templates achieve parametric polymorphism and more. I can write a simple, templated, singly-linked list class in C++ which can do everything the same `'a list` in ML can do.
> About lambda lifting being a (simple) syntactical transformation, please stop. You're right, but in a trivial sense: every compilation process is a (less simple) syntactical transformation. That includes lambda lifting, ghc's crazy optimizer, and every static compiler on this planet.
I was making a greater claim that you seem to understand. Lambda lifting is a simple syntactical transformation. I can explain the entire transformation in a paragraph or less. I can offer example code of the transformation off the top of my head with ease. All lambda lifting does is make explicit what closures allow to remain implicit.
Your following two paragraphs are a fairly obvious attempt to change your original, wrong statement into something defensible.
> So, a language without lambdas doesn't treat functions as first class citizens.
Ridiculous. A language without lambdas is just that: a language without lambdas. Remove lambda from Python, and you remove only the ability of a Python programmer to define unnamed functions. Functions remain first class; their binding rules remain exactly the same. The only difference is that now programmers must give a name to all their functions.
- loup-vaillant 16y ago> As far as I know there is no other language with as comprehensive a collection of container-independent algorithms in the standard library Whoops. I forgot that, sorry. People may have meant true generic programming, after all. Now, actually using STL's <algorithm> and still end up with readable code isn't easy to me. For instance, each time `for_each` or `accumulate` would be appropriate, I end up writing a `for` loop instead, because the end result is more concise and more local. So in the end, container independent algorithms rarely matter to me. > I can write a simple, templated, singly-linked list class in C++ which can do everything the same `'a list` in ML can do. I think we don't use "simple" in the same way. Here, such an implementation of lists takes only 12 tokens and 2 lines in ML. How many do you need to do the same in C++? My first guess is more five times that, probably ten. Still simple, but much more complicated nonetheless. Though in that particular case, I'd rather blame the absence of inductive types. Templates really are simple here. The real problem shows when you combine them with inheritance: you have to jump through some hoops (like having to re-declare virtual methods in the derived classes). > Your following two paragraphs are a fairly obvious attempt to change your original, wrong statement into something defensible. It was an attempt to clarify my meaning. Yes, my statement was wrong. Lambda lifting doesn't go way beyond syntactic sugar. But, to me, it still crosses the line. To you, it doesn't. I think that's only because your definition of "syntactic sugar" is more liberal than mine. But even then, we're not done. Before you do the actual lambda lifting, you have to parse the source code. Trivial in Lisp, but quite a feat in C++. > […] The only difference is that now programmers must give a name to all their functions. To me, such a restriction is sufficient to make function second-class citizen. If you can have anonymous integers, and you can't have anonymous functions at the same time, then functions are not first class. Again, we disagree on a mere definition. Beyond that, I agree that the other "first-classiness" properties of functions are far more important.
- jemfinch 16y agoI get the distinct feeling that no matter how I respond to what you say, you'll find some way to extend the argument. I'm not here to debate you about general issues with C++; I'm here to argue against very specific, incorrect claims you made about C++ in your initial posts. I'm not interested in arguing with you ad infinitum. > Now, actually using STL's <algorithm> and still end up with readable code isn't easy to me. For instance, each time `for_each` or `accumulate` would be appropriate, I end up writing a `for` loop instead, because the end result is more concise and more local. This seems to be a new complaint, again unrelated to your previous complaint. No one, least of all me, is claiming that C++ is concise. If that's a debate you want to have, you'll need to find some other patsy to have it with. > So in the end, container independent algorithms rarely matter to me. They matter a lot to any implementer of new containers and algorithms, because they mean that any container implementer can provide iterators and automatically support a huge library of algorithms, and any algorithm implementer can automatically support a wide array of containers without needing any specific knowledge of how those containers are implemented. > I think we don't use "simple" in the same way. Here, such an implementation of lists takes only 12 tokens and 2 lines in ML. How many do you need to do the same in C++? When did this debate become about conciseness? Your claim was not that parametric polymorphism was wordy in C++, it was that the implementation was "abysmal". In reality, the implementation is as optimal as it really can be in an imperative, C-derived language: a non-polymorphic data structure on some type "X" can be made polymorphic by prepending "template <typename T>" before the data structure and replacing all references to "X" with "T". That's pretty simple. The difference you note in line counts for implementing a singly linked list is not because of any real difference in capability of the language to support parametric polymorphism, but in ML's support for algebraic data types as opposed to C++'s support for machine-based data types: now you're introducing yet another complaint which is not your original complaint. > The real problem shows when you combine them with inheritance: you have to jump through some hoops (like having to re-declare virtual methods in the derived classes). Perhaps, but since virtual methods and inheritance-based subtyping is something ML doesn't support at all you cannot fault C++ for its less-than-optimal support for those features in comparison to ML. > But even then, we're not done. Before you do the actual lambda lifting, you have to parse the source code. Trivial in Lisp, but quite a feat in C++. Introducing yet another complaint unrelated to anyone's original claims. Ignoring it, since it's not relevant to the reason why this thread originally began. > To me, such a restriction is sufficient to make function second-class citizen. "First class" is a well defined term in programming language design and implementation, and it's not the same definition you're trying to use here. I see no point in arguing with you about your non-standard use of the term.