Journal tags: languages

3

sparkline

Cocolingo

This year I decided I wanted to get better at speaking Irish.

Like everyone brought up in Ireland, I sort of learned the Irish language in school. It was a compulsory subject, along with English and maths.

But Irish wasn’t really taught like a living conversational language. It was all about learning enough to pass the test. Besides, if there’s one thing that’s guaranteed to put me off something, it’s making it compulsory.

So for the first couple of decades of my life, I had no real interest in the Irish language, just as I had no real interest in traditional Irish music. They were both tainted by some dodgy political associations. They were both distinctly uncool.

But now? Well, Irish traditional music rules my life. And I’ve come to appreciate the Irish language as a beautiful expressive thing.

I joined a WhatsApp group for Irish language learners here in Brighton. The idea is that we’d get together to attempt some converstation as Gaeilge but we’re pretty lax about actually doing that.

Then there’s Duolingo. I started …playing? doing? Not sure what the verb is.

Duolingo is a bit of a mixed bag. I think it works pretty well for vocabulary acquisition. But it’s less useful for grammar. I was glad that I had some rudiments of Irish from school or I would’ve been completely lost.

Duolingo will tell you what the words are, but it never tells you why. For that I’m going to have to knuckle down with some Irish grammar books, videos, or tutors.

Duolingo is famous for its gamification. It mostly worked on me. I had to consciously remind myself sometimes that the purpose was to get better at Irish, not to score more points and ascend a league table.

Oh, did I ascend that league table!

But I can’t take all the credit. That must go to Coco, the cat.

It’s not that Coco is particularly linguistically gifted. Quite the opposite. She never says a word. But she did introduce a routine that lent itself to doing Duolingo every day.

Coco is not our cat. But she makes herself at home here, for which we feel inordinately honoured.

Coco uses our cat flap to come into the house pretty much every morning. Then she patiently waits for one of us to get up. I’m usually up first, so I’m the one who gives Coco what she wants. I go into the living room and sit on the sofa. Coco then climbs on my lap.

It’s a lovely way to start the day.

But of course I can’t just sit there alone with my own thoughts and a cat. I’ve got to do something. So rather than starting the day with some doomscrolling, I start with some Irish on Duolingo.

After an eleven-month streak, something interesting happened; I finished.

I’m not used to things on the internet having an end. Had I been learning a more popular language I’m sure there would’ve been many more lessons. But Irish has a limited lesson plan.

Of course the Duolingo app doesn’t say “You did it! You can delete the app now!” It tries to get me to do refresher exercises, but we both know that there are diminishing returns and we’d just be going through the motions. It’s time for us to part ways.

I’ve started seeing other apps. Mango is really good so far. It helps that they’ve made some minority languages available for free, Irish included.

I’m also watching programmes on TG4, the Irish language television station that has just about everything in its schedule available online for free anywhere in the world. I can’t bring myself to get stuck into Ros na Rún, the trashy Irish language soap opera, but I have no problem binging on CRÁ, the gritty Donegal crime drama.

There are English subtitles available for just about everything on TG4. I wish that Irish subtitles were also available—it’s really handy to hear and read Irish at the same time—but only a few shows offer that, like the kid’s cartoon Lí Ban.

Oh, and I’ve currently got a book on Irish grammar checked out of the local library. So now when Coco comes to visit in the morning, she can keep me company while I try to learn from that.

Programming CSS

There’s a worrying tendency for “real” programmers look down their noses at CSS. It’s just a declarative language, they point out, not a fully-featured programming language. Heck, it isn’t even a scripting language.

That may be true, but that doesn’t mean that CSS isn’t powerful. It’s just powerful in different ways to traditional languages.

Take CSS selectors, for example. At the most basic level, they work like conditional statments. Here’s a standard if statement:

if (condition) {
// code here
}

The condition needs to evaluate to true in order for the code in the curly braces to be executed. Sound familiar?

condition {
// styles here
}

That’s a very simple mapping, but what if the conditional statement is more complicated?

if (condition1 && condition2) {
// code here
}

Well, that’s what the decendant selector does:

condition1 condition2 {
// styles here
}

In fact, we can get even more specific than that by using the child combinator, the sibling combinator, and the adjacent sibling combinator:

  • condition1 > condition2
  • condition1 ~ condition2
  • condition2 + condition2

AND is just one part of Boolean logic. There’s also OR:

if (condition1 || condition2) {
// code here
}

In CSS, we use commas:

condition1, condition2 {
// styles here
}

We’ve even got the :not() pseudo-class to complete the set of Boolean possibilities. Once you add quantity queries into the mix, made possible by :nth-child and its ilk, CSS starts to look Turing complete. I’ve seen people build state machines using the adjacent sibling combinator and the :checked pseudo-class.

Anyway, my point here is that CSS selectors are really powerful. And yet, quite often we deliberately choose not to use that power. The entire raison d’être for OOCSS, BEM, and Smacss is to deliberately limit the power of selectors, restricting them to class selectors only.

On the face of it, this might seem like an odd choice. After all, we wouldn’t deliberately limit ourselves to a subset of a programming language, would we?

We would and we do. That’s what templating languages are for. Whether it’s PHP’s Smarty or Twig, or JavaScript’s Mustache, Nunjucks, or Handlebars, they all work by providing a deliberately small subset of features. Some pride themselves on being logic-less. If you find yourself trying to do something that the templating language doesn’t provide, that’s a good sign that you shouldn’t be trying to do it in the template at all; it should be in the controller.

So templating languages exist to enforce simplicity and ensure that the complexity happens somewhere else. It’s a similar story with BEM et al. If you find you can’t select something in the CSS, that’s a sign that you probably need to add another class name to the HTML. The complexity is confined to the markup in order to keep the CSS more straightforward, modular, and maintainable.

But let’s not forget that that’s a choice. It’s not that CSS in inherently incapable of executing complex conditions. Quite the opposite. It’s precisely because CSS selectors (and the cascade) are so powerful that we choose to put guard rails in place.

Declaration

I like the robustness that comes with declarative languages. I also like the power that comes with imperative languages. Best of all, I like having the choice.

Take the video and audio elements, for example. If you want, you can embed a video or audio file into a web page using a straightforward declaration in HTML.

<audio src="..." controls><!-- fallback goes here --></audio>

Straightaway, that covers 80%-90% of use cases. But if you need to do more—like, provide your own custom controls—there’s a corresponding API that’s exposed in JavaScript. Using that API, you can do everything that you can do with the HTML element, and a whole lot more besides.

It’s a similar story with animation. CSS provides plenty of animation power, but it’s limited in the events that can trigger the animations. That’s okay. There’s a corresponding JavaScript API that gives you more power. Again, the CSS declarations cover 80%-90% of use cases, but for anyone in that 10%-20%, the web animation API is there to help.

Client-side form validation is another good example. For most us, the HTML attributes—required, type, etc.—are probably enough most of the time.

<input type="email" required />

When we need more fine-grained control, there’s a validation API available in JavaScript (yes, yes, I know that the API itself is problematic, but you get the point).

I really like this design pattern. Cover 80% of the use cases with a declarative solution in HTML, but also provide an imperative alternative in JavaScript that gives more power. HTML5 has plenty of examples of this pattern. But I feel like the history of web standards has a few missed opportunities too.

Geolocation is a good example of an unbalanced feature. If you want to use it, you must use JavaScript. There is no declarative alternative. This doesn’t exist:

<input type="geolocation" />

That’s a shame. Anyone writing a form that asks for the user’s location—in order to submit that information to a server for processing—must write some JavaScript. That’s okay, I guess, but it’s always going to be that bit more fragile and error-prone compared to markup.

(And just in case you’re thinking of the fallback—which would be for the input element to be rendered as though its type value were text—and you think it’s ludicrous to expect users with non-supporting browsers to enter latitude and longitude coordinates by hand, I direct your attention to input type="color": in non-supporting browsers, it’s rendered as input type="text" and users are expected to enter colour values by hand.)

Geolocation is an interesting use case because it only works on HTTPS. There are quite a few JavaScript APIs that quite rightly require a secure context—like service workers—but I can’t think of a single HTML element or attribute that requires HTTPS (although that will soon change if we don’t act to stop plans to create a two-tier web). But that can’t have been the thinking behind geolocation being JavaScript only; when geolocation first shipped, it was available over HTTP connections too.

Anyway, that’s just one example. Like I said, it’s not that I’m in favour of declarative solutions instead of imperative ones; I strongly favour the choice offered by providing declarative solutions as well as imperative ones.

In recent years there’s been a push to expose low-level browser features to developers. They’re inevitably exposed as JavaScript APIs. In most cases, that makes total sense. I can’t really imagine a declarative way of accessing the fetch or cache APIs, for example. But I think we should be careful that it doesn’t become the only way of exposing new browser features. I think that, wherever possible, the design pattern of exposing new features declaratively and imperatively offers the best of the both worlds—ease of use for the simple use cases, and power for the more complex use cases.

Previously, it was up to browser makers to think about these things. But now, with the advent of web components, we developers are gaining that same level of power and responsibility. So if you’re making a web component that you’re hoping other people will also use, maybe it’s worth keeping this design pattern in mind: allow authors to configure the functionality of the component using HTML attributes and JavaScript methods.