|
Dren posted:a great flamewar interspersed with math jokes Pretty sure this is a statement about the field of programming.
|
# ? May 8, 2013 00:05 |
|
|
# ? Jun 6, 2024 05:35 |
|
Plorkyeran posted:And ridiculously less verbose in some cases. Almost all cases, which is really sad. I sort of wish they just made something like argn reserved identifiers and allowed you to form lambda expressions around them, a lot like how the library approaches have to do it, but the language approach would work with function calls and control statements without having to make "lazy" versions. E: Even in C++14 it's going to be verbose, especially if you want stuff like automatically deduced exception specifications. A library-based approach allows for automatic exception specifications, automatically deduced return types, unspecified parameter types, and more, which in practice you want almost all of the time. Using the argn approach, you need to employ no extra effort to get it. That Turkey Story fucked around with this message at 00:10 on May 8, 2013 |
# ? May 8, 2013 00:07 |
|
That Turkey Story posted:No. The deferred operation is still short-circuited, just like you would expect. It's the top-level operation that's not short-circuited. Again, "short-circuiting" doesn't even make sense in this domain other than with respect to the deferred operation.
|
# ? May 8, 2013 04:14 |
|
Victor posted:I admit that I don't know how they accomplish this and I'm not sure I'm sufficiently interested to find out how. I admit your example has become motivating, but for a single reason: it preserves short-circuiting. There is no surprise with the example code above. I'm not sure anyone here would be unhappy with that instance of overloading || and &&. Note that (arg1 != 0) && (1 / 0 != 1) would crash. And (arg1 != 0) && my_retarded_expression_builder() would exhibit all the side effects of my_retarded_expression_builder().
|
# ? May 8, 2013 05:08 |
|
shrughes posted:Note that (arg1 != 0) && (1 / 0 != 1) would crash. And (arg1 != 0) && my_retarded_expression_builder() would exhibit all the side effects of my_retarded_expression_builder().
|
# ? May 8, 2013 05:42 |
|
Victor posted:Ahh. Then there isn't as much C++ wizardry as I thought—I was kinda wondering how one could deal with the case you brought up. Thanks for misleading me, TTS! I have concluded that overloading || and && is dumb, if you care about maintainability and/or readability. Some people admittedly don't. ??? What? How is that misleading? It's exactly what he and I have both been saying repeatedly. We weren't even in disagreement. That said, if for some reason you did want this [nonsensical] code to work, you could -- just make the offending part dependent on an actor. That Turkey Story fucked around with this message at 07:39 on May 8, 2013 |
# ? May 8, 2013 07:35 |
|
A minor horror, but I found a data pool that I had mislabeled as "poot" in my code for a bit. It must be how late it is, but the idea of my code having farts in it is making me giggle too much. The code smells!
|
# ? May 8, 2013 07:50 |
|
AlsoD posted:Nah, group elements need an inverse too which strings can't* have. Depending on how picky you are about semantics, strings could be considered to form a monoid however ... Out of curiosity, what sort of pickiness would say that the set of strings under concatenation isn't a monoid? It appears cut and dried to me.
|
# ? May 8, 2013 09:04 |
|
Hammerite posted:Out of curiosity, what sort of pickiness would say that the set of strings under concatenation isn't a monoid? It appears cut and dried to me. When reasoning about things like this especially in Haskell it's generally considered in a more 'ideal' world than is actually the case. Just off the top of my head, (++) is O(n) where n is the length of the first argument i.e. the former is slower than the latter: code:
e: and if you consider unsafePerformIO then things get really weird VVVV: What you need to know about category theory to use monoids in Haskell:
gonadic io fucked around with this message at 10:37 on May 8, 2013 |
# ? May 8, 2013 10:23 |
|
Nothing like whatever the last 5 pages was about to make me go crosseyed and feel very, very dumb.
|
# ? May 8, 2013 10:29 |
|
Captain Capacitor posted:Nothing like whatever the last 5 pages was about to make me go crosseyed and feel very, very dumb. I really wonder how many programmers understand all that without a CS degree. Very, very few I'd imagine.
|
# ? May 8, 2013 10:34 |
|
AlsoD posted:When reasoning about things like this especially in Haskell it's generally considered in a more 'ideal' world than is actually the case. Just off the top of my head, (++) is O(n) where n is the length of the first argument i.e. the former is slower than the latter: I can't imagine a single reason to consider performance relevant to the monoid-ness of something; if you do, anything other than 'addition and multiplication of machine-size integers' probably won't be one.
|
# ? May 8, 2013 10:47 |
|
yaoi prophet posted:if you do, anything other than 'addition and multiplication of machine-size integers' probably won't be one. I think you could at least extend it to any operation on a finite group, since those are all constant-time - in the sense that you can pick a constant c such that any operation can be guaranteed to take less than c units of time to complete.
|
# ? May 8, 2013 11:20 |
|
Rocko Bonaparte posted:A minor horror, but I found a data pool that I had mislabeled as "poot" in my code for a bit. It must be how late it is, but the idea of my code having farts in it is making me giggle too much. The code smells! On a related note, I smiled when someone marked a code review with "looks good, make sure you blah blah blah then you can poo poo it"
|
# ? May 8, 2013 12:05 |
|
When writing some code for doing MRI simulations I had a process for performing phase-encoding shots and counting them for the current image and cumulatively. Naturally, two accumulator variable names arose: cur_shot_count and cum_shot_count.
|
# ? May 8, 2013 12:16 |
|
I'm personally a big fan of cumtrapz.
|
# ? May 8, 2013 12:30 |
|
Captain Capacitor posted:Nothing like whatever the last 5 pages was about to make me go crosseyed and feel very, very dumb. People are throwing around a bunch of jargon, but the basic ideas aren't too hard to understand. All the jokes are around the idea of a group in mathematics. If you have a set G (e.g. strings) and an binary operator * (e.g. concatenation), then they form a group if the following 4 conditions are met:
A monoid is the same thing, except it doesn't require inverses. The set of strings under concatenation meets the first three requirements, but not the fourth, so it is a monoid, but not a group. Also, a group is called abelian if elements commute with each other, a * b = b * a.
|
# ? May 8, 2013 12:33 |
|
Thanks. I only have 3 semesters left in my degree, and I still had no clue what any of that was about.
|
# ? May 8, 2013 13:06 |
|
AlsoD posted:When reasoning about things like this especially in Haskell it's generally considered in a more 'ideal' world than is actually the case. Just off the top of my head, (++) is O(n) where n is the length of the first argument i.e. the former is slower than the latter: I don't know anything about Haskell, I was coming at it purely from a maths standpoint. I appreciate that it is more complicated if you have to consider how a computer language actually implements stuff. Hope I didn't annoy you by causing you to effortpost. Van Kraken posted:A monoid is the same thing, except it doesn't require inverses. The set of strings under concatenation meets the first three requirements, but not the fourth, so it is a monoid, but not a group. Also, a group is called abelian if elements commute with each other, a * b = b * a. For didactic purposes: another example of a monoid is the set of real numbers under multiplication, in fact any field under its multiplication operation.
|
# ? May 8, 2013 13:38 |
|
I wish SA had a like post button because I lol'd hard at cumtrapz and "Pretty sure this is a statement about the field of programming." (USER WAS PUT ON PROBATION FOR THIS POST)
|
# ? May 8, 2013 13:58 |
|
Found in our old C code:code:
|
# ? May 8, 2013 14:30 |
|
When it's on purpose it stops being funny and starts being creepy.
|
# ? May 8, 2013 14:33 |
|
Suspicious Dish posted:When it's on purpose it stops being funny and starts being creepy. Ever think it's an AI state for a virtual sex simulator? Huh?!
|
# ? May 8, 2013 14:40 |
|
Did you know that PHP is not Javascript? Apparently I did not.JavaScript code:
code:
PHP code:
code:
PHP code:
(* e: "PHP equivalent" meaning of course "What I thought would be the PHP equivalent"
|
# ? May 8, 2013 14:42 |
|
Hughlander posted:Ever think it's an AI state for a virtual sex simulator? Huh?!
|
# ? May 8, 2013 14:43 |
|
Hughlander posted:Ever think it's an AI state for a virtual sex simulator? Huh?! Still not funny and instead creepy.
|
# ? May 8, 2013 15:31 |
|
zergstain posted:Thanks. I only have 3 semesters left in my degree, and I still had no clue what any of that was about. That's not really anything that I've ever seen in a required class for an undergrad CS degree, it's just about pure mathematics that you'll probably only get in an actual math course. You'll probably get combinatorics, logic, some set theory and some strategies for forming proofs, but usually not category theory. Or at least that's how it is in my school.
|
# ? May 8, 2013 17:09 |
|
Wheany posted:Did you know that PHP is not Javascript? Apparently I did not. I had this exact same problem, but going in the opposite direction, from PHP to Perl, which was much worse. It's a completely straightforward and obvious issue... except I'd never heard of pass-by-value or pass-by-reference, and in fact I came from a mathematical background, so it didn't even occur to me that a "function" would not behave like a mathematical function. Figuring out exactly what was happening the first time was pretty
|
# ? May 8, 2013 17:11 |
|
Look Around You posted:That's not really anything that I've ever seen in a required class for an undergrad CS degree, it's just about pure mathematics that you'll probably only get in an actual math course. You'll probably get combinatorics, logic, some set theory and some strategies for forming proofs, but usually not category theory. Or at least that's how it is in my school. Groups are in any abstract algebra class though, so you certainly don't need to go as far as category theory to encounter them.
|
# ? May 8, 2013 17:16 |
|
That Turkey Story posted:??? What? How is that misleading? It's exactly what he and I have both been saying repeatedly. We weren't even in disagreement.
|
# ? May 8, 2013 17:31 |
|
Keep in mind That Turkey Story is the guy who made binary literals in C++ using awful preprocessor hacks and thought that this was a shining beacon of good taste.
|
# ? May 8, 2013 17:38 |
|
Suspicious Dish posted:Keep in mind That Turkey Story is the guy who made binary literals in C++ using awful preprocessor hacks and thought that this was a shining beacon of good taste. It's not "good taste," it's the only way to do it. Be thankful that Paul Mensonides did that, otherwise you wouldn't have a lot of the high-level libraries that exist in C++.
|
# ? May 8, 2013 17:41 |
|
Nah, I'm good.
|
# ? May 8, 2013 17:45 |
|
You really hate me, Suspicious Dish!
|
# ? May 8, 2013 18:03 |
|
yung turkistori, did anything ever come of the discussion you had on one of the Golang blogs (I think it was Russ Cox's but I could be mistaken) about generic programming a la Stepanov, and the virtues of pervasive value semantics? It was the first time I had seem any of the Go people be open to an idea they (by which I mean mostly Rob Pike) hadn't come up with or weren't familiar with.
|
# ? May 8, 2013 18:17 |
|
Otto Skorzeny posted:yung turkistori, did anything ever come of the discussion you had on one of the Golang blogs (I think it was Russ Cox's but I could be mistaken) about generic programming a la Stepanov, and the virtues of pervasive value semantics? It was the first time I had seem any of the Go people be open to an idea they (by which I mean mostly Rob Pike) hadn't come up with or weren't familiar with. Real life took over. I don't know where they are going at this point. For some further explanation, I diverted my spare time to writing a new proposal to bring back C++0x style concepts into the next C++ standard but eventually just threw my hands up in the air with that and accepted that the "concepts lite" stuff that Bjarne is trying to get in would either make it into C++14 and likely ruin the chances for proper concepts ever getting in, or we'd be in the same predicament that we were in that caused concepts to be cut from C++11. I just got tired of everything and it's a lot of effort and ultimately just rests on the backs of people pushing conflicting ideologies. That Turkey Story fucked around with this message at 18:28 on May 8, 2013 |
# ? May 8, 2013 18:21 |
|
That Turkey Story posted:It's not "good taste," it's the only way to do it. Be thankful that Paul Mensonides did that, otherwise you wouldn't have a lot of the high-level libraries that exist in C++.
|
# ? May 8, 2013 18:29 |
|
To be clear, I don't hate you, TTS. I'm just not fond of your type of thinking which I find way too often in the C++ world. I'm sure you're a good programmer and a good API designer in those contexts, but I've honestly been burnt badly by libraries like yours which require me to have a deep knowledge in all the corner cases of C++ in order to use them. C++ is one of those languages is so huge that I've worked in it for years and I'm still discovering features that I never knew existed, and you can't expect most C++ programmers to know everything about it. Python, for instance, forbids overriding its AND and OR operators simply so it could gain consistency with short-circuiting. And it's of course possible to do something absolutely crazy with it as well, even if it's just a toy. (I worked extensively in LEPL for a project where the guy before me chose it, because it allowed him to make a prototype super fast. It has bad error messages when a thing fails, the DSL embedding doesn't really work for Python and if you don't parenthesize correctly, your poo poo fails in mysterious ways. The debugging for it is "call this method to turn on a debug log, and send that log to a mailing list so Andrew can help you decipher it". It's slow, and the solution is some magic memoization which is supposed to work but breaks in edge cases. It's just not a usable solution.) As I said in the Game Dev thread, my philosophy is on making clearly understandable and debuggable code at the expense of forbidding clever syntax and increasing verbosity. Relying on people to know that && will short circuit sometimes and not others, depending on context that might genuinely take people 5 minutes to find isn't furthering that goal. Relying on complex preprocessor metaprogramming tricks that specify Peano arithmetic as a lookup table because "that's the only way to do it" isn't furthering that goal.
|
# ? May 8, 2013 18:41 |
|
Victor posted:Would you mind posting a few links that explain how this was the only way to do it? I'm just starting to get into template metaprogramming, mostly by examining code my boss is writing. I do have a bit of experience with Haskell and Scheme. It's mostly due to the fact that prior to C++11 there was no way to create "variadic templates" (templates that can take any number of parameters). A good example of why this is useful is tuple types. For instance, you often want to be able to do: code:
Anyway, since templates prior to 2011 couldn't be variadic, you had to do the equivalent of the following: code:
The remaining way that you deal with redundancy at compile-time is through the preprocessor. Rather than manually maintaining a bunch of specializations and redundant code in C++, you do some metaprogramming with the preprocessor which results in that redundant code behind the scenes. By doing this, you no longer have to maintain and test a whole bunch of instantations -- you just work with the code that generates those instantiations. ...The issue is that the C and C++ preprocessor is extremely limited. You can't loop, you can't recurse, you can only do basic mathematical operations in certain contexts, etc. Basically, all that you can really do is concatenate tokens and use those concatenated tokens to result in the names of other macros that you can then expand. Remarkably, with this tiny bit of functionality, you can actually create containers and high-order algorithms, lambda functions, etc. but it requires the preprocessor code that's written to have redundancy. So in the end there is redundancy somewhere, but now the redundant code is generic and able to be used by any number of libraries that require variadic templates. It also, perhaps most importantly, is a library that is maintained by someone other than the person creating the library that needs variadic templates. It "just works." Now in C++11 we have direct support for variadic templates so you don't need to do the preprocessor stuff for them, although there are still other places where the preprocessor library is useful. The point is, in the early 2000s the community was faced with a problem: either you just don't have things like tuple types and wait until the next standard (which came a decade later) or you manually maintain monstrous libraries that have considerable redundancy. The existence of the preprocessor library provided a third option -- have concise, maintainable libraries the remove the top-level redundancy by using the preprocessor. Of course, this leaves you with people like myself, who would gladly use libraries like the tuple library back in the early 2000s because it's a tool that fits our needs, and people like Suspicious Dish (not meant as an insult) that do not want to use these libraries because of all of the hackiness going on behind the scenes -- What happens if something goes wrong? Do I want to have to trudge through preprocessor code? Is using the tool worth the other potential headaches?
|
# ? May 8, 2013 18:51 |
|
|
# ? Jun 6, 2024 05:35 |
|
operatorequalguy posted:It does. List classes become highly useful when loading files (either in text mode or binary mode), because it's a reported problem using ftell may not accurately return the size of the file (the details were a bit sketchy, but what size the file is depends on which mode (text or binary) it's in). Apparently relying on this caused users issues so I wanted to bypass that altogether - just load the characters via fgetc, whilst counting how many there are in a list. This guy is the best.
|
# ? May 8, 2013 20:10 |