Here is where I plan to Blog Emacspeak tricks and introduce new features as I implement them.

Thursday, July 27, 2017

Data-Binding In Emacs Lisp: let-alist When Processing JSON Data

Data-Binding In Emacs Lisp: let-alist When Processing JSON Data

1 Summary

Module json-read consumes JSON data structures and transforms them
into their elisp equivalent, where JSON dictionaries become alists and
JSON arrays become vectors. Accessing that data from lisp would
ordinarily require using lisp accessors such as assoc, car andcdr. With let-alist, we get data-binding for free — the result
is elisp code that uses dotted-variables to directly access specific
slots in a deeply nested data structure. Thus, processing data
available as JSON via Web APIs is a really good use-case forlet-alist. Long-standing wish — I wish Emacs' JSON parsing were
implemented in native code rather than in elisp.

1.1 A Working Example

I recently implemented myself a NOAA Weather API Client — it pulls
the NOAA Weather Forecast (weekly and hourly) as JSON objects, and
produces an org-mode buffer that renders the data.
Note that though the above is part of a much largeremacspeak-wizards module, the above function and its dependencies
are themselves mostly independent of Emacspeak, except for the last
two forms in the weather forecast function.
Here is an annotated version of the function that gets NOAA data and
leverages let-alist to process the results:

In the above_ /gweb-my-address_ is a Lat/Lng pair as returned bygmaps-geocode defined in g-client/gmaps.el. That is used as the
default location for which we retrieve the forecast.

Parameter ask if non-nil results in the user being prompted
for the address — that address is then geocoded using
the Google Maps API.

The weather forecast display will leverage org-mode for
structured navigation; however we dont want that buffer to be
editable in general; moreover special-mode gives us nice
features such as q for quitting that window. So we usespecial-mode as the major mode, and orgstruct-mode as a minor
mode to get the best of both worlds.

The API call to NOAA results in a JSON data structure whereresult.properties.periods holds an array of forecast
objects. Using that result in let-alist gives us data binding
for free! Notice the following:

We can use .properties.periods in the cl-loop as the list
to iterate over.

Within that loop body, a second let-list enables data
binding over the forecast object that we are processing in the
loop body.

Data accesses inside the loop body are again simple given the
data binding created by the let-alist.

The code for generating the hourly forecast is similar in spirit —
the main take-away here is that let-alist saves a lot of
boiler-plate code that would have been otherwise required to take
apart the nested list structure we got back with our data.