I once needed the SLA for an endpoint my dashboard leaned on, so I asked the team that owned it. Their lead came back with 200ms ± 500ms. Read that literally and the fastest responses arrive 300ms before the request is even sent. The number wasn’t malicious — it came straight out of the standard formulas. The formulas were wrong for the data, and that mistake is everywhere.
The third article in the series, still on conditions. The previous installment
was about their shape — merging ifs, factoring shared decisions, dropping checks that earn nothing. This one reaches for the other lever: the algebra of the conditions themselves — not a textbook tour, just the handful of transformations I lean on in everyday code.
Great programmers cheat. A hard problem gets quietly swapped for an easier one; a transaction-grade database is replaced by a flat file nobody misses; machinery everyone else considers mandatory simply never gets built. They know a lot — and that’s exactly why they get away with it.
The second article in the series. The first
was about control flow; this one stays with the same tactic — reshaping code — one layer down, at the condition. Here: merging ifs, factoring shared decisions, and dropping checks that earn nothing. The Boolean algebra of conditions — De Morgan and friends — is a different lever, and gets its own installment next time.
You can find plenty of articles about design — where and how to use SQL, NoSQL, message queues, Redis, VMs, and so on. Almost nobody writes about tactics: the actual coding. It borders on style, but it isn’t just style. This is the first article in a series on tactics I use day to day. Highly opinionated — I don’t expect you to follow it. Look, chuckle, think about it, and use what you like.
How a slow first cut, a surprising benchmark, and a tour through V8’s regex engine landed five small libraries on npm that still earn their keep a decade later.
As programmers we rarely have a luxury to write a project from scratch. Usually we have
to retrofit existing projects with all cool things we need. If a new component, or a library
we want to use introduces new concepts that bleed outside its boundary, we have a “culture clash”,
when old code is unaware about new concepts have to work with it anyhow. Sometimes the clash is so bad
that we have to give up on using shiny new things, or have to significantly rework their code,
which requires time and efforts we cannot afford.
Incomplete objects allow us to concentrate on important properties of JavaScript objects
ignoring the rest: we don’t need to specify every single property, and we can deal with
cyclical graphs.
Incomplete arrays is a complimentary feature to inspect only the first few array items.
Both features are very useful for patterns, and heya-unify
provides rich facilities to automate
creating incomplete objects: they can be marked up explicitly on per-instance basis, recursively
with a special utility, and we can specify how to deal with objects by default during unification.
Custom unification in heya-unify
allows us to deal with our specific objects in JavaScript,
create unification helpers, and even custom logical conditions. It is there to bridge unification
with our existing projects.
Looking at the 1st part
and
the 2nd part
of the series is recommended before diving into details.
Custom unification
Unification makes comparing simple objects a cinch no matter how complex they are, and we can easily apply it
to JSON-like trees as is. Additionally heya-unify
“knows” how to unify other common JavaScript objects:
dates, and regular expressions. Yet in Real Life™ we are faced with complications like that:
Unification for JS
introduced heya-unify
—
a practical mini library to leverage unification in JavaScript. This post explains when
it makes sense to use unification, and gives practical examples of how to use it.
When to unify?
Below is my laundry list for unification. As soon as I see a project, which deals with items on
the list, I investigate if it makes sense to use heya-unify
.
Unification is a very interesting programming tool. Originated from logical programming
(its the foundation of Prolog) and used in functional programming (e.g., Haskell) it helps
to compare objects for equality, identify known patterns, and reassemble results differently.
Wikipedia gives a somewhat complex definition
of unification, but many people see it as
an extended equivalence comparison, a pattern matching tool, and some even find parallels with
XPath queries, CSS, and even jQuery, all operating on regular objects. See it for yourself.
Time and again working on big web applications we customize files based on user’s platform,
and their preferences. We can send different files to legacy browsers, different CSS and JS to
mobile browsers depending on their form factor, different images to accomodate bandwidth requirements,
and so on.
This post was prompted by my desire to serve sprites produced by
grunt-tight-sprite
as WebP images to WebP-capable browsers falling back to “classic” image formats for the rest using nginx.
While it is hardly a new topic, I was not satisfied with existing solutions, which all used if and rewrite,
instead of simpler methods.
Once I wrote a blog post On JavaScript, EDP, and 0ms timeouts
, which discussed a "smart" trend to pepper code with timeouts of … 0ms: setTimeout(f, 0). Authors of those "programming pearls" genuinely believed that this code reschedules a function call to the next available time slice after the code that set the timer was executed without introduction of a delay (after all it is 0ms!). In reality a typical delay was 10-20ms. With new generation of browsers it starts with 4ms and jumps to 1000ms for non-current/hidden tabs.
Finally: my open source JavaScript project DCL
is built on ideas described in this article. Available for node.js and modern browsers, it implements OOP with mixins and AOP at "class" and object level. Read documentation and background articles on www.dcljs.org
, clone its code on github.com/uhop/dcl
, and follow @dcl_js
.
Almost any Java programmer, who starts to study JS groking its OOP facilities and a dynamic nature of JS, thinks that they can be greatly improved and starts its own OOP library/helpers. Majority of them left forgotten when their authors learn more and more details and patterns of JS, yet some grow to fruition and being marketed. This article is dedicated to such people.
Many years ago I decided to replace plain text areas in Django’s Admin with rich text editor, so I can edit HTML on my blog using WYSIWYG. Six (yes, 6) years ago I looked around and selected
TinyMCE
. Over time it turned out that I was forced to upgrade TinyMCE and the link script I had because new browsers continue breaking my rich editor editing. Finally it stopped working again in all modern browsers, and I decided that enough is enough. It is time to replace it. This time I settled on Dojo’s Rich Editor
hosted on Google CDN
— simple, functional, less work to set up.
In the previous post
we explored “array extras” and how they can help us to write concise yet performant and clean code. In this post we take a look at generalizing recursive algorithms with recursion combinators — high-level functions that encapsulate all boilerplate code needed to set up the recursion. These functions were added to dojox.lang.functional and will be officially released with Dojo 1.2.
In general the recursion is a form of iterative problem solving in the same category as loops. There are two major natural sources of recursive algorithms: recursive data
structures (lists, trees, and so on), and recursive definitions
(factorial, Fibonacci numbers, the GCD algorithm, etc.). The
recursion plays a prominent role in the functional programming (FP),
and one of the best articles on this topic is “Recursion Theory and Joy”
by Manfred von Thun
, the creator of Joy
(a purely functional
programming language with Forth-like syntax). Manfred’s article
explains intricacies of recursion including the venerable Y
combinator
, recursion combinators in general, and introduces a practical set of recursion combinators, which will guide us in this post.
Finally: my open source JavaScript project DCL
is built on ideas described in this article. Available for node.js and modern browsers, it implements OOP with mixins and AOP at "class" and object level. Read documentation and background articles on www.dcljs.org
, clone its code on github.com/uhop/dcl
, and follow @dcl_js
.
If we look at the history of computer programming languages, we can see that practically all new programming methodologies were about one thing: taming complexity. The anarchy of earlier days of procedural programming
(example: Fortran) gave way to structured programming
(Pascal), which was refined with modular programming
(Modula), and was reformulated when object-oriented programing
went mainstream (C++, and much later Java). And it stopped there. The focus shifted to different branches of computer programming, namely to functional programming, and, to a lesser degree, logical programming. The only major development in this branch was the rise of aspect-oriented programming
(AOP) paradigm. Let’s take a look at AOP in our favorite language: JavaScript, and how Dojo helps the language with dojox.lang.aspect package.
What makes JavaScript so different from other languages? Is it its
dynamic nature? Its prototype-based funky inheritance? No. The most
unusual thing for newcomers is how JavaScript programs handle the
workflow. The program looks like a bowl of spaghetti. There is no start
or end of the program. What we have here is a bunch of functions, which
are called in response to some external events. In most cases we have
no way to predict the order of these events. And we know that all
callbacks are called from a single thread. Of course we know that it is
not a nature of JavaScript but rather a limitation imposed by a
specific container of JavaScript programs — web browsers. Majority of
JavaScript code is written for browsers and now we have a perception
problem. But let’s dig deeper to understand the problem better.
Everybody knows that JavaScript is a multi-paradigm language, and it can be used to program functionally. Practically all functional idioms can be used directly: higher-order functions, recursion, closures, and so on. The recent resurgence of Functional Programming (FP) brings functional methodologies in the mainstream. FP fundamentals gave us a lot of powerful idioms: iterative functions, which can replace loops, list processing in general, function manipulations, and many other things, which helps us to keep our code small yet concise, more powerful, and more fun. Let’s take a look at how Dojo helps to leverage the functional paradigm in the Core, and in the extended DojoX package (dojox.lang.functional).
Introduction
Web 2.0 brought on us an onslaught of new server-side web frameworks, and made it OK to put some code on the client side as well. Yes, I am talking about Ajax
. While elements of Ajax were available (and used) for a long time now, 2005 was the crucial year for this relatively old technology fueled by proliferation of modern browsers with proper support of JavaScript and HTML DOM, which, in turn, gave a rise to numerous Ajax toolkits. As always new exciting technology polarizes people — you can find ardent supporters of Ajax and a booing horde of naysayers. The latter crowd points out real and imaginary problems with Ajax. Some problems are real enough but stem from a misuse of the technology. One of them is a performance of a web application. In this article I will show how to improve a performance of a web application with Ajax and how to optimize an Ajax web application. Specifically I will show how to optimize a Dojo
-based high-performance web application. I will use Django
and Apache
as examples of a server environment.