Simply Jonathan

Archive for August 2016

Mediany

Tonight I’ve published Mediany, a small JavaScript library I’ve been working on. It’s released under the MIT License.

Mediany allows you to declare behaviour at different media query breakpoints. This allows you to e.g. have one thing happen when a button is clicked at one screen size, and something else (or something additional) happen when it is clicked at another screen size.

I built this to scratch my own itch. With responsive web design, it has become customary to transform the design based on the screen size of the user’s viewport – rearrange elements into columns, show things that were previously hidden, etc. (Media queries have a great many additional things to check for, but checking screen size – and width in particular – is the most common use case.)

As one transforms the design to fit larger sizes, I found that I also need to modify the behaviour. Clicking a button might require some set of changes at a small size, and something else entirely at a larger screen size. Mediany helps this process by declaring behaviour at specific media queries.

What’s in a name

I initially wanted to name the library responsive.js, because my research back then had indicated that was an unused name. As it turns out, it isn’t.

I still think responsive.js would be a great name for it. It is, in my estimation, the JavaScript library I’ve seen that comes closest to the principles of Responsive Web Design. There are a lot of libraries that will allow a mix of dynamic rendering (see aforementioned responsive.js project) and more complex break point handling. What I wanted was very simple: When a media query is true, perform this behaviour. I don’t want to handle the transition between two queries, and indeed I point people towards BreakJS for that functionality, I just want simple, declarative behaviour.

Developing a library

This is the first JavaScript library I’ve ever published. A lot of best practices were new to me (and I might indeed have missed many). I settled for a very conservative behaviour: there is no ES6-style encapsulation, only a simple bootstrapping function and one intended-for-public-consumption function: mediany.

It was also the development of Mediany that had my thinking so much about mustard. In the end, after a back and forth with Jeremy Keith, I settled for checking for features I reasonably expect aren’t present, but not all (Object.prototype.hasOwnProperty and Array.prototype.push not being feature-checked, although I technically could do it).

Mediany is available on npm, and I welcome any feedback.

Jean Grae – 2-32’s

I raise havoc, like giving Mobb Deep a booster chair

Knowing what mustard to cut

‘Cutting the mustard’ is the term the BBC News web developers use for what in other circles is called ‘feature detection’: Programmatically checking whether a given feature is available in the user’s browser.

The technique can be summarised succinctly as:

if (feature in element) {}

Where feature is the feature to check for (like ‘querySelector’) and element is the element you will be accessing said feature on (often window or document, though it can be any DOM element).

This is a crucial component of progressive enhancement, adding features to users whose browsers can support them, in a layered manner where said features are considered additions.

The problem I have encountered is of a philosophical nature: What features should one cut the mustard for?

If we take BBC’s opening statement (‘The browser is a hostile development environment’) to its extreme conclusion, a browser could theoretically support no JavaScript APIs. Thus, to cut the mustard, one would have to feature detect everything.

Now, this is probably overkill. Aside from the obvious fact that if the browser doesn’t support the controls if and in feature detection isn’t even possible, there are softer features to check for that are probably overkill. Object.prototype.hasOwnProperty() has been part of JavaScript since the beginning, and is implemented in all browsers known to MDN, so it can probably be assumed to be present.

But this still leaves the question: What features should one cut the mustard for? If we can assume some features are present, but not others, how do we determine which ones to check for? The only good rule of thumb I can think of is consulting implementation tables such as the ones on MDN and Can I use…, and drawing the line somewhere. And although better than outright user agent detection, it veers too close for my liking.

This might be me being too idealistic, but I am still unsure of the right approach.

Learning Clojure

Over the last month or so, I’ve begun learning Clojure. I don’t do much blogging, let alone technical, but I realise I’ve actually had this blog for so long that my first impressions of Python (the language I spend most of my day job writing in), are documented.

I read through Kyle Kingsbury’s Clojure from the ground up series, and found it an easy learning process. Although I consider myself somewhat of a polyglot, I realised that I hadn’t actually learned any new programming languages in almost ten years, aside from various JavaScript type annotation supersets. (I’ve tried learning Haskell, but have been largely unsuccessful.)

All in all, I like it. I like its functional paradigm, making functions pure by default, but not having to ask permission to get side-effects (which is the feeling I get a bit with Haskell). Leiningen is a great tool to get up and running, and it takes care of a lot of the minutae, like installing dependencies and running tests. I really like being able to name functions almost anything, including non-ASCII characters and characters normally reserved (so now I can use possessive in a function name).

One thing I find about that I really dislike is the abbreviations. Now, this might simply be because it’s the first language I’ve picked up in a while, and I simply haven’t paid attention to it in other languages, but the incessant abbreviating every conceivable name drives me up the wall. Why in the world does it have to be conj and assoc, what’s wrong with conjoin and associate‽ The fact that abbreviations are applied so randomly proved a stumbling block for me, which I feel it really shouldn’t have to be. This is my first foray into Lisp, so I don’t know how much (if any) is simply convention, but space-saving concerns one might have had in the 50s can surely be ignored today. I get more riled up than I justifiably should be, but it irks me. (And again, I realise this might simply just be my internalisation of some abbreviations: I have no problem with str, concat and def.)

I find the destructuring syntax in a lot of cases to be greatly confusing and emanating magic. I have come to terms with let taking a vector of alternating key value pairs, but the sprinkling of keywords to imbue bindings with special properties means I’m still at a copy & paste–stage for some use cases. I’m not very far into macros yet (I have yet to write my first one), but from what I can sense, it leads to a lot of poorly designed APIs. But it might just take some getting used to. (I thought the self argument for Python methods was stupid at first, and now I don’t think about it.)

I also really miss Python’s named, any-order parameters. I realise something similar can be achieved in Clojure using keys destructuring, but that can’t be combined with arity overloading, which I also really like. (Yes, this might be a case of wanting to have a cake and eating it too.)

The lack of a good date and time library is also unfortunate (at least for the apps I tend to do). I’ve been using clj-time, which seems to be a pretty thin wrapper around Joda Time, and while it does its job, it has some odd shortcomings, the primary being its incapability of representing date-less times. I’ve resorted to vectors of hours, minutes, etc., but when you’re used to Python’s datetime library, specifically datetime.time in this instance, you find yourself wanting.

I have found one library that I really like, though: Enlive. It’s an unconventional templating library, in that it doesn’t make a DSL for templating (or, indeed, give access to the whole language, as in PHP), letting the templates instead be pure HTML, and doing the transformations in Clojure. It took me a little while to get the hang of doing things such as loops, but I think it makes for a clean separation of concerns, and I’ll definitely investigate the concept in Python. (There is a Python port, although it doesn’t seem to get much attention these days.)

All in all, I’m really excited about Clojure. For web development it lacks some of the maturity and cohesiveness that I’m used to with Django, but as a language it has a lot of interesting concepts and libraries.

This is Simply Jonathan, a blog written by Jonathan Holst. It's mostly about technical topics (and mainly the Web at that), but an occasional post on clothing, sports, and general personal life topics can be found.

Jonathan Holst is a programmer, language enthusiast, sports fan, and appreciator of good design, living in Copenhagen, Denmark, Europe. He is also someone pretentious enough to call himself the 'author' of a blog. And talk about himself in the third person.