Coding: Fleeting Thoughts

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

Moderators: phlip, Moderators General, Prelates

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 » Thu May 19, 2011 12:05 am UTC

Steax wrote:/at the stage of picking salts, and tempted to use 64-character random strings

That's pretty standard.

Also, what are your favorite hashing algorithms, for security?

I'm looking at whirlpool for now. Hmm.

What's the use case? I'm not particularly familiar with whirlpool, but for certain use cases (like password hashing), I (and many others) consider it bad practice to use a general-purpose hashing algorithm, since they're specifically designed to be fast, and that means that an attacker doing a brute-force attack against you can calculate a lot of hashes very quickly, especially if they're using something like Amazon EC2 cluster GPU compute instances. Some hash algorithms (like bcrypt or scrypt) are specifically designed to be slow to calculate, meaning that brute-force attacks against them are very difficult. (Both also automatically do salting, so you don't have to worry about doing it manually.)

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 » Thu May 19, 2011 3:16 pm UTC

So does anyone else when they go into a code file to make a change make their goal to add the minimum number of code lines possible? Or even better refactor the internal stuff to reduce the number of lines while still making the change?

I always feel good about it when I run the final diff and I cut 100 lines off while still adding or improving the functionality. :mrgreen:

DaveInsurgent
Posts: 207
Joined: Thu May 19, 2011 4:28 pm UTC
Location: Waterloo, Ontario

Re: Coding: Fleeting Thoughts

Postby DaveInsurgent » Thu May 19, 2011 4:32 pm UTC

I don't go in to a change looking to alter lines of code. I go in looking at method complexity, total number of methods, repeated code, items that should be abstracted out or otherwise moved to a different (possibly new) class.

Overall reduction in lines of code may be one way to get a "good feeling" about what you've done, but I think it's a pretty shallow metric. I may have made something tremendously more readable, yet this added 3 net lines of code. Bad? Likewise, I may have actually taken a method and produced several smaller methods, but the overhead of the actual method delcaration caused an net increase in lines of code.

If you haven't alread, I strongly suggest reading Clean Code. http://www.amazon.ca/Clean-Code-Handbook-Software-Craftsmanship/dp/0132350882/ref=sr_1_1?ie=UTF8&s=books&qid=1305822692&sr=8-1

There are also other equally good books that I'm sure others would suggest. I happened upon this one first so I've stuck with it.

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 » Thu May 19, 2011 6:45 pm UTC

Xeio wrote:So does anyone else when they go into a code file to make a change make their goal to add the minimum number of code lines possible? Or even better refactor the internal stuff to reduce the number of lines while still making the change?

I always feel good about it when I run the final diff and I cut 100 lines off while still adding or improving the functionality. :mrgreen:

Yes, sometimes things can be simplified. But often refactoring something to have more lines makes it more readable. I don't think it should be your goal to reduce the number of lines, but if you see an somewhere where there's an obvious readable alternative, it's a good idea to change it.
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
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 » Thu May 19, 2011 6:55 pm UTC

TheChewanater wrote:Yes, sometimes things can be simplified. But often refactoring something to have more lines makes it more readable. I don't think it should be your goal to reduce the number of lines, but if you see an somewhere where there's an obvious readable alternative, it's a good idea to change it.
Well, we have style guidelines anyway (and I hate most of the code condensing tricks). I usually mean like "hey, I can turn this into a one line call because we have functions to do this built in". Though that's less common unless I'm working in some barely-touched really old file, or possibly written by someone who doesn't know the codebase well (like, we should almost never have to write SQL directly to fetch from the DB, which was one of the things I was stripping out today because we have calls to do exactly that).

Granted, there are a few code files that are downright ugly. 4200 lines, usually in some not very readable mess of functionality? When I have the chance I really try to refactor and trim those if possible (sometimes they are legitimately big though).

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

Re: Coding: Fleeting Thoughts

Postby Sc4Freak » Fri May 20, 2011 12:15 am UTC

Xeio wrote:So does anyone else when they go into a code file to make a change make their goal to add the minimum number of code lines possible? Or even better refactor the internal stuff to reduce the number of lines while still making the change?

I always feel good about it when I run the final diff and I cut 100 lines off while still adding or improving the functionality. :mrgreen:

Well okay, but please put those into two different commits. :P

Nothing worse than trying to find a change in a diff amidst a hundred other unrelated changes.

Posi
Posts: 111
Joined: Mon Jul 16, 2007 6:08 am UTC

Re: Coding: Fleeting Thoughts

Postby Posi » Fri May 20, 2011 7:13 am UTC

phlip wrote:All perl and no play makes Posi a dull boy.

Also: your code snippet works as expected for me... no nested arrays of any sort. Something weird is probably going on with your environment.

As typed out, it works as expected for me as well. However, in the app it does one the nested array thing in one specific case.

I am probably doing something silly, but I just don't know what. At this point, I don't really care to fix it anymore.

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 May 21, 2011 9:15 pm UTC

FT: Is is safe for me to assume other people's compilers will have <tr1/shared_ptr.h>? I just found out about it, and I prefer not to add external dependencies like Boost if I don't have to.
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
Sc4Freak
Posts: 673
Joined: Thu Jul 12, 2007 4:50 am UTC
Location: Redmond, Washington

Re: Coding: Fleeting Thoughts

Postby Sc4Freak » Sat May 21, 2011 11:32 pm UTC

Just use Boost. It's a header-only library so if you don't want people to go download Boost then just copy the headers you need and include them in your project.

EvanED
Posts: 4331
Joined: Mon Aug 07, 2006 6:28 am UTC
Location: Madison, WI
Contact:

Re: Coding: Fleeting Thoughts

Postby EvanED » Sat May 21, 2011 11:38 pm UTC

Depends how portable you want to be. Visual Studio 2005 doesn't have an official TR1 implementation at all; for 2008 it's an optional download (separate even from the service pack, and unavailable for the express editions). So on that front I'd say it's borderline.

Now, what you can do is use the TR1 headers as includes, and tell people that if they don't have a native TR1 to use the Boost-provided version. They have some wrappers that mean that if you include the right directory (boost/tr1 or something) in your include paths it will pull in the boost <shared_ptr.hpp> header and put shared_ptr into the std::tr1 namespace.

(I'm less a fan of Sc4Freak's idea to copy just the headers you need... even Boost's header-only libraries have a habit of including a crapton of their other headers. I wouldn't be at all surprised to see the transitive dependencies of <shared_ptr.hpp> pulling in 50 files.)

Edit: so for "fun" I decided to trace through Boost's shared_ptr header. I currently have 59 headers that might be pulled in by including <shared_ptr.hpp>; I haven't even traced transitive dependencies for 24 of them, and have also ignored a bunch of system-dependent headers included here and I suspect included eventually from somewhere in the config. (I closed the tab with that open.) Only 16 of those are shared_ptr.hpp itself or in the smart_ptr directory, and there are at least 15 different files or directories at the top level that have something included from them.

Here's my list:
Spoiler:
assert.hpp
checked_delete.hpp
current_function.hpp
config.hpp
config/no_tr1/memory.hpp
config/no_tr1/utility.hpp
config/select_complier_config.hpp
config/select_platform_config.hpp
config/select_stdlib_config.hpp
detail/workaround.hpp
exception/detail/attribute_noreturn.hpp
exception/exception.hpp
memory_order.hpp
mpl/if.hpp
non_type.hpp
preprocessor/list/for_each_i.hpp
shared_ptr.hpp
smart_ptr/bad_weak_ptr.hpp
smart_ptr/shared_ptr.hpp
smart_ptr/detail/lightweight_mutex.hpp
smart_ptr/detail/lwm_nop.hpp
smart_ptr/detail/lwm_pthreads.hpp
smart_ptr/detail/lwm_win32_cs.hpp
smart_ptr/detail/quick_allocator.hpp
smart_ptr/detail/shared_ptr_nmt.hpp
smart_ptr/detail/shared_count.hpp
smart_ptr/detail/sp_convertible.hpp
smart_ptr/detail/sp_counted_base.hpp
smart_ptr/detail/sp_counted_impl.hpp
smart_ptr/detail/sp_has_sync.hpp
smart_ptr/detail/spinlock.hpp
smart_ptr/detail/spinlock_pool.hpp
throw_exception.hpp
type_traits/alignment_of.hpp
type_traits/type_with_alignment.hpp

Didn't look at transitive dependencies from:
preprocessor/tuple/to_list.hpp
preprocessor/tuple/elem.hpp
preprocessor/tuple/rem.hpp
preprocessor/cat.hpp
preprocessor/list/transform.hpp
preprocessor/list/append.hpp
preprocessor/list/adt.hpp
preprocessor/repitition/for.hpp
preprocessor/arithmetic/inc.hpp
preprocessor/config/config.hpp
type_traits/is_pod.hpp
static assert.hpp
type_traits/detail/bool_trait_def.hpp
type_traits/detail/bool_trait_undef.hpp
type_traits/intrinsics.hpp
type_traits/detail/size_t_trait_def.hpp
type_traits/detail/size_t_trait_undef.hpp
mpl/aux_/value_wknd.hpp
mpl/aux_/static_cast.hpp
mpl/aux_/na_spec.hpp
mpl/aux_/lambda_support.hpp
mpl/aux_/config/integral.hpp
mpl/aux_/config/ctps.hpp
mpl/aux_/config/workaround.hpp


Long story short, I've tried to separate out something from boost in the past, and it was not even remotely worth it. One of my friends has said Boost has a tool that will do this automatically, but I don't know where it is and he's the only place I've ever heard of it, and even then it'd be only barely worth it.

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 » Sun May 22, 2011 2:49 am UTC

Sc4Freak wrote:Just use Boost. It's a header-only library so if you don't want people to go download Boost then just copy the headers you need and include them in your project.

I was using Boost at first, but EvanD pretty much summed up why I'm not anymore. tr1 is basically Boost, so it's probably not any better in that regard.

I tried writing my own template. Does anyone see any obvious mistakes?

Code: Select all

template<class T>
class ptr
{
    public:
        ptr (T* t)
            :    object (t),
                count (new unsigned int (1))
        {
        }
        
        template
<class OtherT>
        ptr (ptr<OtherT> const& other)
            :    object (other.object),
                count (other.count)
        {
            (*count)++;
        }
    
        ptr const
& operator= (ptr const& other)
        {
            (*count)--;
        
            if 
(!(*count))
            {
                delete object;
                delete count;
            }
        
            object 
= other.object;
            count = other.count;
        
            
(*count)++;
             
            return *
this;
        }
    
        T
& operator* ()
        {
            return *object;
        }
    
        T
* operator-> ()
        {
            return object;
        }
    
    
        
~ptr ()
        {
            (*count)--;
        
            if 
(!(*count))
            {
                delete object;
                delete count;
            }
        }

        T* object;
        unsigned int* count;
};
 
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
Sc4Freak
Posts: 673
Joined: Thu Jul 12, 2007 4:50 am UTC
Location: Redmond, Washington

Re: Coding: Fleeting Thoughts

Postby Sc4Freak » Sun May 22, 2011 3:28 am UTC

Don't. Smart pointers are extremely difficult to write correctly. tr1 or Boost, it doesn't matter so long as you're not writing your own!

Off the top of my head:
  • You don't provide const overloads, so you won't be able to use it as a const object
  • You don't provide any cast operators, so you can't do if(ptr) {}, and you also can't compare to NULL
    • Note that providing an implicit cast operator to bool is very dangerous because it allows you to write stuff like ptr * 10 and it'll compile
    • Providing a cast operator to a void* pointer (or whatever) is even more dangerous and breaks safety of your pointer
  • Your pointer is not thread safe: your class can explode if somebody simultaneously copies/assigns your smart pointer from multiple threads
  • You don't offer any way to break cyclic references (Boost provides weak_ptr)
  • Your constructor is not explicit, meaning you're going to allow implicit conversion from a normal pointer to a smart pointer
  • You don't define !=, ==, or < operator overloads
  • Your ptr<A> is not assignable to ptr<B> even if A* can be implicitly cast to B*

I'm sure there are lots of other problems I didn't spot, but the key is to use the standard library where possible (or failing that, Boost). In general, the people who write these libraries are a lot smarter than you or I.

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 » Sun May 22, 2011 3:46 am UTC

Sc4Freak wrote:Off the top of my head:
  • You don't provide const overloads, so you won't be able to use it as a const object
  • You don't provide any cast operators, so you can't do if(ptr) {}, and you also can't compare to NULL
    • Note that providing an implicit cast operator to bool is very dangerous because it allows you to write stuff like ptr * 10 and it'll compile
    • Providing a cast operator to a void* pointer (or whatever) is even more dangerous and breaks safety of your pointer

It provides operator*. "if (& *ptr) { ... }"
Sc4Freak wrote:
  • Your pointer is not thread safe: your class can explode if somebody simultaneously copies/assigns your smart pointer from multiple threads

  • Okay, that's a good point.
    Sc4Freak wrote:
  • You don't offer any way to break cyclic references (Boost provides weak_ptr)

  • Also a good point I should fix if I end up using this code.
    Sc4Freak wrote:[*] Your constructor is not explicit, meaning you're going to allow implicit conversion from a normal pointer to a smart pointer

    The constructor is intentionally explicit so I can write "ptr<A> a = new A".
    Sc4Freak wrote:[*] You don't define !=, ==, or < operator overloads

    operator* can be used to call the encapsulated object's operator==, or I could add an operator== in about 3 lines of code.
    Sc4Freak wrote:[*] Your ptr<A> is not convertible/compatible with ptr<B> even if A* can be implicitly cast to B*[/list]

    ptr<A> IS convertable to ptr<B> if A* can implictly cast to B*. The copy constructor is a template.

    Sc4Freak wrote:I'm sure there are lots of other problems I didn't spot, but the key is to use the standard library where possible (or failing that, Boost). In general, the people who write these libraries are a lot smarter than you or I.

    Well, the reason why I tried writing that is because the standard library doesn't actually have one (TR1 isn't standardized). If you have any suggestions that I can easily integrate into my project, I'd rather use them than write my own.
    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.

    EvanED
    Posts: 4331
    Joined: Mon Aug 07, 2006 6:28 am UTC
    Location: Madison, WI
    Contact:

    Re: Coding: Fleeting Thoughts

    Postby EvanED » Sun May 22, 2011 4:05 am UTC

    TheChewanater wrote:
    Sc4Freak wrote:Just use Boost. It's a header-only library so if you don't want people to go download Boost then just copy the headers you need and include them in your project.

    I was using Boost at first, but EvanD pretty much summed up why I'm not anymore. tr1 is basically Boost, so it's probably not any better in that regard.

    TR1 has a huge advantage over Boost from the get-go, which is that you almost always use the standard library provided with your compiler, which means that the code doesn't need to work with several different compilers. Boost needs to be portable across compilers and compiler versions.

    Beyond that, the standard library writers seem to be better able to contain themselves. If your library has MPL, who could resist using it? So some of the "almost all headers in the Boost library" pull in the MPL. GCC 4.6 pulls in 111 headers when you use <tr1/memory>... but then again, it pulls in 134 if you include <iostream>, and 98 if you include plain <memory>. Further, the reason the number of headers matters was to argue against trying to separate Boost from Boost.

    BTW, <boost/shared_ptr.hpp> pulls in 128 headers on GCC under Linux. (I thought of a way to get these counts automatically, though it's not counting quite the same thing I was before.)

    TheChewanater wrote:
    Sc4Freak wrote:Off the top of my head:
    • You don't provide const overloads, so you won't be able to use it as a const object
    • You don't provide any cast operators, so you can't do if(ptr) {}, and you also can't compare to NULL
      • Note that providing an implicit cast operator to bool is very dangerous because it allows you to write stuff like ptr * 10 and it'll compile
      • Providing a cast operator to a void* pointer (or whatever) is even more dangerous and breaks safety of your pointer

    I provide operator*. "if (& *ptr) { ... }"

    No offense, but my god is that ugly, in addition to technically incorrect. (What if the pointed-to type overloads operator&?)

    Sc4Freak wrote:[*] Your constructor is not explicit, meaning you're going to allow implicit conversion from a normal pointer to a smart pointer

    The constructor is intentionally explicit so I can write "ptr<A> a = new A".

    That's a very questionable decision in my and many other's opinions. ptr<A> a(new A); is only slightly less ugly, and you gain much more safety from hard-to-find mistakes.

    Sc4Freak wrote:[*] You don't define !=, ==, or < operator overloads

    operator* can be used to call the encapsulated object's operator==, or I could add an operator== in about 3 lines of code.

    The encapsulated object's operator == doesn't do the same thing, and sure, you could fix all these things, but why not use an implementation that exists and is probably one of the most well-tested C++ code bases out there?

    Well, the reason why I tried writing that is because the standard library doesn't actually have one (TR1 isn't standardized). If you have any suggestions that I can easily integrate into my project, I'd rather use them than write my own.

    TR1 is a standard, and I'm with sc4freak in saying "if your system doesn't provide TR1 then use Boost's substitution" is way better than rolling your own.

    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 » Sun May 22, 2011 4:22 am UTC

    EvanED wrote:TR1 is a standard, and I'm with sc4freak in saying "if your system doesn't provide TR1 then use Boost's substitution" is way better than rolling your own.

    Okay. This isn't a serious project, so I guess it doesn't matter if it won't work with some outdated compilers.
    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.

    EvanED
    Posts: 4331
    Joined: Mon Aug 07, 2006 6:28 am UTC
    Location: Madison, WI
    Contact:

    Re: Coding: Fleeting Thoughts

    Postby EvanED » Sun May 22, 2011 4:26 am UTC

    You're also ignoring part of what I'm saying. Even if someone is trying to compile with an outdated complier that doesn't have TR1, all they have to do is add boost/tr1 to their include paths and your #include <tr1/memory>s and std::tr1::shared_ptrs will still work, just with the Boost-provided implementations.

    IMO at this point in time that's the best of both worlds.

    User avatar
    Dason
    Posts: 1311
    Joined: Wed Dec 02, 2009 7:06 am UTC
    Location: ~/

    Re: Coding: Fleeting Thoughts

    Postby Dason » Mon May 23, 2011 10:09 pm UTC

    I really like RStudio but I wish it had support for either emacs or vi style keybindings.
    double epsilon = -.0000001;

    User avatar
    llamanaru
    Posts: 241
    Joined: Sat May 01, 2010 2:40 am UTC
    Location: Colorado

    Re: Coding: Fleeting Thoughts

    Postby llamanaru » Wed May 25, 2011 12:08 am UTC

    Is there any way to automatically download every file in a directory on an http server like you can with ftp?

    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? » Wed May 25, 2011 12:15 am UTC

    llamanaru wrote:Is there any way to automatically download every file in a directory on an http server like you can with ftp?


    Depends on whether the http server allows indexing. If so, just build an URL scraper and traverse the directory structure. Or find some program that does the same.
    I edit my posts a lot and sometimes the words wrong order words appear in sentences get messed up.

    User avatar
    llamanaru
    Posts: 241
    Joined: Sat May 01, 2010 2:40 am UTC
    Location: Colorado

    Re: Coding: Fleeting Thoughts

    Postby llamanaru » Wed May 25, 2011 12:32 am UTC

    I feel stupid now. Thanks YSN.

    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? » Wed May 25, 2011 12:49 am UTC

    Of course it wouldn't surprise me if wget was smart enough to do that automagically.
    I edit my posts a lot and sometimes the words wrong order words appear in sentences get messed up.

    User avatar
    llamanaru
    Posts: 241
    Joined: Sat May 01, 2010 2:40 am UTC
    Location: Colorado

    Re: Coding: Fleeting Thoughts

    Postby llamanaru » Wed May 25, 2011 12:55 am UTC

    Now I feel more stupid. Again. Thanks. (it was wget -r path/to/directory/ that did it for me.)

    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 » Wed May 25, 2011 6:39 am UTC

    Is the following piece of code understandable? Would you balk if you encountered it in the wild or is it a perfectly valid way of doing what it's trying to do?

    Code: Select all

    outerLoop:
    for (List<Foo> foo: foos) {

        List<Bar> bars = getBars(foo);

        for (Bar bar: bars) {
            pauseLoop:
            while(true) {
                switch (checkEnvironmentState()) {
                case PAUSE:
                    pause();
                    break;
                case STOP:
                    break outerLoop;
                case CONTINUE:
                    break pauseLoop;
                }
            }
            doStuff(bar);
        }
    }
    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
    phlip
    Restorer of Worlds
    Posts: 7572
    Joined: Sat Sep 23, 2006 3:56 am UTC
    Location: Australia
    Contact:

    Re: Coding: Fleeting Thoughts

    Postby phlip » Wed May 25, 2011 6:49 am UTC

    I'd probably rewrite it as something like:

    Code: Select all

    while (checkEnvironmentState() == PAUSE) pause();
    if (checkEnvironmentState() == STOP) break outerLoop;

    It's not strictly the same (what with checkEnvironmentState being called twice... which should be fine if it's a simple getter, but if it's something more complicated you should check for possible race-conditions, or possible failures if it'll only return STOP once). If you need something more robust:

    Code: Select all

    EnvironmentState state;
    while ((state = checkEnvironmentState()) == PAUSE) pause();
    if (state == STOP) break outerLoop;

    which I think is equivalent to your while(true){switch}. But I'd prefer the first one if it was acceptable... it just seems more readable.

    I'd also consider pulling the loops out into their own function if they're not already, so I could use "return" instead of "break outerLoop", but that's just a matter of taste.

    [edit]
    Another possibility to consider... I'm not saying this is better, just another option to consider:

    Code: Select all

    void handleEnvironmentState() {
      EnvironmentState state;
      while ((state = checkEnvironmentState()) == PAUSE) pause();
      if (state == STOP) throw new EnvironmentAbortException();
    }
    And then catch that wherever is appropriate. In this context, as its own function, I wouldn't even necessarily be averse to the while(true){switch} thing:

    Code: Select all

    void handleEnvironmentState() {
      while (true) {
        switch (checkEnvironmentState()) {
        case PAUSE:
          pause();
          break;
        case STOP:
          throw new EnvironmentAbortException();
        case CONTINUE:
          return;
        }
      }
    }


    [edit 2]
    Also also, if you're going to have "pause(); break;" in your code, you need to find a way to make reference to this in a comment somewhere.

    Code: Select all

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

    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 » Wed May 25, 2011 10:43 am UTC

    checkEnvironmentState, while in theory just a getter (depending on the hidden variable "time"), is crazy expensive, and also cannot be assumed to be referentially transparent even if time is considered to be an explicit parameter, so it can only really be safely called once each iteration. This is why it's in the "while(true) {switch}" construct, as I feel slightly less icky writing that than introducing more mutable state (something I suspect may be considered weird by many, especially as it's a very local state). Also, I just like code to be decomposable; the "while (); if()" are intrinsically linked but syntactically independent, while in the "while(true) {switch}" the loop and the switch are independent in that they both make sense on their own. Does this make sense, or am I rambling?

    I did also consider using functions instead of labeled breaks, but the problem with that, given that I use the switch construct, it's cumbersome to replace two different labeled breaks using only return. You'd have to return a boolean telling the outer function if it should return as well or not. Even if that weren't a problem, I'm not a big fan of making functions just to make a new control structure available. Enter exceptions, which would solve the issue with labeled breaks and the switch, and I think the non-locality and extra names make this route definitely lose out to the labeled breaks.

    Eh, now I don't really see the difference in approaches anymore. It's all just code, and it all means the same anyway. I guess I thought that since it's such a small piece of code it would be easier to analyze different approaches that clearly do the same and perhaps figure out what's more legible, but since it's such a short piece of code all approaches are perfectly legible anyway.
    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.

    sheynfinkel
    Posts: 12
    Joined: Sun May 22, 2011 12:22 am UTC

    Re: Coding: Fleeting Thoughts

    Postby sheynfinkel » Wed May 25, 2011 5:29 pm UTC

    java sucks...

    User avatar
    broken_escalator
    They're called stairs
    Posts: 3312
    Joined: Tue Mar 23, 2010 1:49 am UTC
    Location: _| ̄|○

    Re: Coding: Fleeting Thoughts

    Postby broken_escalator » Wed May 25, 2011 5:36 pm UTC

    Before I pour through documentation I figured I'd ask here if anyone knows of a try/catch type system for SAS.

    I'm switching around dates but also keeping an eye out for bad data. Problem is when its found it tends to make a mess of my log letting me know the bad data is bad data. Nothing breaks, I'd just like to suppress it or at least not make a huge mess. I think the closest thing I know is an options to lower the amount of errors displayed.

    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 » Wed May 25, 2011 8:46 pm UTC

    Berengal wrote:Is the following piece of code understandable? Would you balk if you encountered it in the wild or is it a perfectly valid way of doing what it's trying to do?

    Code: Select all

    outerLoop:
    for (List<Foo> foo: foos) {

        List<Bar> bars = getBars(foo);

        for (Bar bar: bars) {
            pauseLoop:
            while(true) {
                switch (checkEnvironmentState()) {
                case PAUSE:
                    pause();
                    break;
                case STOP:
                    break outerLoop;
                case CONTINUE:
                    break pauseLoop;
                }
            }
            doStuff(bar);
        }
    }

    IMO it's clearer what this code is meant to do, assuming you have better variable names.

    Code: Select all

    bool timeToStop = fale;

    for (List<Foo> foo = foos.head; foo != null && !timeToStop; foo = foo.next) {

        List<Bar> bars = getBars(foo);

        for (Bar bar: bars) {
            bool timeToContinue = false
            
            while
    (!timeToContinue && !timeToStop) {
                switch (checkEnvironmentState()) {
                case PAUSE:
                    pause();
                    break;
                case STOP:
                    timeToStop = true;
                    break;
                case CONTINUE:
                    timeToContinue = true;
                    break;
                }
            } 
            doStuff
    (bar);
        }
    }
     
    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.

    sheynfinkel
    Posts: 12
    Joined: Sun May 22, 2011 12:22 am UTC

    Re: Coding: Fleeting Thoughts

    Postby sheynfinkel » Wed May 25, 2011 11:06 pm UTC

    I use emacs on linux machine and I have a horrible time copying and pasting code to coding sites, in particular stackoverflow. That site never indents the code properly and I wind up spending half and hour editing and re-editing. Is it just me? Does anyone know what I can do to fix this? Sites like pastebin and hpaste work okay so I normally provide a link to those but still, I'd like to be able to do this effortlessly.

    ryanelm
    Posts: 4
    Joined: Thu May 26, 2011 8:25 am UTC

    Life is difficult

    Postby ryanelm » Thu May 26, 2011 8:27 am UTC

    a='5';
    a + 5; // == '55';
    a - -5; // == 10

    User avatar
    Steax
    SecondTalon's Goon Squad
    Posts: 3038
    Joined: Sat Jan 12, 2008 12:18 pm UTC

    Re: Coding: Fleeting Thoughts

    Postby Steax » Thu May 26, 2011 8:35 am UTC

    So, throwing away all old singleton code,

    Code: Select all


    $db 
    = new Database();

    class Manager{
       
    function foo(){
          global $db;
         
     $db->something();
       }
    }
     


    I tried passing objects in arguments,

    Code: Select all


    $db 
    = new Database();

    class Manager{
       
    function foo(Database $someDB){
          $someDB->something();
       }
    }

    $someManager = new Manager();
    $someManager->foo($db);
     


    But this meant a lot of awkward remembering of argument lists. Passing them in constructors, like so


    Code: Select all


    $db 
    = new Database();

    class Manager{
       
    private $dbObject;
       
    function __construct(Database $someDB){
          $this->dbObject = $someDB;
       }
       
       
    function foo(){
          $dbObject->something();
       }
    }

    $someManager = new Manager($db);
    $someManager->foo();
     


    Works, but then I get into awkwardly trying to order declarations around, because I can't pass in a new object before defining it. That causes headaches with tossing around which class is dependent on what, and it still has argument headaches as I have to remember the correct order in the constructor. And I can't just pass an Array of all other objects, since they need to be defined.

    So...

    I decide passing a list of all manager objects in my program, and do so in a function (rather than constructor), so I can define all of them first. Then this function adds in links from each manager object to every other one, and then I can use these links within functions to access whatever managers I need.

    It certainly fixes the other problems, and it allows for easy unit testing (just pass a new fresh array of managers for each test). But is there anything I'm overlooking?

    Code: Select all


    $db 
    = new Database();
    $links = Array();
    $links['db'] = $db;

    class Base{
       
    protected $managers = Array();
       
       
    function init($objects){
          $this->managers = $objects;
       }
    }

    class Manager extends Base{
       
    function foo(){
          $this->links['db']->something();
       }
    }

    $someManager = new Manager();
    $someManager->init($links);
    $someManager->foo();

     


    Someone tell me if I'm doing this right. Every time I check some other sample code, example or project, they'll have their own little flavor of madness...
    In Minecraft, I use the username Rirez.

    Pepve
    Posts: 57
    Joined: Wed Jul 28, 2010 9:47 am UTC

    Re: Coding: Fleeting Thoughts

    Postby Pepve » Thu May 26, 2011 9:09 am UTC

    I think you're looking for dependency injection. Google link.

    User avatar
    Steax
    SecondTalon's Goon Squad
    Posts: 3038
    Joined: Sat Jan 12, 2008 12:18 pm UTC

    Re: Coding: Fleeting Thoughts

    Postby Steax » Thu May 26, 2011 12:15 pm UTC

    See, this is what I get for not classes. I miss out on all the cool terms.

    So I guess what I'm doing is practically a blanket dependency injection, yes? I give each object a link to the other objects, instead of individually setting the inner variables. I don't really know if what I'm doing is much slower than doing so individually, but my current method takes up so little time. Since PHP passes around object pointers (okay, not pointers, but yeah, that) anyway, I don't think there's too much overhead.

    What worried me was classes holding links to themselves. I wonder if that's not really a good idea...
    In Minecraft, I use the username Rirez.

    Posi
    Posts: 111
    Joined: Mon Jul 16, 2007 6:08 am UTC

    Re: Coding: Fleeting Thoughts

    Postby Posi » Fri May 27, 2011 2:41 am UTC

    Posi wrote:
    phlip wrote:All perl and no play makes Posi a dull boy.

    Also: your code snippet works as expected for me... no nested arrays of any sort. Something weird is probably going on with your environment.

    As typed out, it works as expected for me as well. However, in the app it does one the nested array thing in one specific case.

    I am probably doing something silly, but I just don't know what. At this point, I don't really care to fix it anymore.


    Actually, I figured it out. Something apparently important that I forgot to mention was that it was a object method.

    Code: Select all

    #Therefore the call was this
    my @ss = $ome_object->method_that_returns_a_list()
    #and not this
    my @ass = method_that_returns_a_list()


    When Perl sees you try to assign a scalar to a list, it will automagically create a new list for you and jam your scalar in the first spot. However, my scalar was actually a list, so it made a new list put and jammed my list in the first spot.

    So the proper fix was to cast the list back to a list:

    Code: Select all

    my @ass = @{$ome_object->method_that_returns_a_list()}

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

    Re: Coding: Fleeting Thoughts

    Postby headprogrammingczar » Fri May 27, 2011 11:22 am UTC

    That's a dereference, not a cast, but at least it works.
    <quintopia> You're not crazy. you're the goddamn headprogrammingspock!
    <Weeks> You're the goddamn headprogrammingspock!
    <Cheese> I love you

    User avatar
    MHD
    Posts: 630
    Joined: Fri Mar 20, 2009 8:21 pm UTC
    Location: Denmark

    Re: Coding: Fleeting Thoughts

    Postby MHD » Sat May 28, 2011 2:52 am UTC

    Comment parsing in monadic parser combinators is killing my family.

    Code: Select all

    char :: Char -> Parser ()
    many_ :: Parser a -> Parser ()
    notChar :: Char -> Parser Char

    comment :: Parser ()
    comment = do char '#'
                 (char '(' >> multiLine) <|> (lineComm)
      where lineComm = many_ (notChar '\n')
            multiLine = do { char ')'; char '#' <|> multiLine } <|> do { many_ (notChar ')'); multiLine }


    This will parse mighty fine all the empty comments, but fails everywhere else.

    EDIT: Think there might be a bug in my parser lib... Fuck.
    EvanED wrote:be aware that when most people say "regular expression" they really mean "something that is almost, but not quite, entirely unlike a regular expression"

    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 May 28, 2011 12:16 pm UTC

    I assume your comment format is:

    Code: Select all

    # single line comment
    #( multi-line
    comment )


    I can't make heads or tails of what multiLine actually does, but it doesn't parse any sort of structure that I recognize. I suggest you start that definition over and see if something more reasonable comes out.
    <quintopia> You're not crazy. you're the goddamn headprogrammingspock!
    <Weeks> You're the goddamn headprogrammingspock!
    <Cheese> I love you

    User avatar
    chridd
    Has a vermicelli title
    Posts: 843
    Joined: Tue Aug 19, 2008 10:07 am UTC
    Location: ...Earth, I guess?
    Contact:

    Re: Coding: Fleeting Thoughts

    Postby chridd » Sat May 28, 2011 3:56 pm UTC

    headprogrammingczar wrote:I assume your comment format is:

    Code: Select all

    # single line comment
    #( multi-line
    comment )
    The multiline format appears to be

    Code: Select all

    #( multi-line
    comment )#
    so if it encounters a close parenthesis not followed by a #, the comment continues.
    ~ chri d. d. /tʃɹɪ.di.di/ (Phonotactics, schmphonotactics) · she · Forum game scores
    mittfh wrote:I wish this post was very quotable...

    sheynfinkel
    Posts: 12
    Joined: Sun May 22, 2011 12:22 am UTC

    Re: Coding: Fleeting Thoughts

    Postby sheynfinkel » Sat May 28, 2011 4:16 pm UTC

    Using bash I get tab completion with:

    Code: Select all

    $ mv * /usr--tab_complete

    and

    Code: Select all

    $ sudo mv /usr--tab_complete

    but not

    Code: Select all

    $ sudo mv * /usr--nothing


    Anyone know why that is?
    I'd ask this in the Help Desk forum but they don't have a thread for small simple questions.

    Pepve
    Posts: 57
    Joined: Wed Jul 28, 2010 9:47 am UTC

    Re: Coding: Fleeting Thoughts

    Postby Pepve » Sat May 28, 2011 7:51 pm UTC

    I'm presuming you're using a Debian-based distro. I tested it and got the same result. Then i looked at /etc/bash_completion (which is... 1700 lines). I don't really understand what's going on there, but they are doing something special to sudo completion. I think this may be a bug in the sudo handling. Their website has info on reporting bugs.


    Return to “Coding”

    Who is online

    Users browsing this forum: No registered users and 7 guests