3 ms·
Look at all the duplicated code in this python redis client: https://github.com/andymccurdy/redis-py/blob/13850b1b9ed34ee69b37a665b526ddea18860025/redis/client.
by seiji 16y ago
Look at all the duplicated code in this python redis client: https://github.com/andymccurdy/redis-py/blob/13850b1b9ed34ee69b37a665b526ddea18860025/redis/client.py#L852 https://github.com/andymccurdy/redis-py/blob/13850b1b9ed34ee... . The python version has duplicated 'self' tokens, 'def' tokens, arguments, execute_command, converting keys in each function, ...
Compare to the non-duplicated code in my Lisp redis client: https://github.com/mattsta/er/blob/681e4f91d0601d2997b2b5b7aad628f9b972595c/include/redis-cmds.lfe#L199 https://github.com/mattsta/er/blob/681e4f91d0601d2997b2b5b7a... . In the Lisp version, each redis-cmd-* call is a macro created by a macro which calls another macro to create the function in a polymorphic way.
You are one step closer to Lisp enlightenment.
- BrandonM 16y agoTo be fair, you could have done much the same thing in Python: basic_execute_command = { # snip ### SET COMMANDS ### "sadd": "Add ``value`` to set ``name``" , "scard": "Return the number of elements in set ``name``" , "sismember": "Return a boolean indicating if ``value`` is a member of set ``name``" , "smembers": "Return all members of the set ``name``" , "smove": "Move ``value`` from set ``src`` to set ``dst`` atomically" , "spop": "Remove and return a random member of set ``name``" , "srandmember": "Return a random member of set ``name``" , "srem": "Remove ``value`` from set ``name``" # snip } def _basic_execute_command (self, cmd): return lambda *args: self.execute_command(cmd.upper(), *args) # snip def __init__ (self, *args, **kwargs): # snip for cmd in self.basic_execute_command: self.__dict__[cmd] = self._basic_execute_command(cmd) # snip This is pretty memory-inefficient if you have several redis objects, but I'm sure you could come up with something better than what I hacked together in a few minutes. I know that Lisp ranks above Python on the metaprogramming scale, but simply adding easy object introspection can allow for cool factoring constructs that a Java (or similar) programmer wouldn't even consider. It's possible to make copy-pasta in any language.
- silentbicycle 16y agoYeah, if you can interpret a data structure at runtime, you don't need to write out the corresponding code at all. You could have all the redis connection instances share the same command dict, or make it a variable in the package.
- silentbicycle 16y agoThere's nothing specific to Lisp in that, though. I did something similar with my Lua redis client, sidereal (http://github.com/silentbicycle/sidereal/blob/master/sidereal.lua http://github.com/silentbicycle/sidereal/blob/master/siderea...): ---R: Return the string value of the key function Sidereal:get(key) end cmd("GET", "k") ---R: Set a key to a string returning the old value of the key function Sidereal:getset(key, value) end cmd("GETSET", "kv") ---R: Multi-get, return the strings values of the keys function Sidereal:mget(key_list) end cmd("MGET", "K") (The comment and function lines are only there for luadoc; it could just be the cmd lines.) FWIW, I need to update it - antirez changed the protocol in a recent version, and I haven't gotten back to it yet. It should remove a good portion of the code, though - he switched everything to using the bulk form.