Coding: Fleeting Thoughts

A place to discuss the implementation and style of computer programs.

Moderators: phlip, Moderators General, Prelates

User avatar
phlip
Restorer of Worlds
Posts: 7573
Joined: Sat Sep 23, 2006 3:56 am UTC
Location: Australia
Contact:

Re: Coding: Fleeting Thoughts

Postby phlip » Fri Feb 25, 2011 6:13 am UTC

Pop quiz: spot the problem in this code:

Code: Select all

blah *ptr = NULL;
try
{
  ptr = new blah();
  // code
}
__finally
{
  ptr = NULL;
  delete ptr;
}


Extra credit: guess how many times this exact pattern appears in the code I'm working on...

Code: Select all

enum ಠ_ಠ {°□°╰=1, °Д°╰, ಠ益ಠ╰};
void ┻━┻︵​╰(ಠ_ಠ ⚠) {exit((int)⚠);}
[he/him/his]

User avatar
Sc4Freak
Posts: 673
Joined: Thu Jul 12, 2007 4:50 am UTC
Location: Redmond, Washington

Re: Coding: Fleeting Thoughts

Postby Sc4Freak » Fri Feb 25, 2011 6:33 am UTC

Time to break out shared_ptr.

User avatar
phlip
Restorer of Worlds
Posts: 7573
Joined: Sat Sep 23, 2006 3:56 am UTC
Location: Australia
Contact:

Re: Coding: Fleeting Thoughts

Postby phlip » Fri Feb 25, 2011 6:36 am UTC

Hell, auto_ptr would've been enough. As it is, I just got rid of the "ptr = NULL" bit and left well alone.

Code: Select all

enum ಠ_ಠ {°□°╰=1, °Д°╰, ಠ益ಠ╰};
void ┻━┻︵​╰(ಠ_ಠ ⚠) {exit((int)⚠);}
[he/him/his]

wellingtonsteve
Posts: 49
Joined: Sun Apr 27, 2008 10:26 am UTC

Re: Coding: Fleeting Thoughts

Postby wellingtonsteve » Fri Feb 25, 2011 10:20 am UTC

phlip wrote:Pop quiz: spot the problem in this code:


I'm very new to C++ but the problem is that we're setting ptr to NULL before calling delete ptr, hence we've leaked away the memory that the blah intance comsumed and I assume delete won't like being asked to delete NULL. Also, could there somehow be an exception thrown in the try block before the new blah is even created and assigned? I can't see how, but this would definitely cause problems later on, even if you didn't have the ptr = NULL; line right?

What confuses me is this: Surely this fixes the problems I mentioned:

Code: Select all

__finally
{
  if(ptr != NULL) delete ptr;
}

Or have I missed soemthing? I don't understand what auto_ptr and shared_ptr are about... (*Googles them*)

User avatar
Sc4Freak
Posts: 673
Joined: Thu Jul 12, 2007 4:50 am UTC
Location: Redmond, Washington

Re: Coding: Fleeting Thoughts

Postby Sc4Freak » Fri Feb 25, 2011 10:55 am UTC

It's unnecessary, actually. Calling delete on NULL is legal and a no-op.

User avatar
phlip
Restorer of Worlds
Posts: 7573
Joined: Sat Sep 23, 2006 3:56 am UTC
Location: Australia
Contact:

Re: Coding: Fleeting Thoughts

Postby phlip » Fri Feb 25, 2011 1:24 pm UTC

wellingtonsteve wrote:Or have I missed soemthing? I don't understand what auto_ptr and shared_ptr are about... (*Googles them*)

They're classes based on the handy C++ feature that if you have an object on the stack, its destructor will be called as soon as it goes out of scope, however that happens... be it just running out the end of the block, or returning, throwing an exception... similar to a finally block, except built in to the object itself. So there's classes like std::auto_ptr, which wraps a pointer, and automatically deletes the pointer when the object is destroyed, so you can do something like:

Code: Select all

std::auto_ptr<foo> ptr(new foo());
// do stuff with *ptr
and then the "new foo()" will automatically get deleted when you're done. tr1::shared_ptr is similar, but you can have several pointers all pointing to the same object, and it won't get automatically deleted until all the shared_ptr objects are destroyed... essentially giving you a reference-counted GC.

See Wikipedia.

Code: Select all

enum ಠ_ಠ {°□°╰=1, °Д°╰, ಠ益ಠ╰};
void ┻━┻︵​╰(ಠ_ಠ ⚠) {exit((int)⚠);}
[he/him/his]

User avatar
Xeio
Friends, Faidites, Countrymen
Posts: 5101
Joined: Wed Jul 25, 2007 11:12 am UTC
Location: C:\Users\Xeio\
Contact:

Re: Coding: Fleeting Thoughts

Postby Xeio » Fri Feb 25, 2011 2:50 pm UTC

Sc4Freak wrote:It's unnecessary, actually. Calling delete on NULL is legal and a no-op.
Oh good, so it leaks everywhere and you don't get any errors at all (at least a compile warning I would hope?).

elminster
Posts: 1560
Joined: Mon Feb 26, 2007 1:56 pm UTC
Location: London, UK, Dimensions 1 to 42.
Contact:

Re: Coding: Fleeting Thoughts

Postby elminster » Fri Feb 25, 2011 6:09 pm UTC

It's annoying when trying to test something that requires network latency to test when you don't have remote server to put it on. I guess I could code/find some kind of proxy system that could simulate it.
Image

User avatar
Berengal
Superabacus Mystic of the First Rank
Posts: 2707
Joined: Thu May 24, 2007 5:51 am UTC
Location: Bergen, Norway
Contact:

Re: Coding: Fleeting Thoughts

Postby Berengal » Fri Feb 25, 2011 8:19 pm UTC

elminster wrote:It's annoying when trying to test something that requires network latency to test when you don't have remote server to put it on. I guess I could code/find some kind of proxy system that could simulate it.

A quick search gave me this: http://sourceforge.net/projects/wanem/
It is practically impossible to teach good programming to students who are motivated by money: As potential programmers they are mentally mutilated beyond hope of regeneration.

User avatar
Sc4Freak
Posts: 673
Joined: Thu Jul 12, 2007 4:50 am UTC
Location: Redmond, Washington

Re: Coding: Fleeting Thoughts

Postby Sc4Freak » Fri Feb 25, 2011 9:16 pm UTC

Xeio wrote:
Sc4Freak wrote:It's unnecessary, actually. Calling delete on NULL is legal and a no-op.
Oh good, so it leaks everywhere and you don't get any errors at all (at least a compile warning I would hope?).

No. There's nothing wrong with calling delete on a NULL pointer, and it's not indicative of a bug or memory leak.

Code: Select all

int* foo = NULL;
try
{
    foo = new int[5];
    /* do stuff that can throw */
}
catch(const std::exception& ex)
{
    /* log exception and continue */
}
delete [] foo;


It just saves you from having to check for NULL everywhere.

User avatar
Xeio
Friends, Faidites, Countrymen
Posts: 5101
Joined: Wed Jul 25, 2007 11:12 am UTC
Location: C:\Users\Xeio\
Contact:

Re: Coding: Fleeting Thoughts

Postby Xeio » Fri Feb 25, 2011 9:35 pm UTC

Sc4Freak wrote:No. There's nothing wrong with calling delete on a NULL pointer, and it's not indicative of a bug or memory leak.
Well, I'd think the compiler should go "hey, you just set this to null, and there is no possibility for it not to be null but you're trying to call delete on it, are you sure you meant to do that?".

User avatar
Thesh
Made to Fuck Dinosaurs
Posts: 6598
Joined: Tue Jan 12, 2010 1:55 am UTC
Location: Colorado

Re: Coding: Fleeting Thoughts

Postby Thesh » Fri Feb 25, 2011 9:46 pm UTC

Xeio wrote:
Sc4Freak wrote:No. There's nothing wrong with calling delete on a NULL pointer, and it's not indicative of a bug or memory leak.
Well, I'd think the compiler should go "hey, you just set this to null, and there is no possibility for it not to be null but you're trying to call delete on it, are you sure you meant to do that?".


There aren't a whole lot of warnings to begin with, and adding warnings for every stupidity (especially something not incredibly common, such as this) would be crazy.
Summum ius, summa iniuria.

User avatar
Xeio
Friends, Faidites, Countrymen
Posts: 5101
Joined: Wed Jul 25, 2007 11:12 am UTC
Location: C:\Users\Xeio\
Contact:

Re: Coding: Fleeting Thoughts

Postby Xeio » Fri Feb 25, 2011 10:37 pm UTC

Thesh wrote:There aren't a whole lot of warnings to begin with, and adding warnings for every stupidity (especially something not incredibly common, such as this) would be crazy.
That's exactly what needs to be done though, but a 3rd party tool to do so maybe a better option in most cases (we use ReSharper where I work for this).

User avatar
TheChewanater
Posts: 1279
Joined: Sat Aug 08, 2009 5:24 am UTC
Location: lol why am I still wearing a Santa suit?

Re: Coding: Fleeting Thoughts

Postby TheChewanater » Fri Feb 25, 2011 11:30 pm UTC

Oh yay, a Python rant!

Code: Select all

number=0

def next_number 
():
    global number
    number 
= number + 1
    return number

def return_next_number 
(argument = next_number ()):
    return argument

print return_next_number 
()
print return_next_number ()
print return_next_number () 


What you'd expect this to print:

Code: Select all

1
2
3


What it prints:

Code: Select all

1
1
1


Perhaps this is useful for some twisted reason the Python developers came up with, but I don't see why next_number() should only be called once. This is especially annoying if I'm creating an instance of some class as a default parameter, and I accidentally let every object have the same instance because of this.
ImageImage
http://internetometer.com/give/4279
No one can agree how to count how many types of people there are. You could ask two people and get 10 different answers.

User avatar
e^iπ+1=0
Much, much better than Gooder
Posts: 2065
Joined: Sun Feb 15, 2009 9:41 am UTC
Location: Lancaster

Re: Coding: Fleeting Thoughts

Postby e^iπ+1=0 » Sat Feb 26, 2011 12:07 am UTC

I've never seen anyone try something like that before.

Code: Select all

number=0

def next_number():
    global number
    number+=1
    return number

def return_next_number(foo):
    return foo

print return_next_number(next_number())
print return_next_number(next_number())
print return_next_number(next_number())

This works fine.
poxic wrote:You, sir, have heroic hair.
poxic wrote:I note that the hair is not slowing down. It appears to have progressed from heroic to rocking.

(Avatar by Sungura)

User avatar
You, sir, name?
Posts: 6983
Joined: Sun Apr 22, 2007 10:07 am UTC
Location: Chako Paul City
Contact:

Re: Coding: Fleeting Thoughts

Postby You, sir, name? » Sat Feb 26, 2011 12:49 am UTC

FT: In UNIX, you can use watch to periodically run anything. Not necessarily stuff you want to watch. It's less work than setting up a cron job or writing a loop.
I edit my posts a lot and sometimes the words wrong order words appear in sentences get messed up.

User avatar
Xanthir
My HERO!!!
Posts: 5426
Joined: Tue Feb 20, 2007 12:49 am UTC
Location: The Googleplex
Contact:

Re: Coding: Fleeting Thoughts

Postby Xanthir » Sat Feb 26, 2011 1:42 am UTC

TheChewanater wrote:Oh yay, a Python rant!

Agreed, it's pretty annoying. Particularly with seemingly simple code like:

Code: Select all

def foo(bar = []):
  ...stuff with bar...

...where the new list is shared between every function call.
(defun fibs (n &optional (a 1) (b 1)) (take n (unfold '+ a b)))

User avatar
Cleverbeans
Posts: 1378
Joined: Wed Mar 26, 2008 1:16 pm UTC

Re: Coding: Fleeting Thoughts

Postby Cleverbeans » Sat Feb 26, 2011 2:41 am UTC

TheChewanater wrote:Perhaps this is useful for some twisted reason the Python developers came up with, but I don't see why next_number() should only be called once.


The reasoning seems obvious to me, functions aren't procedures, they shouldn't alter state data. If you require a persistant variable between calls wrap it into a class and pass that as the default. Iterators and generators are the obvious way to do this sort of thing.
"Labor is prior to, and independent of, capital. Capital is only the fruit of labor, and could never have existed if labor had not first existed. Labor is the superior of capital, and deserves much the higher consideration." - Abraham Lincoln

User avatar
Xanthir
My HERO!!!
Posts: 5426
Joined: Tue Feb 20, 2007 12:49 am UTC
Location: The Googleplex
Contact:

Re: Coding: Fleeting Thoughts

Postby Xanthir » Sat Feb 26, 2011 2:44 am UTC

I'm not sure you understand the point of the example. The problem is that Python evaluates the next_number() function *once*, during the definition of the function, rather than every time the function is called. The point is that this introduces an unwanted shared variable between calls.

(I assume the example was just a stripped down trivial example rather than one from production code, as the precise thing the example is doing is indeed best done by iterators.)
(defun fibs (n &optional (a 1) (b 1)) (take n (unfold '+ a b)))

User avatar
hotaru
Posts: 1045
Joined: Fri Apr 13, 2007 6:54 pm UTC

Re: Coding: Fleeting Thoughts

Postby hotaru » Sat Feb 26, 2011 3:40 am UTC

Xanthir wrote:I'm not sure you understand the point of the example. The problem is that Python evaluates the next_number() function *once*, during the definition of the function, rather than every time the function is called. The point is that this introduces an unwanted shared variable between calls.

no, it doesn't. if you don't want the value shared between function calls, don't do it that way. the way it works really is the most obvious way to have it work. would you rather have this:

Code: Select all

a = 0

def f(foo = a):
    return foo

a = 42

print f()

print "42"?

Code: Select all

factorial product enumFromTo 1
isPrime n 
factorial (1) `mod== 1

User avatar
TheChewanater
Posts: 1279
Joined: Sat Aug 08, 2009 5:24 am UTC
Location: lol why am I still wearing a Santa suit?

Re: Coding: Fleeting Thoughts

Postby TheChewanater » Sat Feb 26, 2011 3:48 am UTC

The real version was more like this:

Code: Select all

class Bar:
  def __init__ (self):
    self.= 0
    self
.= 0


Code: Select all

class Foo:
  def __init__ (self, bar = Bar ()):
    self.bar = bar


Code: Select all

foo1 = Foo ()
foo2 = Foo ()

foo2.bar.= 0
foo2
.bar.= 5

print foo1
.bar.xfoo1.bar.y


This would print "0" and "5".
ImageImage
http://internetometer.com/give/4279
No one can agree how to count how many types of people there are. You could ask two people and get 10 different answers.

User avatar
phlip
Restorer of Worlds
Posts: 7573
Joined: Sat Sep 23, 2006 3:56 am UTC
Location: Australia
Contact:

Re: Coding: Fleeting Thoughts

Postby phlip » Sat Feb 26, 2011 7:12 am UTC

hotaru wrote:would you rather have this:

Code: Select all

a = 0

def f(foo = a):
    return foo

a = 42

print f()

print "42"?

Yes. It would be consistent with the closure behavior, if nothing else. It would also be consistent with other languages that use default parameters, like C++, where if you have "foo(param = expression)", the expression is evaluated each time the function is called without that parameter. In Python, go get this behaviour, you have to do:

Code: Select all

def foo(param = None):
  if param == None:
    param = expression
which is ugly, and doesn't allow you to handle an explicit None value (or rather, to handle an explicit None value you have to declare some other out-of-band value to use as your marker). Whereas, to get the Python behaviour in C++, you just need

Code: Select all

static const type param_defvalue = expression;
int foo(type param = param_defvalue)
which makes sense, as a global constant to store the default value is exactly what Python is doing hidden, behind the scenes.

Code: Select all

enum ಠ_ಠ {°□°╰=1, °Д°╰, ಠ益ಠ╰};
void ┻━┻︵​╰(ಠ_ಠ ⚠) {exit((int)⚠);}
[he/him/his]

0xBADFEED
Posts: 687
Joined: Mon May 05, 2008 2:14 am UTC

Re: Coding: Fleeting Thoughts

Postby 0xBADFEED » Sat Feb 26, 2011 7:20 pm UTC

phlip wrote:Yes. It would be consistent with the closure behavior, if nothing else. It would also be consistent with other languages that use default parameters, like C++, where if you have "foo(param = expression)", the expression is evaluated each time the function is called without that parameter. In Python, go get this behaviour, you have to do:

Code: Select all

def foo(param = None):
  if param == None:
    param = expression

which is ugly, and doesn't allow you to handle an explicit None value (or rather, to handle an explicit None value you have to declare some other out-of-band value to use as your marker). Whereas, to get the Python behaviour in C++, you just need


If you really, really want this behavior it's not hard to write a decorator that will give it to you. E.g.

Code: Select all

def defaults(**defaults):
    def wrapper(f):
        def wrap(*args, **kwargs):
            import copy
            for k,v in defaults.items():
                if k not in kwargs:
                    kwargs[k] = copy.copy(v)
            return f(*args, **kwargs)
        return wrap
    return wrapper

#then use like

@defaults(bar=[])
def foo(baz, bar):
    ...

This would give you fresh copies of the initial arguments for every call, but it's unidiomatic and ugly as hell.

EDIT
It occurs to me you could make this somewhat more palatable with a little more work using the 'inspect' module to automatically find default arguments.

Code: Select all

def copydefaults(f):
    import copy, inspect
    fspec = inspect.getargspec(f)
    defaults = fspec.defaults
    bindings = {}
    if defaults:
        names = fspec.args[len(fspec.args)-len(defaults):]
        bindings = dict(zip(names, defaults))
    def wrap(*args, **kwargs):
        for k,v in bindings.items():
            if k not in kwargs:
                kwargs[k] = copy.copy(v)
        print kwargs
        return f(*args, **kwargs)
    return wrap

#then use like

@copydefaults
def foo(bar, baz=[]):
    ....


Still unidiomatic as hell but slightly less ugly.
Last edited by 0xBADFEED on Sun Feb 27, 2011 8:56 pm UTC, edited 4 times in total.

User avatar
TheChewanater
Posts: 1279
Joined: Sat Aug 08, 2009 5:24 am UTC
Location: lol why am I still wearing a Santa suit?

Re: Coding: Fleeting Thoughts

Postby TheChewanater » Sat Feb 26, 2011 7:46 pm UTC

Code: Select all

def foo(bar = "DO NOT PASS THIS EXACT STRING AS BAR OR BAD THINGS WILL HAPPEN"):
  if bar is "DO NOT PASS THIS EXACT STRING AS BAR OR BAD THINGS WILL HAPPEN":
    self.bar = Bar ()
  else:
    self.bar = bar
 


EDIT: I'm also mad I can't do this:

Code: Select all

def foo (first, second = first):
  pass
ImageImage
http://internetometer.com/give/4279
No one can agree how to count how many types of people there are. You could ask two people and get 10 different answers.

User avatar
Link
Posts: 1419
Joined: Sat Mar 07, 2009 11:33 am UTC
Location: ᘝᓄᘈᖉᐣ
Contact:

Re: Coding: Fleeting Thoughts

Postby Link » Sun Feb 27, 2011 1:53 pm UTC

I'd use a dummy object with instance comparison rather than a string with value comparison. E.g.:

Code: Select all

class DefaultObject(object):
    pass

def foo(bar = DefaultObject()):
    if isinstance(bar, DefaultObject):
        # stuff

Still not as good as calling the constructor of the default argument every time, but less messy than reserving an arbitrary string.

User avatar
mister_m
Posts: 34
Joined: Fri Feb 04, 2011 2:51 am UTC

Re: Coding: Fleeting Thoughts

Postby mister_m » Thu Mar 03, 2011 9:00 pm UTC

Does anyone know anything about makefiles?

I am interested in learning about them a little bit, and employing them for tasks outside of simply compiling stuff. (for example, uploading a new version of a static website to a remote server). This seems interesting to me. Resources please!

User avatar
You, sir, name?
Posts: 6983
Joined: Sun Apr 22, 2007 10:07 am UTC
Location: Chako Paul City
Contact:

Re: Coding: Fleeting Thoughts

Postby You, sir, name? » Thu Mar 03, 2011 9:40 pm UTC

$ info make

There. Read.
I edit my posts a lot and sometimes the words wrong order words appear in sentences get messed up.

User avatar
b.i.o
Green is the loneliest number
Posts: 2519
Joined: Fri Jul 27, 2007 4:38 pm UTC
Location: Hong Kong

Re: Coding: Fleeting Thoughts

Postby b.i.o » Fri Mar 04, 2011 3:16 am UTC

mister_m wrote:(for example, uploading a new version of a static website to a remote server)

There are tools for this that won't make you want to murder things. If you have SSH access (and you should...), and are using any halfway-decent version control system you can either (in the case of a DVCS like git) push directly to your server, or (on your server) pull from your central repo. Or, you could just just scp or something I guess. But really, why would you use a makefile for this!?

User avatar
mister_m
Posts: 34
Joined: Fri Feb 04, 2011 2:51 am UTC

Re: Coding: Fleeting Thoughts

Postby mister_m » Fri Mar 04, 2011 4:44 pm UTC

b.i.o wrote:
mister_m wrote:(for example, uploading a new version of a static website to a remote server)

There are tools for this that won't make you want to murder things. If you have SSH access (and you should...), and are using any halfway-decent version control system you can either (in the case of a DVCS like git) push directly to your server, or (on your server) pull from your central repo. Or, you could just just scp or something I guess. But really, why would you use a makefile for this!?


I understand that I could do that, and also simply even use rsync (which I have been doing), but I am planning on migrating my website to a static site generator called Jekyll - which requires me to 'compile' markup files for posts and pages and layout files into static html pages that can be uploaded to a server.

User avatar
You, sir, name?
Posts: 6983
Joined: Sun Apr 22, 2007 10:07 am UTC
Location: Chako Paul City
Contact:

Re: Coding: Fleeting Thoughts

Postby You, sir, name? » Fri Mar 04, 2011 7:57 pm UTC

Wtf bug of the day:

Code: Select all

trit_t tryte_set(tryte_t a, int n, trit_t new) {
        tryte_t b = a;

        int p3 = 3;
        for(int i = 0; i < n; i++) {
                a -= a < 0 ? (-(-a+p3/2)%p3+p3/2) : ((a+p3/2)%p3 - p3/2);
                p3 *= 3;
        }

        return b - (a < 0 ? (-(-a + p3/2) % p3 + p3 / 2) : ((a+p3/2)%p3 - p3/2)) + new * p3/3;
}

...

for(int j = 6; j >= 0; j--) {
     printf("%d \n", tryte_set(9+3, 2, 1));
}


Completely deterministic, right? Same input should give the same output? Well, that was what I thought at any rate. What it prints is

Code: Select all

vlofgren@channeld:~/code/tun2/math$ ./test
-27
24
21
21
21
21
21
vlofgren@channeld:~/code/tun2/math$ ./test
69
21
21
21
21
21
21
vlofgren@channeld:~/code/tun2/math$ ./test
-27
24
21
21
21
21
21
vlofgren@channeld:~/code/tun2/math$ ./test
-123
27
21
21
21
21
21
vlofgren@channeld:~/code/tun2/math$ ./test
-171
27
21
21
21
21
21
vlofgren@channeld:~/code/tun2/math$ ./test
357
24
21
21
21
21
21



Ah, fuck, now I know what happened. Lingering .o-file. Figured it would be something like that.
I edit my posts a lot and sometimes the words wrong order words appear in sentences get messed up.

User avatar
headprogrammingczar
Posts: 3072
Joined: Mon Oct 22, 2007 5:28 pm UTC
Location: Beaming you up

Re: Coding: Fleeting Thoughts

Postby headprogrammingczar » Sat Mar 05, 2011 12:55 am UTC

And that, ladies and gentlemen, is why you should clean before recompiling.
<quintopia> You're not crazy. you're the goddamn headprogrammingspock!
<Weeks> You're the goddamn headprogrammingspock!
<Cheese> I love you

User avatar
TheChewanater
Posts: 1279
Joined: Sat Aug 08, 2009 5:24 am UTC
Location: lol why am I still wearing a Santa suit?

Re: Coding: Fleeting Thoughts

Postby TheChewanater » Sat Mar 05, 2011 12:57 am UTC

makefile fail?
ImageImage
http://internetometer.com/give/4279
No one can agree how to count how many types of people there are. You could ask two people and get 10 different answers.

User avatar
You, sir, name?
Posts: 6983
Joined: Sun Apr 22, 2007 10:07 am UTC
Location: Chako Paul City
Contact:

Re: Coding: Fleeting Thoughts

Postby You, sir, name? » Sat Mar 05, 2011 12:59 am UTC

Yeah, it wasn't keeping track of the headers as dependencies for the source files.

But it's such an uniquely characteristic problem that it was one of the first things I checked.
I edit my posts a lot and sometimes the words wrong order words appear in sentences get messed up.

User avatar
TheChewanater
Posts: 1279
Joined: Sat Aug 08, 2009 5:24 am UTC
Location: lol why am I still wearing a Santa suit?

Re: Coding: Fleeting Thoughts

Postby TheChewanater » Sat Mar 05, 2011 1:26 am UTC

Speaking of stupid mistakes, I'm currently writing a LISP interpreter. (No, that's not the mistake. Is it?)

Anyway, it was crashing whenever I tried to display a number. Half and hour of trying to make sense of debugger messages later, here's the culprit:

Code: Select all

string
NumberNode
::get_string ()
{
    string str;
    
    
// snip
    
    str
;
}
 

I guess I'm getting used to LISP-style return values.
ImageImage
http://internetometer.com/give/4279
No one can agree how to count how many types of people there are. You could ask two people and get 10 different answers.

User avatar
Area Man
Posts: 256
Joined: Thu Dec 25, 2008 8:08 pm UTC
Location: Local

Re: Coding: Fleeting Thoughts

Postby Area Man » Sat Mar 05, 2011 2:02 am UTC

I always recommend using at least -Wall when developing.
Better yet, add -pedantic -Wextra -Werror ; the compiler is your friend.
Bisquick boxes are a dead medium.

User avatar
Cleverbeans
Posts: 1378
Joined: Wed Mar 26, 2008 1:16 pm UTC

Re: Coding: Fleeting Thoughts

Postby Cleverbeans » Sat Mar 05, 2011 8:55 pm UTC

TheChewanater wrote:

Code: Select all

def foo(bar = "DO NOT PASS THIS EXACT STRING AS BAR OR BAD THINGS WILL HAPPEN"):
  if bar is "DO NOT PASS THIS EXACT STRING AS BAR OR BAD THINGS WILL HAPPEN":
    self.bar = Bar ()
  else:
    self.bar = bar
 



You could do this as well, assuming you didn't want to pass a function to bar that you don't want called immediately.

Code: Select all

class Foo:
   def __init__(self,bar = Bar):
      try:
         self.bar = bar.__call__()
      except:
         self.bar = bar


Desired behavior without reserving a token.


Code: Select all

[code=php]def foo (first, second = first):
  pass
[/quote]

Is this just to save typing foo(x,x) or does it have some practical value which escapes me?
"Labor is prior to, and independent of, capital. Capital is only the fruit of labor, and could never have existed if labor had not first existed. Labor is the superior of capital, and deserves much the higher consideration." - Abraham Lincoln

User avatar
Robert'); DROP TABLE *;
Posts: 730
Joined: Mon Sep 08, 2008 6:46 pm UTC
Location: in ur fieldz

Re: Coding: Fleeting Thoughts

Postby Robert'); DROP TABLE *; » Sat Mar 05, 2011 10:19 pm UTC

It means you can call foo(x,y), doesn't it?

Also, trying to write an RPG, and I've just found how useful delegates are.

Code: Select all

public Player()
        {
           /* ... */
            Skills.Add(
                new Skill()
                {
                    cost = 0,
                    name = "Death",
                    Function = delegate(Player P, Opponent A) { A.Health = A.Health * 0; }
                }
            );
        }
...And that is how we know the Earth to be banana-shaped.

User avatar
You, sir, name?
Posts: 6983
Joined: Sun Apr 22, 2007 10:07 am UTC
Location: Chako Paul City
Contact:

Re: Coding: Fleeting Thoughts

Postby You, sir, name? » Sun Mar 06, 2011 10:16 pm UTC

For some reason, I keep thinking of the modulo operation as incredibly slow (in C), and that

Code: Select all

a - b * (int) (a / b)

is much faster than

Code: Select all

a % b


I have no idea if there is truth to this, or if it's just some fixed idea.
I edit my posts a lot and sometimes the words wrong order words appear in sentences get messed up.

User avatar
headprogrammingczar
Posts: 3072
Joined: Mon Oct 22, 2007 5:28 pm UTC
Location: Beaming you up

Re: Coding: Fleeting Thoughts

Postby headprogrammingczar » Sun Mar 06, 2011 10:44 pm UTC

Obvious solution, compile both and examine the generated assembly code.
<quintopia> You're not crazy. you're the goddamn headprogrammingspock!
<Weeks> You're the goddamn headprogrammingspock!
<Cheese> I love you

bittyx
Posts: 194
Joined: Tue Sep 25, 2007 9:10 pm UTC
Location: Belgrade, Serbia

Re: Coding: Fleeting Thoughts

Postby bittyx » Sun Mar 06, 2011 11:01 pm UTC

You, sir, name? wrote:For some reason, I keep thinking of the modulo operation as incredibly slow (in C), and that

Code: Select all

a - b * (int) (a / b)

is much faster than

Code: Select all

a % b


I have no idea if there is truth to this, or if it's just some fixed idea.


Well that's relatively easy to test.

Code: Select all

#include <stdio.h>
#include <time.h>

#define MAX_N 1000000000

int main()
{
  int a=300, b=13, x; // it shouldn't really matter what a and b are
  long i;
  double sum=0;

  clock_t start, stop;

  start = clock();
  for ( i = 0; i <= MAX_N; i++)
  {
    x = a % b;
    sum += x;
  }
  stop = clock();

  printf("a %% b: %f\nsum: %f\n", (double) (stop - start) / CLOCKS_PER_SEC, sum);

  sum = 0;

  start = clock();
  for ( i = 0; i <= MAX_N; i++)
  {
    x = a - b * (int) (a / /b);
    sum += x;
  }
  stop = clock();

  printf("a - b * (int) (a / b): %f\nsum: %f\n", (double) (stop - start) / CLOCKS_PER_SEC, sum);

  return 0;
}


I compiled this with "gcc program.c -o program", ran it, and got:

Code: Select all

a % b: 11.700000
a - b * (int) (a / b): 11.710000

(I left out the sums from the output obviously).
Well, I ran it a few more times, and got the following:

Code: Select all

a % b:                   11.70  11.69  11.70  11.68  11.71
a - b * (int) (a / b):   11.72  11.70  11.70  11.70  11.71


Not much of a difference, your formula tends to be just a little bit worse. Tried compiling with "-O2" and got:

Code: Select all

a % b:                    1.75   1.75   1.76   1.76   1.75
a - b * (int) (a / b):    1.77   1.79   1.75   1.76   1.77


So with or without compiler optimization, your code seems to run just a little bit longer; it's a pretty negligible difference, though. I didn't have patience to run it on more than a billion passes, but as a rule of thumb, i tend to believe that basic (built-in) C operations have been optimized as much as they can already, so I try not to be a smart-ass about it. :D (Just kidding, no offense meant!)

Ninja edit: Or yeah, what headprogrammingczar said. Although, even taking into consideration the inaccuracies with using the clock() for measuring execution time, I think this is a fine comparison.


Return to “Coding”

Who is online

Users browsing this forum: No registered users and 9 guests