... I think the perl code actually compiles (err, runs) though. :-)
HN user
bstamour
I used arch around 2008 or so, then distro-hopped to Slackware, when I remain to this day. Some of us escape.
They actually ship three different cans - one for each firewall in the base install.
You're right. Lambdas in C++ are syntactic sugar over something the core language has allowed you to do since before C++98. Since you control which variables you capture into the closure, and how, when writing the lambda, all of the information regarding how to make it (e.g. it's size, data members, etc) is static, and so it does not require the use of the heap at all. A concrete example. The following C++ examples do the same thing, and neither touch the heap:
// A. Using a struct. The old manual way.
struct my_lambda {
my_lambda(int c) : c_(c) {}
int operator() (int x) const {
return x == c_;
}
int c_;
};
auto f(vector<int> numbers) {
my_lambda lam(2);
// remove all the matching elements
erase_if(numbers, lam);
return numbers;
}
// B. Using a lambda
auto g(vector<int> numbers) {
int c = 2;
erase_if(numbers, [c](int x) { return x == c; });
return numbers;
}Internally, lambdas are structs with the "function call" operator overload. Context is done via members of the struct: capture by-value, and the struct copies them and stores its own, capture by reference, and the struct member is a reference. There should be zero heap allocation in any case.
I still use it on my primary desktop computer at home. It's a great, stable system that just keeps on running and doing what it needs to do.
Slackware. I use the Plasma5 packages maintained by Eric Hameleers, and it's a wonderful experience.
We use Delphi for some of our older applications (everything new is migrating to either C++17 or Go). I remember upgrading the IDE (forget which version, but it was about 3 years ago) and after loading my project, I hit F1 to bring up the help menu. The whole IDE crashed... Between little surprises like that and the insane licensing price, I'm glad we're moving off of it. I don't have any objections to the language itself, but the tooling just isn't where it needs to be.
Lock guard has no default constructor, so the line will in fact materialize a temporary lock guard around the mutex m, then throw it away at the semi-colon, thus locking nothing.
You can add a literal operator:
auto operator "" _r(char const* str, unsigned long) {
return std::regex{str};
}
To avoid all the backslashes, you can use a raw string literal: int main() {
auto myre = R"(^hello\w*)"_r;
}Concrete example:
void foo(const int* const p1, int* const p2) {
int a = *p1;
*p2 += 42;
int b = *p1;
return a == b; // b = a + 42
}
int main() {
int x = 0;
return foo(&x, &x);
}You're right, but what I meant about it was that just because the variable is const, doesn't mean it can't change from somewhere else between reads. Even if you use synchronization to avoid data races, if you read the pointer to const twice in the function, it could change between the reads.
If the initial object itself isn't const, then merely declaring the function parameter as a pointer to const won't guarantee that some other thread of execution won't change the value under your nose. Or if you have multiple pointer parameters, they can alias each other.
Indirection in C and C++ is a mess, but at least C has the "restrict" keyword. Best to program with value types whenever you can, and use pointers and references when you must.
readonly was the original proposed name, if I remember my D&E [0] correctly. Bjarne outlined in that book why he went with const instead, but I forget why off the top of my head. I guess it's tine for a re-read!
[0] The Design and Evolution of C++
The examples in the articles are non-constant pointers to constant data. If you want to declare the pointer itself const, you need to do it after the asterisk.
const int* const
instead of const int*Lufia 2 is one of my absolute favourite SNES-era RPG's. I try to replay it every few years.
But in languages that support multiple dispatch at the language level, they're just another way of writing polymorphic functions. They're not just a niche feature. When you don't have to write all of the ceremony of the visitor pattern, it's easier to use visitors everywhere without thinking about them.
Why have functions and control structures when we can just jmp?
Very cool. There should be an arrow from Simula to C++ though, as that's where C++ got its object oriented features from.
The dialect of object orientation that Delphi compiles is different than object pascal. It's pretty safe to call Delphi a language.
Boost came about from a few members of the ISO C++ committee as a way to iterate on library features. It would be a shame if none of that work made it's way back into the standard.
I love the Graham scan algorithm for computing convex hulls of sets of points. That and the fast exponentiation algorithm, which can be used to compute linear recurrences (e.g. fibonacci) in O(log n) time.
Knuth defines effectiveness as: "... all of the operations to be performed in the algorithm must be sufficiently basic that they can in principle be done exactly and in a finite length of time by a man using paper and pencil."
K-means and other heuristic algorithms fit that description.
a % b is a way to do it in fewer iterations than a - b.
It's an example of uniform initialization syntax that was brought into the language in C++11. It simplifies some things (no narrowing conversions allowed) but also complicates things (if any constructor takes in an initialize-list, it gets priority). In this case, the code is constructing an object of type weekday from an expression that represents that particular date.
I adore Zodiac as well but am in a decided minority in that regard.
We're in the same camp, friend. Zodiac was my favourite novel of his.
Have you looked at Perl 6? It's optionally typed, and can be nearly as terse as apl with some of it's higher order operators.
Verbing weirds language. Respect your parts of speech!
No it won't. You'll get a compile time error, as T could either deduce to int or double. Unless you explicitly specify it as max<int>(1, 2.0) or max<double>(1, 2.0).
C++'s type system has always been stricter than C's. Even the following, totally valid C program, is ill-formed C++
int* x = malloc(5 * sizeof (int));
because in C++ you cannot implicitly cast a void pointer.