Hacker Newsnew | past | comments | ask | show | jobs | submit | epper's commentslogin

> [...] The problem is with code reuse. The only real form of code reuse that OOP addresses is direct object inheritance. [...]

Inheritance is a form of code reuse in OOP. Composition is another one which is often preferred since it does not have the issues you mention here.

Note that just a couple of days ago this was posted on HN: http://userpage.fu-berlin.de/~ram/pub/pub_jf47ht81Ht/doc_kay... It's the definition that basically the inventor of Object Oriented Programming gave of OOP itself. One of the nice things he says is that he left out inheritance on purpose because he "didn't like it" the way it was done and wanted to "understand it better".

Regardless, I think your advice of learning other programming paradigms is great.


He does mention Dependency Injection briefly. Anyway Spring is just one option (e.g. Guice is another one).


True, I just dont like Google's take on Java so I dont use any of their libraries.


This is very cool! Have to look better into it, but it does not seem to be error tolerant. Hence here is a related approach to make error-tolerant this kind of typeahead search!!

Live demo: http://ipubmed.ics.uci.edu/

Paper: "Efficient interactive fuzzy keyword search" by Shengyue Ji, Guoliang Li, Chen Li, Jianhua Feng (UC Irvine & Tsinghua University)

scholar link: http://scholar.google.com/scholar?q=Efficient+interactive+fu...


> I'm sure there are tons of developers that can sort arrays like there is no tomorrow, but sometimes I would like to work with people that can create software.

Companies should search for developers that can do both.


Then they should focus on both during their interview process, right?


I agree with you that there should be focus on both during an interview process.

However I see no problem in a post/discussion/website focusing on a part of the interview process such as coding/algorithmic questions.


Yep, servers are in europe.

They say in their FAQ that their servers are in secure server farm in Switzerland, Germany and France.


Wuala: http://www.wuala.com

Data is encrypted with your password on the client side, your password never leaves your PC. They published a paper on their security implemenation: http://ieeexplore.ieee.org/xpl/freeabs_all.jsp?arnumber=4032...

It allows to synchronize multiple folders and it gives access to a certain number of previous versions. You can also share folders with friends, publicly or via a secret link.

It's cross-platform: Win, Mac, Linux.

I'm a happy customer since more than a year (it's free up to 2GB though) and I wonder why so few people know about it.


Problem with this approach is sharing and key management.

If you want to send something to someone, that means you need to securely communicate the key to them first or take the SpiderOak approach of "We guarantee security locally but if you share a file = file is shared unencrypted".


True, but if you both are friends on Wuala you can do it easily.

Provided that no man in the middle attacks take place during the "friendship" operation :)


First time I write in HN, but I really wanted to give my take on this.

I have to say that I really feel that to get readability, over nesting too, you often should refactor a bit the code.

I would in fact write the get_cached_user method by using separate methods and a @cache decorator. Every single function is very readable by itself.

(I'm not fluent in python, pseudo-python follows... but you should get the idea)

    def cache(function_to_cache):
        '''
        A Decorator that caches a function result
        '''
        def wrapper(param):
            cache_key = function_to_cache.name + " on " + param
            if cache.contains(cache_key):
                return cache.get(cache_key)
            else
                value = function_to_cache(param)
                cache.set(cache_key, value)
                return value
        return wrapper
    
    @cache
    def get_cached_user_by_id(id):
        return db.get_user_by_id(id)
    
    @cache
    def get_cached_user_by_username(username):
        return db.get_user_by_username(username)
        
    
    def get_cached_user(user_id = None, username = None):
        user = None
        if user_id:
            user = get_cached_user_by_id(user_id)
        else if username:
            user = get_cached_user_by_username(username)
        
        if not user:
            raise ValueError('User not found')
        
        return user


I don't think I'd want to maintain this bit of code although I'd prefer it to the mess of nesting in the original implementation. Each separate way of caching gets its own function which is ... ok I guess. Its explicit, which is pythonic, but overly verbose for multiple methods and we have to draw the line somewhere.

I think decorators are complex enough that I can't immediately look at the thing and know what its doing in the same way as early returns. A closure that takes a function pointer with some introspection magic is just a lot of mental juggling. At least with your case the complexity doesn't compound and is pushed as low as possible (as per Code Complete).

A final note: functions can have static members just like classes in python. fuction_to_cache.name would access the .name member of the function if such a thing existed (it will be an AttributeError? in this case). You are looking for function.__name__ I believe.


I don't think that decorators are too complex to be used usually... In python it should be a known and understood pattern and therefore it should not scare at all.

(Moreover it should handle multiple args, and there are better and more popular implementation such as @memoize)

However my assumption in this specific case is that the project is not small and therefore that decorator and this "pattern" could be used somewhere else too. If this is not the case I agree with you that it would just add too much complexity and it would hence be better to not have the decorator at all. The get_cached_user_by_username and get_cached_user_by_id would just handle the cache hit/miss by themselves.

Still it would be much more readable, because the main point I would say is to separate a long or too nested method in more methods.

    def get_cached_user_by_id(id):
        user = cache.get_user_by_id(id)
        if not user:
            user = db.get_user_by_id(id)
            cache.set_user(user)
        return user
    
    def get_cached_user_by_username(username):
        user = cache.get_user_by_username(username)
        if not user:
            user = db.get_user_by_username(username)
            cache.set_user(user)
        return user
    
    def get_cached_user(user_id = None, username = None):
        user = None
        if user_id:
            user = get_cached_user_by_id(user_id)
        else if username:
            user = get_cached_user_by_username(username)
        
        if not user:
            raise ValueError('User not found')
        
        return user

(Thanks for the .__name__ tip... I have not use python for a while)


Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: