Introducing WIG patterns

Diego Echeverri

Diego Echeverri

Oct 22, 2010

Reading time:

4 mins

Share via:

In my last post you learned how to use WIG to create bindings for 3rd party libraries. We introduced type combinators to express functions and member operators to define properties and methods. Although this is already an improvement over defining the bindings manually, it is not the only way of using WIG.

Configuration Objects

A common pattern in JavaScript libraries is using configuration objects. In JavaScript it is very common use the object literal syntax. One example may be the following1:

var myOptions = {
  zoom: 8,
  center: myLatlng,
  mapTypeId: google.maps.MapTypeId.ROADMAP
};

Most of the time, some properties are marked as "Required" (like the center property), and some are just optional properties. WIG provides you with a special function to make bindings for such cases.

let MapOptions =
    Pattern.Config "MapOptions"
        {
            Optional =
                [
                    "disableDefaultUI", T<bool>
                    // (...)
                ]
            Required =
                [
                    // The initial Map center. Required.
                    "center", LatLng.Type
                    // (...)
                ]
        }

This will generate a new class, where each of the optional members will get translated as getters and setters, and each of the required ones will become parameters in the constructor. This will save you from forgetting to set any of the required attributes, a tangible benefit over using plain JavaScript.

Enumerations

Another common pattern is using enumeration-like types. Here is an example from the Google Maps API that demonstrates this:

visibility | string | Visibility: Valid values: 'on', 'off' or 'simplifed'.

In WIG it is possible to generate types for those strings by using the following handy pattern:

let Visibility =
    Pattern.EnumStrings "Visibility" ["on"; "off"; "simplified"]

This will avoid tedious debugging sessions to discover any mistyped strings, and instead will provide you with IntelliSense to discover the possible values.

Building Your Own Patterns

All these patterns have been built using the class construct covered in my last post. This means that is possible to create your own patterns. For example, say you want an Enumeration pattern to cover integers instead of strings. It's possible to write something like:

let EnumInts n l =
    List.map (fun (x, i) -> (x, sprintf "%d" i)) l
    |> List.toSeq
    |> Pattern.EnumInlines n

Where EnumInlines works in a similar way to EnumStrings but receives an arbitrary string that will be inlined. It can be used in the following way:

let MediaError =
    Utils.EnumInts "MediaError" [
        "MEDIA_ERR_ABORTED", 1
        "MEDIA_ERR_NETWORK", 2
        "MEDIA_ERR_DECODE", 3
        "MEDIA_ERR_SRC_NOT_SUPPORTED", 4
    ]

Conclusions

WIG not only provides you with common patterns but it is also extensible. It allows you to define new patterns so you don't have to repeat yourself. This reduces the effort necessary to bind libraries significantly, and also allows you to reuse metabindings across libraries.


  1. Link is updated to the latest documentation.

Read more from

Can’t find what you were looking for? Drop us a line.

Diego Echeverri
Found a typo?

This blog post is hosted on GitHub here. Feel free to file a ticket or send a PR.

Newsletter

We will not spam you or give your details to anyone.