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
Zombywuf
Mar 29, 2008

pokeyman posted:

Found this in the PHP manual. It's like the guy knew he wanted some kind of conditional execution, but forgot about the "if" keyword.

code:
switch (TRUE)
{
 case ($phlen < 7):
   $ext = $ph;
   break;
 case ($phlen == 7):
   sscanf($ph, "%3s%4s", $pfx, $exc);
   break;
 case ($phlen > 7 AND $phlen < 10):
   sscanf($ph, "%3s%4s%s", $pfx, $exc, $ext);
   break;
 case ($phlen == 10):
   sscanf($ph, "%3s%3s%4s", $area, $pfx, $exc);
   break;
 case ($phlen == 11):
   sscanf($ph, "%1s%3s%3s%4s", $cty, $area, $pfx, $exc);
   break;
 case ($phlen > 11):
   sscanf($ph, "%1s%3s%3s%4s%s", $cty, $area, $pfx, $exc, $ext);
   break;
}

Looks more like a Lisper missing cond.

code:
(cond ((lt phlen 7) (setq ext ph))
      ((eq phlen 7) (sscanf ph "%3s%4s" pfx $exc))
      ((and (gt phlen 7) (lt phlen 10))
          (sscanf ph "%3s%4s%s" pfx exc ext))
      ((eq phlen 10) (sscanf ph "%3s%3s%4s" area pfx exc))
      ((eq phlen 11) (sscanf ph "%1s%3s%3s%4s" cty area pfx exc))
      ((gt phlen 11) (sscanf ph "%1s%3s%3s%4s%s" cty area pfx exc ext)))
Is what they seem to be looking for, assuming the existence of an sscanf macro in Lisp.

Adbot
ADBOT LOVES YOU

Zombywuf
Mar 29, 2008

There's nothing wrong with Hungarian Notation used judiciously, but there's a lot wrong with using it everywhere. It suggests something going badly wrong with your code. Nebby, your examples sound like the code your working on makes poor use of scoping. The problem you think Hungarian Notation solves, I would say, is much better solved by making sure your names stay within about half a page of each other. That is, don't let your functions get so big that the entire context of the name is visible on the screen. If this is impossible, class members for example, the names should be maximally descriptive.

This seems to be the point where you struggle, 'apples' is almost always going to be a collection of 'apple' objects, we don't need to tack on 'lst', 'vec' etc to the beginning to tell us this (yes this is an oblique example of Hungarian Notation, however, it's also English). If all else fails you can just go look them up (C-r in my editor). If your class gains so many members it's impossible to keep track of them all in your head then you need to refactor your class, not rename the members. This is why Hungarian everywhere is a bad sign for code, it's the wrong solution to the problem of complexity.

Zombywuf
Mar 29, 2008

tef posted:

If we're going into unicode territory how about something like ∀ x ∈ l : print x; perhaps?

Wouldn't that make the existential operator the perfect mechanism to introduce unification and backtracking into a language?

ps.
#define ∀(col, op) for_each(col.begin(), col.end(), op)

Zombywuf
Mar 29, 2008

Kidane posted:

While I am paid to write Perl, I am by no means an expert. However, I'm of the opinion that there is nothing inherent to Perl which requires overly-concise code.

No, but concise code is often much easier to read, e.g.
code:
@array2 = map \&do_something, @array1;
Does exactly what it says on the tin.

As for the Optimus KB; WANT! Really, after having just looked at it I may need a change of underwear.

Zombywuf
Mar 29, 2008

more falafel please posted:

It's better than
code:
if(something){
  DoWork();
^^ TWO loving SPACES EVEN THOUGH THE REST OF THE PROJECT USES TABS
}else{
  DoOtherWork();
}

Sheesh, M-x indent-region and get on with your life.

Zombywuf
Mar 29, 2008

more falafel please posted:

That's the problem -- I'm stuck doing that (well, gg=G, but same difference). This code is five years old, and full of crap like this -- defining log macros badly so they need double parentheses, bizarro mixes of Systems Hungarian, CamelCase, camelCase, and under_score_words, depending on this guy's mood that month, static members called m_ivpFoo (instance variable). And of course design problems -- the initializer list for one class's ctor is 124 lines long.

Do you not have check-in access? Or is this one of those case where source control would be too large a change?

quote:

The problem of course is that there's never time -- it's always crunch.

Always the way.

Zombywuf
Mar 29, 2008

dwazegek posted:

No, extension methods are pretty much just syntactic sugar for a call to a method in a referenced static class.
code:
public static class SomeClass
{
  public static bool IsNullOrEmpty(this string s)
  {
    return string.IsNullOrEmpty(s);
  }
}

//these two calls are the same:
s.IsStringNullOrEmpty();
SomeClass.IsNullOrEmpty(s);
Since you're not actually calling an instance method of "s", but actually passing it as the first parameter to an extension method, it doesn't matter if it's null or not.

Yuck. I'd like to plead on behalf of all maintenance programmers everywhere that you don't do that.

Also, why should it not be possible to call a member of a null object?
code:
#include <iostream>

class foo {
public:
  bool is_null() {
    return this == 0;
  }
};

int main() {
  foo *a = 0;
  std::cout << a->is_null() << std::endl;
}
Works fine in C++. This works for exactly the same reason as the above D flat code, but you at least know where to find is_null in this case.

Zombywuf
Mar 29, 2008

Really, even POD?

Zombywuf
Mar 29, 2008

Ah well, good job this is the coding horrors thread. I'd be interested to know if any compilers actually choke on it. Especially is foo::is_null is defined in an external compilation unit.

Zombywuf
Mar 29, 2008

rotor posted:

I don't understand how this is supposed to be especially awful for what is, I assume, supposed to be an in-class example or something.

for loops, have you heard of them?

Zombywuf
Mar 29, 2008

narbsy posted:

if you're doing an in-class example and want to make sure everyone knows what you're doing... then this is better than a for loop due to clarity, at least in my opinion.

/me shudders with horror at the thought that GUI coding should be taught before for loops.

Zombywuf
Mar 29, 2008

I may have found my new favourite control flow structure, the fordowhile loop:
code:
for (i = 0, j = 0; i < 10; ++i, j = 0) do {
  printf("%i %i\n", i, j++);
} while (j < 10);
Now if I can just find a way to combine this with Duff's device...

Zombywuf
Mar 29, 2008

atomic johnson posted:

Christ... everybody knows the way to do this is to make them all prime numbers so that you can just factor the resulting number to get the options that were selected.

chocojosh posted:

Wouldn't the correct solution be to use a bitmask? Define each enum value to 2^i (i = 0,1,2,...,n) and then just check if the relevant is set?

Gah, you're both wrong. Obviously the answer is a bloom filter. It's more extensible that way.

Zombywuf
Mar 29, 2008

Flobbster posted:

And to stroke my e-penis a little, code like what I just wrote above pisses me off. It should be
code:
for(size_t i = 0; i < str.length(); i++)

ITYM:
code:
for (string::size_type i = 0; i < str.length(); ++i)

Zombywuf
Mar 29, 2008

TSDK posted:

It seems to me then that there were 3 WTFs:

1) Relying on specific, non-guaranteed behaviour from uninitialised memory.
2) Knowing that you get specific warnings about sections of code and failing to comment them appropriately.
3) Making a change to some code you don't fully understand without getting in touch with either the original author, or someone who could explain why it's doing what it is.

If you ask me, then the original OpenSSL devs are just as much to blame for that clusterfuck as the guy who put in an incorrect 'fix' for the problem.

Interestingly the first fix posted (mentioned in the bug as not the right way to do it), would have been much less damaging. As for the idea of using uninitialised data as a source of entropy, it's risky as it's possible an attacker could control that data. The real WTF is that, from looking at the code, that buffer should have been filled from /dev/urandom and thus never triggered the warnings. It seems that it would only have used uninitialised data if /dev/urandom was unavailable.

Zombywuf
Mar 29, 2008

This one from my previous job just floated into my mind:
code:
template<class T>
void free(void *pointer) {
  delete (T *)pointer;
}
It's pretty representative. Well actually it only covers a tiny portion of the horror, like using skiplists as a way to store multi GB indexes on disk. That, and storing url encoded argument lists in DB tables instead of adding more columns. Also there was one giant xref table that handled all m to n mappings between tables. There was also this.

Zombywuf
Mar 29, 2008

0x1C to 0x1F are clear the best bytes to delimit data with.

Zombywuf
Mar 29, 2008

0x1C to 0x1F are valid ASCII, and valid utf-8 encodings. Whether or not your text editor will like them I don't know.

Zombywuf
Mar 29, 2008

tef posted:

Perl had the nice thing of goto &function which was occasionally useful, and also allowed you to label loops so you could do break LOOP_NAME

Why the past tense?

Zombywuf
Mar 29, 2008

On the subject of exception based control flow:
code:
class A {
  ...
};

class a : public A {
  ...
};

class b : public A {
  ...
};

void dispatch(const A &obj) {
  try {
    throw obj;
  } catch (a &a_obj) {
    do_stuff_with_a(a_obj);
  } catch (b &b_obj) {
    do_stuff_with_b(b_obj);
  }
}

Zombywuf
Mar 29, 2008

Tetrad posted:

He was literally getting an int out of this class where the address of an int would be in some other class.

I've seen strcpy used on std::string, and it worked. The strcpy prototype was brought into scope from gcc header files copied into the project directory tree. With date stamps in the early 90s; this was in 2005.

quote:

Also a header for a function I wrote when I was in my "templates and boost are awesome" phase (which I'm still in).
code:
template< typename VALUE_TYPE >
void AddValue( const std::string& key, VALUE_TYPE* value, boost::function< bool( typename boost::call_traits< VALUE_TYPE >::param_type ) > validationFunc, bool isRequired );

Nothing wrong that :-)

Zombywuf
Mar 29, 2008

code:
namespace Core.Framework.DataType.BooleanUtils
{
	public static class BooleanFormatter
	{
		/// <summary>
		/// returns string representation of boolean value based on passed definitions of <value>true</value> and <value>false</value>
		/// </summary>
		/// <param name="value"></param>
		/// <param name="trueValue"></param>
		/// <param name="falseValue"></param>
		/// <returns></returns>
		public static string Format(bool value, string trueValue, string falseValue)
		{
			return value ? trueValue : falseValue;
		}
	}
}
Words fail me.

Zombywuf
Mar 29, 2008

_aaron posted:

No, see, this is great, because then you can do things like:
code:
string boolString = BooleanFormatter.Format(true, "false", "true");
MessageBox.Show(true.ToString() + " is " + boolString);
You don't see the utility here!? Not to mention the deep philosophical implications of subjectively defining "true" and "false"...

I can't help but feel you've missed everything that's wrong with the code I posted.

Zombywuf
Mar 29, 2008

Munkeymon posted:

Actually, if this:
code:
IF WS-OPT = 'P' OR 'L'
does what it looks like it does, then that's kind of nice, actually. Explicitly writing out things like if(something == A || something == F) always kind of bugged me for some reason.

You want Prolog:
code:
member(Something, [A, F]) -> thenstuff ; elsestuff.
This message brought to you by the Save the Prolog Foundation.

Zombywuf
Mar 29, 2008

Habnabit posted:

But except: pass makes me want to strangle people.

Sometimes you don't or can't care if an operation fails.

code:
try:
  log_error(error)
except:
  pass

Zombywuf
Mar 29, 2008

Habnabit posted:

Sure, let's go ahead and swallow SystemExit, MemoryError, and KeyboardInterrupt. :v:

Yes, yes, and holy gently caress python makes Ctrl-C an exception. Sheesh. But fair enough, go ahead and catch KeyboardInterrupt, pass the rest.

Zombywuf
Mar 29, 2008

Scaevolus posted:

But it makes sense to handle trapped signals as exceptions-- would you rather there was a different language construct specifically for those sorts of interrupts?

Registered interrupt handlers? If the handler decides to exit the regular exit handlers can kick in. This is pretty much a solved problem in C, why Python does it this way is a mystery, and replaces the notion of "function X raised an exception" with "function X or something else raised an exception". You now have to disambiguate the cases.

Zombywuf
Mar 29, 2008

tef posted:

If you do this in our codebase I will nail your hands to the toilet.

If you don't care if it fails, you should be explicit in the failures to ignore.

It explicitly ignores everything. If you want to ignore everything, this is the mechanism for you.

Zombywuf
Mar 29, 2008

Habnabit posted:

My whole point is you never, ever want to ignore everything. Again, what if a MemoryError is raised? You really want to ignore when there's no memory available, when something higher up the stack could free some memory?
When I don't care if the function is successful, i.e it would be nice to log the error, but we shouldn't tear down the whole program just because we can't. However it turns out you should tear down on memory error because python doesn't guarantee a consistent heap after an out of memory error. I feel dirty just knowing about that.

quote:

When a signal comes in, python interrupts the currently executing stack frame and pushes a new stack frame with the python signal handler function. This function is passed the interrupted stack frame as well. If you have a better idea of how to do this in an interpreted language, I'd love to hear it.
I wouldn't let exceptions escape signal handlers. I certainly wouldn't define keyboard interrupt as an exception. Especially not in a language famed for its simplicity and consistency of behavior. Then again it uses exceptions to signal generator exits, urgh....

Zombywuf
Mar 29, 2008

Habnabit posted:

However, a C extension or python itself can deal with it.
Deal with what exactly?

quote:

I don't think you understand how exceptions work. The exception is not the error; the exception is a signal of an error condition. Discarding the exception does not make the error itself go away. If you can't deal with the error condition, don't pretend you can.
I don't think you understand what "not caring if it fails" means. Unless you're implying that I should expect all code to be exception unsafe and need daddy (some function further up the call stack) to clean up after it. If control has returned to the try block the error should no longer be the problem. The whole point of exceptions is that you get notified that an error happened, not that an error is happening.

quote:

I have no idea what "escape signal handlers" means here. And, again, I urge you to explain how this could be dealt with in a cleaner way.

A signal, i.e. some message received from outside your program, should be understood to be happening in a parallel context, not just lumped at the top of stack on top of whatever is currently executing.

quote:

Same thing here. How else would you do this? Python is not php; these things have been thought out carefully, and this was found to be the optimal solution. You seem to think these things were slapped together without any forethought, but you also don't seem to have any suggestions on how it could be better implemented.

What? Because someone else thought this was the best solution I have to agree?

All hail Hypnoguido, gently caress that.

One simple solution is that of giving generators an iterator interface, i.e. while (mygen.has_more()) { do_stuff(mygen.get_next()); }. This has been implemented in other languages that provide generators or generator like objects - W3C Xpath interface, istream_iterator in C++ and GNU Prolog's C interface to name a few. I'm sure these were thought about and not just slapped together.

zootm posted:

Why not? It creates the correct behaviour in the default case in a transparent and understandable way. And if you have some special handler, you can override the default behaviour simply. Sounds like the best of both worlds.
It only provides expected behavior in the case where you're trying to catch KeyboardInterrupt. When you're expecting the semantics of exceptions to mean "something has gone wrong with the code in my try block", the behavior will break your program. How would you recommend a python program include special handlers for SIG_STOP or SIG_KILL (insert non POSIX equivalents at your own leisure)?

Zombywuf
Mar 29, 2008

Janin posted:

"Out of memory" conditions.
From the docs:

Python docs posted:

exception MemoryError
Raised when an operation runs out of memory but the situation may still be rescued (by deleting some objects). The associated value is a string indicating what kind of (internal) operation ran out of memory. Note that because of the underlying memory management architecture (C's malloc() function), the interpreter may not always be able to completely recover from this situation; it nevertheless raises an exception so that a stack traceback can be printed, in case a run-away program was the cause.

So no, python itself is not guaranteed to be able to recover from a memory error and you can only tear down and dump a stack trace if you want to be safe.

quote:

That would make Python signal handlers pretty useless, since they wouldn't be able to manipulate the execution state except through global C variables.

That's a hell of a lot better than injecting exceptions arbitrarily. It means a bit of code that has specific handlers for different exceptions might be seeing exceptions it has no idea how to recover from because they can be thrown anything.

quote:

What would get_next() do when there's no more data to be retrieved, if not raise an exception? In a case like this:

code:
while (mygen.has_more()) { do_stuff(mygen.get_next()); }
mygen.get_next();

If the user of function does something with it they're not supposed to then the function should throw.

Charles Babbage posted:

On two occasions I have been asked, – "Pray, Mr. Babbage, if you put into the machine wrong figures, will the right answers come out?" In one case a member of the Upper, and in the other a member of the Lower House put this question. I am not able rightly to apprehend the kind of confusion of ideas that could provoke such a question.

quote:

e: Also, it's impossible to implement has_more() for a function-based generator.
No it isn't. Unless you have some crazy ideas about order of evaluation.

quote:

To handle other signals, the programmer just needs to install a signal handler. That handler can do whatever it wants, including raising an exception.

My argument is that this is a bad thing.

Habnabit posted:

No, I never said that. You seem to be so adamant that this not the best way to do it, without considering that there might be a reason why it is that way or providing an alternate implementation.

Go on then, what is the reason. Other than that the secret chiefs of python believe it to be better?

quote:

For something like using SIGHUP to reload config files, you can take advantage of the suspended state of the program and update the configuration from within the signal handler. Of course, you'd have to write your code in a way to prevent reloading from a signal handler from interfering with things while you're in the middle of getting information from the configuration, but you'd have to do the same in C anyway. You could even just set a flag that the main loop would acknowledge, or post an event, or something.
Why not just throw a hangup exception and have the controlling code catch it and reload the config? That way the code using the config won't be running when you do the reload.

Zombywuf
Mar 29, 2008

tef posted:

:words:

Yeah, C's exception handling and generators work completely differently to Python's.

Zombywuf
Mar 29, 2008

Janin posted:

If generators do their work in has_next(), then what should happen when they raise an exception? Does it appear from the has_next() call? That's awfully awkward.

The generator is not "making a mess". Many generators have side effects, and it's important that the side effects happen at the prescribed time. I inserted the sys.exit() to prevent arguments about pre-caching results; often, the results themselves are unimportant and it's the side-effects of the generator that matter.

Calling sys.exit() from the middle of a generator is making a mess. Depending on order of evaluation of generators is to rely on spooky action at a distance. If you want side effect but no results, why are you using a generator? The clue is in the name, it generates output.

quote:

The issue with using a has_next()/get_next() style is that it's not as general as the current system. Any loop implemented with has/get_next() can be wrapped in a generator, but the converse is not true because the behavior of a generator allows unpredictable results.

code:
try:
  while True:
    do_stuff(mygen.next())
except GeneratorExit, e:
  pass
Is frankly vile. If you use the for ... in ... construct it makes no difference when an exception is thrown from the generator, nor if you use list comprehensions. The only thing I can think of this construct being good for is that it makes it slightly easier to implement your own generator class. However python doesn't seem to accept any old class with a next() method as a generator :-(.

Zombywuf
Mar 29, 2008

Janin posted:

If you want a language with carefully-managed side effect handling, use Haskell. The imperative nature of Python precludes stateless generators.
I never said the language should manage side effects. I said that if you're using generators for their side effects you're doing it wrong.

quote:

You are also ignoring that sys.exit() is just an example of a side effect; it could be anything else. Here's a simple coroutine example;
No I'm not, depending on side effects from a generator where the rest of your program interacts with those side effects during the generator's execution is a bad idea.

quote:

how would you implement this using has/get_next()? has_next() wouldn't be able to advance beyond the current point, because the generator requires a value from the yield statement to work.

PEP 342 effectively redefined next to mean send(None). Handling this case is just matter of having a "has next when sent a" function. This is easily handled with an optional argument on the has_next().

quote:

Shouldn't that code just use for..in?
Yes, my point is that you'll only ever see the behavior of using an exception to stop iteration if you do something badly wrong.

quote:

I don't understand what you mean, here. If you mean custom iterables, that's easy to do. If you mean actual custom generator classes, why on earth would you want to?

You probably wouldn't, yet the design seems to be geared around making it easier.

Zombywuf
Mar 29, 2008

code:
  BufferedReader br = new BufferedReader(new FileReader(fle.toString()));
Haha, Java you card.

Also, why the hell is the filename a string builder?

Zombywuf
Mar 29, 2008

Vanadium posted:

It worked for lisp

Really? Can't say I've seen evidence of this.


Prolog on the other hand...

Zombywuf
Mar 29, 2008

Lone_Strider posted:

code:
--------------------------------------------------------------------------
--Notes:Everytime u run this it will give u a new id so it can be used anywhere to
--get a unique ID for you Inserts,....
--Changes on:  Change Flag:
---------------------------------------------------------------------------------
ALTER  PROCEDURE [dbo].[spSelect_NextID]
as

SET NOCOUNT ON
 
begin 
 select NextID from dbo.tblNextID
 
 update dbo.tblNextID
 set NextID = NextID + 1 
end 
Return
Auto increment? @@IDENTITY? gently caress outta here with those, we got a key generating table :cool:

Be very careful here, there are legitimate reasons to do this. Although unless your db's default isolation level is serializable (and you db properly supports serializable (which it doesn't)) this is the wrong code to do it. There are two reasons to do this: the first is where keys must be unique across multiple tables (i.e. table1.key must never be equal to table2.key), the second is if you require sequential keys. If a transaction that has allocated a key for an identity column rolls back when there is another transaction active that has allocated the key after it, the rolled back transaction will leave a gap in the keys.

Of course if your system doesn't need either of these there is no reason for this function to exist and as I said, it's wrong.

The fix would be to set the isolation level to at least repeatable read and use an update lock table hint on tblNextID in the SELECT statement.

Zombywuf
Mar 29, 2008

rjmccall posted:

Language interpreters regularly end up like this, although "large functions" tends to be the least of the craziness. But if you're worried at all about interpreter performance, you really can't afford to make a function call per instruction or AST node.

Your compiler should decide when to inline the functions. It's probably better at it than you are.

Zombywuf
Mar 29, 2008

rjmccall posted:

This is excellent advice for general programming, but it's not so hot for core interpreter loops.

Get a better compiler or write it in asm. If you're second guessing your compiler's interpretation of instruction cache usage, you have a problem.

Adbot
ADBOT LOVES YOU

Zombywuf
Mar 29, 2008

floWenoL posted:

Oh, how cute, it's someone who hasn't ever needed to program for performance!

Never found I could do much better than just telling gcc to do a profiled build. Unless I did it in asm. If you're playing guess-what-the-compiler-will-do you're wasting time.

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