Bluish Coder

Programming Languages, Martials Arts and Computers. The Weblog of Chris Double.


2007-01-08

JSON Web Services with Factor

There's a post on Matt Croydon's weblog about using Lua to process JSON Web Services. The resulting Lua code is very easy to read. Here's my attempt at the same code in Factor:

REQUIRES: libs/http-client libs/json ;
USING: kernel io http-client json hashtables 
       prettyprint sequences math namespaces ;

[ 
  "http://local.yahooapis.com/MapsService/V1/" %
  "trafficData?appid=YahooDemo&street=" %
  "701+First+Street&city=Sunnyvale&state=CA" %
  "&output=json" %
] "" make http-get rot 200 = [
  nip json> 
  "Result" "ResultSet" rot hash hash
  1 swap [ 
    "Result: " write 
    >r dup . 1+ r> [
      swap write ": " write .
    ] hash-each
  ] each drop
] [
  2drop
] if

I split the URL up into a 'make' block so it wouldn't wrap in this weblog post. I could have used the long string itself. It looks ok and is readable if you know Factor but not as readable as the Lua example.

In Factor the tendancy is to factor things out into small words to make things more readable and to reduce the use of stack manipulation words. Here's a refactored version:

REQUIRES: libs/http-client libs/json ;
USING: kernel io http-client json hashtables 
       prettyprint sequences math namespaces 
       errors ;

: json-get ( url -- object )
  http-get rot 200 = [ 
    nip json> 
  ] [  
    "Could not process result" throw
  ] if ;

: hash-path ( hash seq -- object )
  swap [ swap hash ] reduce ;

: counted-each ( seq quot -- )
  #! Call the quotation for each element in
  #! the sequence. The quotation receives a count
  #! of the number of times the quotation has been called
  #! and should have stack effect ( element count -- ).
  0 -rot swap [ >r >r 1+ dup r> r> -rot call ] each-with drop ; 

: print-hashtable ( hash -- )
  [ swap write ": " write . ] hash-each ;

[ 
  "http://local.yahooapis.com/MapsService/V1/" %
  "trafficData?appid=YahooDemo&street=" %
  "701+First+Street&city=Sunnyvale&state=CA" %
  "&output=json" %
] "" make json-get { "ResultSet" "Result" } hash-path [
  "Result: " write . print-hashtable
] counted-each

While longer the result is some words that are immediately reusable in other contexts. Especially 'json-get', 'hash-path' and 'counted-each'. Anyone want to contribute a different Factor version in the comments below?

Please note that I didn't do this exercise to prove that language A is better than language B, it just gave me a chance to use the JSON library in Factor and see how usable it was. In fact I found a bug in my JSON implementation while doing it so you'll need the fixes from my repository:

darcs get http://www.bluishcoder.co.nz/repos/factor

Tags


This site is accessable over tor as hidden service 6vp5u25g4izec5c37wv52skvecikld6kysvsivnl6sdg6q7wy25lixad.onion, or Freenet using key:
USK@1ORdIvjL2H1bZblJcP8hu2LjjKtVB-rVzp8mLty~5N4,8hL85otZBbq0geDsSKkBK4sKESL2SrNVecFZz9NxGVQ,AQACAAE/bluishcoder/-61/


Tags

Archives
Links