I like to preach to software engineers that
the essence of software engineering is designing for complexity.
I also preach that
coding = design.
So transitively speaking
coding = designing for complexity.
I deeply believe this (and you are going to hear it often in this blog). While there are many important skills a coder brings to the job designing for complexity (DC henceforth) is our bread and butter.
Yes, there are other important talents we bring to coding...
the essence of software engineering is designing for complexity.
I also preach that
coding = design.
So transitively speaking
coding = designing for complexity.
I deeply believe this (and you are going to hear it often in this blog). While there are many important skills a coder brings to the job designing for complexity (DC henceforth) is our bread and butter.
Yes, there are other important talents we bring to coding...
- Performant algorithms,
- Cool animations
- Understanding new and adjacent new technologies
- etc.
These are important and often are the most fun part of the programming job but we spend most of our time (80%+) on DC. A good programmer is thinking about design when writing every line of code. "How will it relate to the other code in this app?", "how will it stand-up to change?", "will the next developer (or even me 6 months later) understand this?", "what dependencies does it create?", etc. I would much rather have a teammate that is good at DC than somebody that occasionally has a clever idea for a special case.
Why is DC so important? Because, in the absence of good DC, applications rapidly become very difficult to understand, extend, enhance and maintain. Many people managing engineers do not understand how much code is reworked. I don't have good metrics on this but I would estimate upwards of 90% of classes are reworked sometime during their lifetime. This rework is necessary and positive but it is much more difficult (read: expensive) if it hard to understand the code. Good DC also makes it much easier/faster for developers to add new behavior to a system. If the frameworks are sensical and the patterns clear new code is built in a fraction of the time.
All of which brings us back to the subject of this post: the need for a better language for front-end development. Web development has always seemed like a step backwards to me. When web development was becoming popular in the late 90s I was building desktop smalltalk apps. Like most of the developers at the time I was swept up in web development. Moving from a smalltalk ecosystem to the web was like moving back to the stone age: primitive tools and primitive architectures. It was an important transition of course: the internet solved a huge problem: "how to get my software and data to my user".
The world wide web was, of course, designed for hyper linking documents...not for developing apps. And so...for almost 20 years we have hacking away, trying to make an application ecosystem out of this hyperlinking architecture. So here we are in the present. A few years ago the web development community, yearning for a better, more performant user experience, shifted the model for user interface code from the server to the client and we came face-to-face with a big problem: the development language on the browser is very weak: javascript. It is not fair to criticize javascript without pointing out that it was created in the 90s as language for light scripting in HTML pages. It was not designed for the serious development activity we now pull it through.
This language weakness has resulted in many efforts. New languages (e.g., Flex, GWT, Dart) have been largely rejected. Partly, I believe, because the burden of full-scale UI development was not yet upon us. But the world has changed. We can't ignore the transition now: UI code is now exclusively a client-based problem. We have large, single page apps (SPAs) that we are building with a very weak language. My historical metric for domain/DB/UX code was that 60-70% of the code base was UI. Saints be with us!!! We are building over half the world's web application software in javascript!!!!
So are there better options? Absolutely. Many. I believe, though, the top candidates are probably TypeScript or Flow. TypeScript is a real language which "transpiles" to Javascript. Strong typing, real OO features. A language born for the browser but with a serious language bent.
The benefits of strong typing are hotly debated. Frankly I think that most discussion is misdirected. Yes, there are definitely benefits from bug reduction (though the degree is, again, hotly debated). Yes, tooling is much better with strong typing (the typing helps the tool reason about the code). In my opinion though the typing (and the other language constructs of TypeScript) improve the comprehension of code. The more complex the system the more necessary it is to have good languages, frameworks, tools, etc. that make it easier to grasp the system and how it acts. Javascript is very weak in this way. Javascript isn't just a loosely-type language. It barely understands the concept of type. It is, in fact, a very concrete language.
I was recently attempting a large refactoring in javascript and remembered another horror with this language: refactoring. Refactoring is an important part of software engineering. Mistakes are made, designs change. Many events create the need for refactoring. Refactoring is a constant activity in a good software team. Refactoring is very difficult in javascript. This is precisely because of the lack of contract in the language. For instance, I would like to change the name of a highly used class from X to Y. In stronger languages I can immediately see the effect of the change and can, if tooling is reasonable, do it in single operation. This is because the language rules provide the information necessary to reason about the change. In javascript? It is terribly laborious and fraught with risk.
As I mentioned I was a smalltalk programmer in the 90s. I ADORED smalltalk. It is the most beautiful language I have worked with. Smalltalk is a loosely typed language. Yes, a loosely typed language can still be productive and comprehensible. But the similarity between smalltalk and javascript ends with loose typing. Smalltalk is a powerful language. Notably though, the biggest weakness of smalltalk was the loose typing. It was enough of a problem for us that we actually built a type annotation system that was checked by code audits and unit tests. It made a tremendous difference in system comprehension.
I have been doing serious javascript development for about 7 years though I have also been doing iOS and Android development during that time. Working with 4 languages (javascript, objective-c, swift, java) at a time is a great way to appreciate the merits and weaknesses of various languages. There are definitely some benefits of javascript development. I LOVE the fact that I can so quickly watch the effects of my changes in the browser. However, if this was not true I don't think we would even consider developing in javascript. When I write code in Swift it works when it runs. I can easily spend an hour writing code in languages like swift/objective-c/java and have the code work...first time...no screwing around searching for mistypings. The difference is profound. I would much rather spend my time designing code and not fixing my foolish errors.
Which brings me to a more general point about programming languages and ecosystems. I make this point after reading a forum which implied that "strong typing is not important for catching bugs because TDD and code reviews will catch those type errors". This author is clearly a better programmer than I or, at least, has much better discipline. I believe that the computer should do it. Yes, the computer should do it. The computer should do everything it possibly can in the software engineering process. I have better things to do. Wasting my time checking syntax and silly typos is not efficient. I have design problems to solve.
I want a better language.
All of which brings us back to the subject of this post: the need for a better language for front-end development. Web development has always seemed like a step backwards to me. When web development was becoming popular in the late 90s I was building desktop smalltalk apps. Like most of the developers at the time I was swept up in web development. Moving from a smalltalk ecosystem to the web was like moving back to the stone age: primitive tools and primitive architectures. It was an important transition of course: the internet solved a huge problem: "how to get my software and data to my user".
The world wide web was, of course, designed for hyper linking documents...not for developing apps. And so...for almost 20 years we have hacking away, trying to make an application ecosystem out of this hyperlinking architecture. So here we are in the present. A few years ago the web development community, yearning for a better, more performant user experience, shifted the model for user interface code from the server to the client and we came face-to-face with a big problem: the development language on the browser is very weak: javascript. It is not fair to criticize javascript without pointing out that it was created in the 90s as language for light scripting in HTML pages. It was not designed for the serious development activity we now pull it through.
This language weakness has resulted in many efforts. New languages (e.g., Flex, GWT, Dart) have been largely rejected. Partly, I believe, because the burden of full-scale UI development was not yet upon us. But the world has changed. We can't ignore the transition now: UI code is now exclusively a client-based problem. We have large, single page apps (SPAs) that we are building with a very weak language. My historical metric for domain/DB/UX code was that 60-70% of the code base was UI. Saints be with us!!! We are building over half the world's web application software in javascript!!!!
So are there better options? Absolutely. Many. I believe, though, the top candidates are probably TypeScript or Flow. TypeScript is a real language which "transpiles" to Javascript. Strong typing, real OO features. A language born for the browser but with a serious language bent.
The benefits of strong typing are hotly debated. Frankly I think that most discussion is misdirected. Yes, there are definitely benefits from bug reduction (though the degree is, again, hotly debated). Yes, tooling is much better with strong typing (the typing helps the tool reason about the code). In my opinion though the typing (and the other language constructs of TypeScript) improve the comprehension of code. The more complex the system the more necessary it is to have good languages, frameworks, tools, etc. that make it easier to grasp the system and how it acts. Javascript is very weak in this way. Javascript isn't just a loosely-type language. It barely understands the concept of type. It is, in fact, a very concrete language.
I was recently attempting a large refactoring in javascript and remembered another horror with this language: refactoring. Refactoring is an important part of software engineering. Mistakes are made, designs change. Many events create the need for refactoring. Refactoring is a constant activity in a good software team. Refactoring is very difficult in javascript. This is precisely because of the lack of contract in the language. For instance, I would like to change the name of a highly used class from X to Y. In stronger languages I can immediately see the effect of the change and can, if tooling is reasonable, do it in single operation. This is because the language rules provide the information necessary to reason about the change. In javascript? It is terribly laborious and fraught with risk.
As I mentioned I was a smalltalk programmer in the 90s. I ADORED smalltalk. It is the most beautiful language I have worked with. Smalltalk is a loosely typed language. Yes, a loosely typed language can still be productive and comprehensible. But the similarity between smalltalk and javascript ends with loose typing. Smalltalk is a powerful language. Notably though, the biggest weakness of smalltalk was the loose typing. It was enough of a problem for us that we actually built a type annotation system that was checked by code audits and unit tests. It made a tremendous difference in system comprehension.
I have been doing serious javascript development for about 7 years though I have also been doing iOS and Android development during that time. Working with 4 languages (javascript, objective-c, swift, java) at a time is a great way to appreciate the merits and weaknesses of various languages. There are definitely some benefits of javascript development. I LOVE the fact that I can so quickly watch the effects of my changes in the browser. However, if this was not true I don't think we would even consider developing in javascript. When I write code in Swift it works when it runs. I can easily spend an hour writing code in languages like swift/objective-c/java and have the code work...first time...no screwing around searching for mistypings. The difference is profound. I would much rather spend my time designing code and not fixing my foolish errors.
Which brings me to a more general point about programming languages and ecosystems. I make this point after reading a forum which implied that "strong typing is not important for catching bugs because TDD and code reviews will catch those type errors". This author is clearly a better programmer than I or, at least, has much better discipline. I believe that the computer should do it. Yes, the computer should do it. The computer should do everything it possibly can in the software engineering process. I have better things to do. Wasting my time checking syntax and silly typos is not efficient. I have design problems to solve.
I want a better language.
Comments
Post a Comment