8.16.2010
GSoC's Over
Words by
Dan
Well, it was fun, but as of today it's pencils down. I've tagged my repo with a snapshot of my summer's work. I'll be continuing dev of this project so don't despair! In addition, I will probably be speaking at pdxfunc in October about the project. Hope to see you there!
8.05.2010
Abstraction is Complexity
Words by
Dan
I've been thinking more and more about the issues associated with abstraction. I am becoming convinced that abstraction is not always a good choice and certainly should not be taken lightly. When developing structures that other developers will rely upon, you're coding for a much more critical and savvy audience. Overly complex and needlessly heavy-handed code is always the wrong way to do it. Your efforts in API design might be completely destroyed because of a few small choices. Why wrap up simple things like object constructors, when you can expose them instead? Don't abstract unless you have to and when you do don't abuse the privilege.
I've been working with JS a lot more and I think the patterns used in that language to give the appearance of classical inheritance are terrible. Let the language be what it is, not what you wish it was. Most directly, I'm talking about a JS charting library. It is clearly an API designed around object configuration, not object manipulation. In my attempts to provide a simpler API for less experienced developers to use, I've discovered the quirks that are inherent to the choices its designers made. I believe there is too much data hiding. If I wanted to configure an object on the fly, I'll need to reconfigure the whole thing because the API hides my direct access to these configuration functions. I see no reason for these to be hidden, but for these reasons I will abandon my efforts to simplify things further.
API designers, please trust your users more. I've learned this lesson the hard way. It is better to keep an API simple and require the user to do a little more work, than to wrap it up in a leaky abstraction; and lets face it, all abstractions are leaky. If you're going to abstract something, make it opaque and simple! Too much sekret sauce might make things look nice, but when it all goes wrong it won't be pretty.
APIs should provide all functions that are needed to manipulate the underlying public data structures. Don't make things private unless you need to; In fact, don't make it private unless its for internal use only. For example, if you have a chart with axes, and there is an Axis constructor, make that public. Selfish API's don't make me want to use your library. We're using your code to make our lives simpler not harder. If you've gone out of your way to hide important details --I'm looking at you Javascript!-- no one will thank you.
Remember, you don't know what your audience is assuming, maybe its better not to assume at all. And in the case that you do keep assumptions in your code, list them out somewhere! Maybe seeing the number of assumptions made is a good exercise in facing the complexity you've created, since your users will also need to keep track of them too. Now, I will grant that this opinion is a bit harsh. The ideal is probably somewhere in between. Without assumptions code is tedious and tedium leads to mistakes. However, more is not always better so I will leave you with this thought: magic is capitalizing on assumptions, but the best tricks are usually the simplest.
I've been working with JS a lot more and I think the patterns used in that language to give the appearance of classical inheritance are terrible. Let the language be what it is, not what you wish it was. Most directly, I'm talking about a JS charting library. It is clearly an API designed around object configuration, not object manipulation. In my attempts to provide a simpler API for less experienced developers to use, I've discovered the quirks that are inherent to the choices its designers made. I believe there is too much data hiding. If I wanted to configure an object on the fly, I'll need to reconfigure the whole thing because the API hides my direct access to these configuration functions. I see no reason for these to be hidden, but for these reasons I will abandon my efforts to simplify things further.
API designers, please trust your users more. I've learned this lesson the hard way. It is better to keep an API simple and require the user to do a little more work, than to wrap it up in a leaky abstraction; and lets face it, all abstractions are leaky. If you're going to abstract something, make it opaque and simple! Too much sekret sauce might make things look nice, but when it all goes wrong it won't be pretty.
APIs should provide all functions that are needed to manipulate the underlying public data structures. Don't make things private unless you need to; In fact, don't make it private unless its for internal use only. For example, if you have a chart with axes, and there is an Axis constructor, make that public. Selfish API's don't make me want to use your library. We're using your code to make our lives simpler not harder. If you've gone out of your way to hide important details --I'm looking at you Javascript!-- no one will thank you.
Remember, you don't know what your audience is assuming, maybe its better not to assume at all. And in the case that you do keep assumptions in your code, list them out somewhere! Maybe seeing the number of assumptions made is a good exercise in facing the complexity you've created, since your users will also need to keep track of them too. Now, I will grant that this opinion is a bit harsh. The ideal is probably somewhere in between. Without assumptions code is tedious and tedium leads to mistakes. However, more is not always better so I will leave you with this thought: magic is capitalizing on assumptions, but the best tricks are usually the simplest.
8.02.2010
FusionSQL: Python and Google's Fusion Tables
Words by
Dan
This weekend I release a very alpha version of a library I'm working on for connecting with Fusion Tables. I think applications of Fusion Tables will become more interesting as the feature set is improved and they are integrated more with existing Google services. The client and associated libraries are very simple and it can be installed from pypi (assuming its actually up!). Here's a sample session:
As you can see it works much like a sql command line client; there is even tab completion for the keywords and table numbers (I'm working on a mapping between saner names and the numbers). In addition, you can using the FusionSQL class to connection and query FusionTables via the query function.
w00t!
> SHOW TABLES table id | name ---------------- 225017 | tests 224386 | neighborhoods_pdx_join.csv 224383 | neighborhoods_pdx.kml 224239 | PDX Crime Incident Data 2009 > DESCRIBE 224386 column id | name | type ----------------------- col0 | OBJECTID | number col1 | PERIMETER | number col2 | ASSN_ | number col3 | ASSN_ID | number col4 | NAME | location col5 | COMMPLAN | string col6 | SHARED | string col7 | COALIT | string col8 | CHECK_ | string col9 | HORZ_VERT | string > SELECT OBJECTID, PERIMETER, NAME FROM 224386 LIMIT 10 OBJECTID | PERIMETER | NAME ------------------------------------------------------- 1 | 74951.898437500000000 | ST. JOHNS 2 | 63622.199218750000000 | HAYDEN ISLAND 3 | 121064.000000000000000 | LINNTON 4 | 132532.000000000000000 | FOREST PARK/LINNTON 5 | 44036.101562500000000 | KENTON 6 | 188868.000000000000000 | FOREST PARK 7 | 16725.900390620001417 | BRIDGETON 8 | 35067.199218750000000 | EAST COLUMBIA 9 | 2857.860107420000077 | MC UNCLAIMED #2 10 | 26257.099609370001417 | CATHEDRAL PARK
As you can see it works much like a sql command line client; there is even tab completion for the keywords and table numbers (I'm working on a mapping between saner names and the numbers). In addition, you can using the FusionSQL class to connection and query FusionTables via the query function.
w00t!
Subscribe to:
Posts (Atom)