Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Post
  • Reply
nielsm
Jun 1, 2009



From 2 pages ago, but I had to comment on this.

Xenogenesis posted:

OT: I present beautiful handwritten SQL for a small Rails app:
code:
      query = %Q{
        SELECT DISTINCT ON (s.user_id, s.chart_id) s.*
          FROM scores AS s
          JOIN charts AS c
            ON (c.id = s.chart_id)
            #{chart ?
            "WHERE c.id = ?" :
            "WHERE c.key_id = ?
              AND c.game_id = ?"
            }
        AND s.id IN (
          SELECT s2.id
          FROM scores AS s2
          LEFT JOIN scores AS s3
            ON (s2.chart_id = s3.chart_id
                AND s2.user_id = s3.user_id
                AND s2.judgement < s3.judgement)
          WHERE s2.chart_id = s.chart_id
            AND s3.judgement IS NULL
          ORDER BY s2.judgement, s2.score DESC
          #{"LIMIT ?" unless limit.nil?})
        ORDER BY s.user_id, s.chart_id, s.judgement, s.score DESC
      }

Seriously.

What is that subquery supposed to be doing at all? The join in it being a no-op doesn't exactly help.

Join on (blah and foo < s3.judgement).
Where s3.judgement is null.

:suicide:

Adbot
ADBOT LOVES YOU

nielsm
Jun 1, 2009



Xenogenesis posted:

Hahaha, you wish that join was useless.

I see now why it works... I simply forgot to consider the case of the join failing to find any matches.



Also PHP is fine to use as long as you know why it sucks. Its design still makes more sense than mIRC Script.

nielsm
Jun 1, 2009



Never mind me.

nielsm fucked around with this message at 02:35 on Dec 18, 2010

nielsm
Jun 1, 2009



Rewrite it with "variable variables" because PHP is an awesome language :eng99:

php:
<?
$keys = array("feature_button", "feature_name", "feature_button2");
foreach ($keys as $key) {
    if (isset($_POST[$key])) {
        $$key = $_POST[$key];
    }
}?>

nielsm
Jun 1, 2009



Hammerite posted:

I don't see what's wrong with that. Isn't it just an operator precedence issue? In many situations it is necessary to use brackets to enforce the desired order of operations. This seems no different.

The issue is that the precedence is illogical and different from every other language that has the ternary operator.
The design makes the more common case hard.

nielsm
Jun 1, 2009



HFX posted:

Implicit type conversion, or how you get to laugh at someone when they tell you C++ is strongly typed.

code:
class safe_bool {
  // it holds a bool!
  bool v;
  // don't construct from non-boolean types
  safe_bool(int);
  safe_bool(void*);
  safe_bool(double);
public:
  // safe constructors
  safe_bool() : v(false) { }
  safe_bool(bool val) : v(val) { }
  safe_bool(const safe_bool &other) : v(other.v) { }
  // safe assignment operators
  safe_bool & operator = (bool val) { v = val; return *this; }
  safe_bool & operator = (const safe_bool &val) { v = val.v; return *this; }
  // converts to bool
  bool operator bool() const { return v; }
  // acts like a bool
  safe_bool operator ! () const { return !v; }
  safe_bool operator == (const safe_bool &other) const { return v == other.v; }
  safe_bool operator != (const safe_bool &other) const { return v != other.v; }
  // ... add more comparisons here
};
Did I forget anything? Will this even work? :downs:

nielsm
Jun 1, 2009



It's just intended to be a more_typesafe_bool. I'd like to hear about those other problems with bool in C++.

nielsm
Jun 1, 2009



pseudorandom name posted:

Consider what happens when e.g. a smart pointer template class implements operator bool and you compare two different instantiations of that template for equality.

I guess that can be a problem, yes. You mean like this?
code:
shared_ptr<Base> foo;
shared_ptr<Derived> bar;
if (foo == bar) ...
Shouldn't this still solve the problem? But yes it isn't ideal.
code:
template <typename Left, typename Right>
bool operator == (shared_ptr<Left> left, shared_ptr<Right> right)
{ ... }
The solution to problems caused by operator overloads? More operator overloads!

nielsm
Jun 1, 2009



MSVC for 64 bit doesn't allow inline assembly. You can still have assembly source files and call functions written entirely in assembly.

nielsm
Jun 1, 2009



MrMoo posted:

I tried using external MASM64 only to find that the supported syntax can be very different to MASM, i.e. MASM64 is like a version 1.0 and MASM32 is a version 8.0 with a lot more features. If you trawl the MSDN forums you can find tidbits from the developers.

I guess that's another reason that e.g. VirtualDub's build uses YASM.

nielsm
Jun 1, 2009



I think this has something to do with what Python complains about there:

code:
>>> a = []
>>> b = a
>>> a += [2]
>>> a
[2]
>>> b
[2]
>>> a = a + [4]
>>> a
[2, 4]
>>> b
[2]
The += operator for a list modifies it in-place but still performs an assignment as well. So in the case of the list in the tuple, the += operator first modifies the list inside the tuple (which is allowed, try tuple[0].append(1) for one) but then afterwards attempts to do an effectively no-op assignment, which fails.

nielsm
Jun 1, 2009



From the Python language specification(?):

"Augmented assignment statements posted:

An augmented assignment evaluates the target (which, unlike normal assignment statements, cannot be an unpacking) and the expression list, performs the binary operation specific to the type of assignment on the two operands, and assigns the result to the original target. The target is only evaluated once.

An augmented assignment expression like x += 1 can be rewritten as x = x + 1 to achieve a similar, but not exactly equal effect. In the augmented version, x is only evaluated once. Also, when possible, the actual operation is performed in-place, meaning that rather than creating a new object and assigning that to the target, the old object is modified instead.

With the exception of assigning to tuples and multiple targets in a single statement, the assignment done by augmented assignment statements is handled the same way as normal assignments. Similarly, with the exception of the possible in-place behavior, the binary operation performed by augmented assignment is the same as the normal binary operations.
Emphasis added.
I'm not sure what the last thing is supposed to mean.

It seems to say that an assignment will always occur, and that operations may be done in-place. The __iadd__ special method is used for in-place addition. From the description of that, and the above, it seems like what is being done is:
code:
temp = a.__getitem__(0)
val = [1]
if temp.__iadd__:
  temp = temp.__iadd__(val)
elif temp.__add__:
  temp = temp.__add__(val)
elif val.__radd__:
  temp = val.__radd__(temp)
else:
  poo poo
a.__setitem__(0, temp)
The reason it gets this complicated would be because Python doesn't have an "operator[]+=", so it has to be synthesized. I'm sure tuples would just reject that operator anyway, if it existed.

Conclusion: The behaviour really does make sense. I don't have any ideas for making it fail instantly or not throw up, without risking breaking something else, more important.

nielsm
Jun 1, 2009



Also the HTML 5 doctype is so much easier to remember:

<!DOCTYPE html>

nielsm
Jun 1, 2009



I remember reading somewhere that the Java compiler now actually detects cases where it seems a string is being built, and replaces String concatenation operations with a StringBuilder.


But I wonder how the code above will perform if handed the URL of a binary file, I imagine it might end up performing newline transformations on the data.
The main WTF is reading line-by-line instead of just a fixed-size buffer.

Other WTFs:

String output = "";
// ... no assignments to output
output = new String();


No error reporting. Empty resource looks the same as any kind of error.

But it isn't really a horror IMO.

nielsm
Jun 1, 2009



I think the problem is that "regular expressions" as most languages implement them are not all that regular. It can be a problem when the time to match a string goes from O(n) to O(n^2) because your "regular expression" engine turns out to not actually use DFMs.
It'd be nice to replace those irregular expressions with regular expressions and parser generators... one can wish.

nielsm
Jun 1, 2009



Zombywuf posted:

Look at the graph for the part before the Perl one goes crazy.

Remember that the two graphs on the top have different vertical scales. The Perl one measures seconds, the DFM one measures microseconds.

nielsm
Jun 1, 2009



This PHP pattern:
php:
<?php
  include "pages/" $_GET['page'] . '.php';
?>
Makes for great fun if you then fetch index.php?page=../index :haw:

(I'm going to hit someone with a blunt instrument when he shows up.)

nielsm
Jun 1, 2009



Well if nothing else, having some UI state of something indicate a data state, and be the only (or best) way of checking for that data state, is a maintainability-problem brewing. This could also point to the controller leaking into the view, or something to that effect.

IsItemDraggable should depend on IsTransactionProcessed, not the other way.

nielsm
Jun 1, 2009



Biowarfare posted:

code:
try {
	// Everything
}

catch (e) {}

More concisely:

ON ERROR RESUME NEXT

nielsm
Jun 1, 2009



Wheany posted:

Holy poo poo, yes you can:
code:
span[style="text-decoration:underline; color:red; background:yellow"]{
	color:green !important;
	background:blue !important;
	text-decoration:none !important;
}

Hey, you could also use that to make nonsensical style= attributes in your HTML and still have them do something. CSS classes go home!

nielsm
Jun 1, 2009



BigRedDot posted:

Oh, this was 100% the case there. "But we're a research lab, you see!" Or "We make sonars, not software!" Nevermind everything past the actual physical sensor is all built with software nowadays...

Cut the amount of solder in half, we make sonars, not electric circuits.

nielsm
Jun 1, 2009



Well, since it prevents you from writing any kind of re-entrant code, it also effectively prevents you from writing any kind of recursive code. It should be reasonably easy to reason about functions never entering a kind of call loop. When you know that never happens, you can then determine the maximum stack size that can possibly occur, and design memory layout for that. Since everything else is global you should then be able to do some kind of reasoning about total memory consumption.

nielsm
Jun 1, 2009



OddObserver posted:

... Though really, bringing back Pascal might actually not be a horrible idea, either (after adding a string type, of course).

Nobody would write ANSI standard Pascal today. Nobody sane, at least. Give the students FreePascal and have it use Object Pascal mode, I think that may even be default now.
As far as I remember, you then get a boilerplate like this:
code:
program foo;

var
  // variables declared here

begin
  // main program goes here
end.
If that doesn't make sense to someone beginning programming, they probably will never learn anyway. "Here's a program named 'foo', it has these variables, and the actual code begins here, ends here.".

But the more sane option is probably Haskell, a Lisp or an ML on first semester, and then Python on second. On third, throw C++ and Java at them simultaneously.

nielsm
Jun 1, 2009



Jabor posted:

It's the whole lambda scoping thing. Lambdas close over variables, not values.

Evil, but I see how it kinda makes sense.

For whatever reason it didn't catch my eye at first, why use
return BuildAction(wrapperAction, ++i);
instead of
return BuildAction(wrapperAction, i+1);
? I mean, you'd expect i to go out of scope after that so why even bother changing its value. Except it does stay in a scope :eek: That should have raised a flag.

nielsm
Jun 1, 2009



Ensign Expendable posted:

Is e some kind of insane list of lists (of lists)?

Looks like some DOM-alike tree structure. I assume getFirst() actually means "get first child", and not "get first on this level", otherwise it wouldn't really make sense.

The code would make more sense if you had an example of the document tree it's presumably working on.

nielsm
Jun 1, 2009



Brecht posted:

'abstract' is not a C++ keyword? What is this?

Probably C#.

nielsm
Jun 1, 2009



shrughes posted:

No because foo is virtual.

Then your object is still of type T1 even if it masquerades as a B1. If it behaves as a T1 then it is a T1, even if the formal type is something else in the context.
In my world, a type is defined by the operations on it. If two objects with the same interface have different actual operations performed by otherwise identical calls, then they are of different types.

nielsm
Jun 1, 2009



shrughes posted:

So you say that string("hi") and string("hey") are of different types.

That's an interesting definition of "different behaviour".

nielsm
Jun 1, 2009



shrughes posted:

:words:

I guess I see the logic. It just doesn't seem like a terribly useful mental model to me, though it surely can be useful in some formal proof situations.

nielsm
Jun 1, 2009



Zamujasa posted:

As for MySQL, Lua seems to have the opposite problem where a few people pronounce it "L-U-A" when it's actually pronounced "loo-ah".

That annoys the crap out of me. It's not a goddamn abbreviation, it's a word. (Portuguese for moon.) "Oh, name of a language and it's three letters, must be a TLA."

nielsm
Jun 1, 2009



Yeah. C++ is insanely complex. It takes lots of effort to learn all the details. When you know them, it's a really great language. The only true fault of C++ is that it's hard to learn.

Let's rather discuss how retarded it is that "good old" C allows you to declare a function with an unknown argument list and then just call it with whatever parameters.

nielsm
Jun 1, 2009



Munkeymon posted:

If you need access to an object in the finally block of a try, you have to declare it outside of the try, but you do not have to instantiate it outside the try.
Well, C++ doesn't have finally blocks, which can be annoying until you remember you're supposed to put your cleanup logic in your destructors. Then it isn't a problem all of a sudden. It's like garbage collection just better. ("C++ doesn't need garbage collection, because it doesn't produce garbage.")

Example, I have a handle value I need to close when a block is left, even if an exception is thrown:
code:
class AutoHandle {
  HANDLE h;
public:
  AutoHandle(HANDLE h) : h(h) { }
  ~AutoHandle() { CloseHandle(h); }
};

void leek() {
  AutoHandle h(CreateHandle());
  throw "oh poo poo"; // this line is a horror btw
  // no leak
}
A bit of extra code up front, but it gets you a reusable component so it's not actually a loss.


baquerd posted:

Or suppose you want a placeholder member variable at the object level that will be defined in constructor arguments:

code:
class foo {
  final Object butts;
  foo(Object butts) {
     this.butts = butts;
  }
Why would you want an instantiated butts at declaration? Hint: you wouldn't and it would actually break this.

What you do in C++:
code:
class foo {
public:
  const Object butts;
  foo(Object const & butts) : butts(butts) { }
};
Pass a reference to a const Object in (faster pass by value, but still allows you to use a temporary unlike using a pointer type or a non-const reference), then initialise the butts field by its copy constructor from the argument. This is also the same syntax used to call superclass constructors.

nielsm
Jun 1, 2009



Vanadium posted:

This whole discussion would be moot if more people realised that when you say Object variable; in C# you're saying Object^ variable; in C++/CLI which is fundamentally different. :shobon:

But apparently C# Struct var; is equivalent to something like:
char buffer[sizeof(Struct)];
Struct &var = *(Struct*)(void*)buffer;

nielsm
Jun 1, 2009



Vanadium posted:

So the real horror here is that C++ gives you the option of defining a default constructor for on-the-stack, value, non-reference types? Cripes!

Yeah it's terrible isn't it. How can we ever deal with it!

Of course, then C++ lets you do this later on if you really want to:
new(&var) Struct(some, constructor, arguments);
But then you're also responsible for running any destructor yourself...
var.~Struct();

I think the point is just that C++ does useful stuff by default, but you can break the system and do insane poo poo if you really want to.

nielsm
Jun 1, 2009



Toady posted:

bar doesn't hold a reference a stack-allocated Object?

That code is either C# or Java, not C++.

nielsm
Jun 1, 2009



Apparently Apple's C library can't handle formatting into widestrings when the locale is "C".
code:
#include <wchar.h>
int main() {
  return wprintf(L"%ls\n", L"\u3042") < 0;
}
This program will fail on Mac OS, but works fine on Linux and Windows.

Then change it to this:
code:
#include <wchar.h>
#include <xlocale.h>
int main() {
  locale_t loc = newlocale(LC_CTYPE_MASK, "", NULL);
  return wprintf_l(loc, L"%ls\n", L"\u3042") < 0;
}
All of a sudden it works. (But now it isn't very portable at all. Microsoft has _create_locale instead of newlocale but does have wprintf_l, GNU has neither newlocale nor wprintf_l.)

How does this behaviour make sense?

nielsm
Jun 1, 2009



Xenogenesis posted:

https://code.google.com/p/phpreboot/

Surely this is some brilliant troll?

"It has keywords such as if and elseif just like PHP, so therefore it is pretty much the same as PHP."

It's written in Java.


Sure, it may be interesting in its own right, it doesn't look like a terrible idea, but it has those two major faults.


E: Hey you know, they should call it PHPScript. It's related to PHP the same way JavaScript is related to Java.

nielsm
Jun 1, 2009



yaoi prophet posted:

I think my favorite part is how curly braces are used both for control flow and for delimiting code from HTML. Also raw XPath and URIs, both of which contain the end-of-line comment token :allears:

Well the first thing is no better in JSP, they also have XML-ish tags for serverside processing that seem to be able to live just fine inside non-XML, as far as I know. They also have some curly brace function/data insertion syntax thing. (And then there's the three different processing instruction tags.) In summary, JSP has three kinds of special tags, one of which has yet three sub-categories.

I really don't see how an URI should be a syntax element of its own, and not just use string literals. It can't be a good idea to put them directly in the code anyway, that kind of stuff IMO falls under configuration.

nielsm
Jun 1, 2009



pokeyman posted:

I really don't understand why someone would see two options, "require semicolons" and "don't require semicolons", and decide to go right down the middle. Sometimes it's ok to pick one!

Someone had had enough of his compiler telling him that he probably forgot a semicolon somewhere and had a great idea: "If the compiler can tell me where they need to be, let it insert them for me!"

Adbot
ADBOT LOVES YOU

nielsm
Jun 1, 2009



TasteMyHouse posted:

Apparently, in VC++6, this worked:

VC10 still has a compiler option to allow that broken scoping, look under the C/C++ > Language settings. But yeah, better fix the code.

  • 1
  • 2
  • 3
  • 4
  • 5
  • Post
  • Reply