Thursday, September 8, 2016

Static vs. dynamic typing of programming languages [source]

Updated 2010-10-20 — added a bit more information about Boo’s type inferencing.
Updated 2012-04-08 — This post is an appendix to a post comparing Java and Python. Some comments on this post are actually comments on that other post.
There is widespread confusion or disagreement about the meanings of the words static, dynamic, strong and weak when used to describe the type systems of programming languages.
Here is a description of the way (or at least one of the ways) these terms are most commonly used.
In a statically typed language, every variable name is bound both
  • to a type (at compile time, by means of a data declaration)
  • to an object.
The binding to an object is optional — if a name is not bound to an object, the name is said to be null.
Once a variable name has been bound to a type (that is, declared) it can be bound (via an assignment statement) only to objects of that type; it cannot ever be bound to an object of a different type. An attempt to bind the name to an object of the wrong type will raise a type exception.
In a dynamically typed language, every variable name is (unless it is null) bound only to an object.
Names are bound to objects at execution time by means of assignment statements, and it is possible to bind a name to objects of different types during the execution of the program.
Here is an example.
In a statically-typed language, the following sequence of statements (which binds an integer object, then a string object, to the name employeeName) is illegal. IfemployeeName had been declared to be an int, then the second statement would be illegal; if it had been declared to be a String, then the first statement would be illegal. But in a dynamically-typed language this sequence of statements is perfectly fine.
employeeName = 9
employeeName = "Steve Ferg"
Python is a dynamically-typed language. Java is a statically-typed language.
In a weakly typed language, variables can be implicitly coerced to unrelated types, whereas in a strongly typed language they cannot, and an explicit conversion is required. (Note that I said unrelated types. Most languages will allow implicit coercions between related types — for example, the addition of an integer and a float. By unrelated types I mean things like numbers and strings.) In a typical weakly typed language, the number 9 and the string “9” are interchangeable, and the following sequence of statements is legal.
a  = 9
b = "9"
c = concatenate(a, b)  // produces "99"
d = add(a, b)          // produces 18
In a strongly typed language, on the other hand, the last two statements would raise type exceptions. To avoid these exceptions, some kind of explicit type conversion would be necessary, like this.
a  = 9
b = "9"
c = concatenate(  str(a),  b)
d = add(a,  int(b)  )
Both Java and Python are strongly typed languages. Examples of weakly typed languages are Perl and Rexx.
A third distinction may be made between manifestly typed languages in which variable names must have explicit type declarations, and implicitly typed languages in which this is not required. Implicitly-typed languages use type inferencing rather than data declarations to determine the types of variables.
Most static languages, like Java, are also manifestly typed.  But Frank Mitchell notes that some are not: “Haskell and the dialects of ML, for example, can infer the type of any variable based on the operations performed on it, with only occasional help from an explicit type.” Scala is an interesting new statically-typed language for the Java Virtual Machine that uses type inference
Boo is a Python-like language with type inferencing that runs on the .NET CLI. Here is a snippet from the Boo page about Boo’s type inference:
Assignments can be used to introduce new variables in the current scope. The type for the new variable will be inferred from the expression on the right. Only the first assignment to a variable is taken into account by the type inference mechanism.
The following program is illegal:
        s = "I'm a string"   # s is bound with type string
        s = 42               # and although 42 is a really cool number s can only hold strings

Thursday, May 19, 2016

Does typing speed matter for programmers?

A few months ago Jeff Atwood blogged again about the need for programmers to be good typists. In fact he has espoused sheer disdain over the years for all programmers if they were anything less than certified touch-typists. In November 2008 he wrote
We are typists first, and programmers second. It’s very difficult for me to take another programmer seriously when I see them using the hunt and peck typing techniques.
Again, in October 2010 he continues
I can’t take slow typists seriously as programmers. When was the last time you saw a hunt-and-peck pianist?
Strong words indeed. Personally, i think he’s missing the bigger issue. The whole reason we write code is to solve a problem in software. And in order to solve such problems there has to be a certain amount of thought expended on the problem in hand. If you look a little further down the page in the comments section of the 2010 entry he states
I can type 150wpm+ on a keyboard…
Somehow, i doubt his claims because if this was the case he would be one of the fastest typists in the world.
As of 2005, writer Barbara Blackburn was the fastest English language typist in the world, according to The Guinness Book of World Records. Using the Dvorak Simplified Keyboard, she has maintained 150 words per minute (wpm) for 50 minutes
But, honestly is this really relevant? …err… No!

A simple test

I’ve just taken a few typing tests on the internet to see how fast i type. The results were that i type at about 40-45 words per minute with a minimum amount of errors, so what does this mean? Well, using Jeff’s premise the following is true
  1. Typing speed equates to being a good programmer.
  2. I can solve software problems at the same rate as i type.
So, my performance should be able to be graphed thus
If you work out Jeff’s performance using the same formula you get about 3,500 lines of code a day!
But’s there only one problem with this approach, It is nonsense! No programmer will ever be able to tell you how many lines of code he will be expected to write in a day because he has no idea what is going to be encountered, so why does Jeff insist that fast is good?
With creative endeavors, such as programming, there has to be time for contemplation for creativity to emerge, there has to be thought in what you are doing. No programmer has all the answers before starting to write code and problems tend to bloom as code is written as unforeseeable issues are dealt with.
Such is the case with sculpting any masterpiece as the image on the left hints at. David by Michelangelo took roughly 3 years to complete and no one measures Michelangelo’s worth as a sculptor in ‘stones chipped per day’. No one measures an architect’s worth by the speed with which he draws a building plan. No one looks at a programmers code and measures the quality in the amount of code present or how fast it was typed.
So, when Jeff Atwood asks ‘when was the last time you saw a hunt-and-peck pianist?’ Well, never, because a pianist’s job is to interpret static instructions and to play it at the correct speed, not necessarily to think about it. The composer, however, probably worked extremely hard creating and composing that piece and the quality of music produced was not measured on how fast the composer played the piano. I can pretty much guarantee that the composer worked on that piece far in excess of the time the piece of music plays for.
As long as you can type faster than you can solve software problems, you will be fine as a programmer. 40+ words per minute is adequate to make sure typing doesn’t hinder your thoughts. Any programmer demanding that you are not as good as them because you can’t type as fast is probably showing signs of elitism.
In one study of average computer users, the average rate for transcription was 33 words per minute, and only 19 words per minute for composition. In the same study, when the group was divided into ‘fast’, ‘moderate’ and ‘slow’ groups, the average speeds were 40wpm, 35wpm, and 23wpm respectively. ‘Hunt and Peck’ typists can reach speeds of about 37wpm for memorized text, and 27wpm when copying text. An average professional typist reaches 50 to 70wpm

Wednesday, May 18, 2016

Peer Dependencies

by Domenic Denicola,
Reposted from Domenic's blog with permission. Thanks!

npm is awesome as a package manager. In particular, it handles sub-dependencies very well: if my package depends on request version 2 and some-other-library , but some-other-library depends on request version 1, the resulting dependency graph looks like:

├── request@2.12.0
└─┬ some-other-library@1.2.3
  └── request@1.9.9

This is, generally, great: now some-other-library has its own copy of request v1 that it can use, while not interfering with my package's v2 copy. Everyone's code works!

The Problem: Plugins

There's one use case where this falls down, however: plugins. A plugin package is meant to be used with another "host" package, even though it does not always directly use the host package. There are many examples of this pattern in the Node.js package ecosystem already:
Even if you're not familiar with any of those use cases, surely you recall "jQuery plugins" from back when you were a client-side developer: little <script> s you would drop into your page that would attach things to jQuery.prototype for your later convenience.
In essence, plugins are designed to be used with host packages. But more importantly, they're designed to be used with particular versions of host packages. For example, versions 1.x and 2.x of my chai-as-promised plugin work with chai version 0.5, whereas versions 3.x work with chai 1.x. Or, in the faster-paced and less-semver–friendly world of Grunt plugins, version 0.3.1 of grunt-contrib-stylus works with grunt 0.4.0rc4, but breaks when used with grunt 0.4.0rc5 due to removed APIs.
As a package manager, a large part of npm's job when installing your dependencies is managing their versions. But its usual model, with a "dependencies" hash in package.json , clearly falls down for plugins. Most plugins never actually depend on their host package, i.e. grunt plugins never do require("grunt") , so even if plugins did put down their host package as a dependency, the downloaded copy would never be used. So we'd be back to square one, with your application possibly plugging in the plugin to a host package that it's incompatible with.
Even for plugins that do have such direct dependencies, probably due to the host package supplying utility APIs, specifying the dependency in the plugin's package.json would result in a dependency tree with multiple copies of the host package—not what you want. For example, let's pretend that winston-mail 0.2.3 specified "winston": "0.5.x" in its "dependencies" hash, since that's the latest version it was tested against. As an app developer, you want the latest and greatest stuff, so you look up the latest versions of winston and of winston-mail , putting them in your package.json as:

  "dependencies": {
    "winston": "0.6.2",
    "winston-mail": "0.2.3"
But now, running npm install results in the unexpected dependency graph of

├── winston@0.6.2
└─┬ winston-mail@0.2.3
  └── winston@0.5.11
I'll leave the subtle failures that come from the plugin using a different Winston API than the main application to your imagination.

The Solution: Peer Dependencies

What we need is a way of expressing these "dependencies" between plugins and their host package. Some way of saying, "I only work when plugged in to version 1.2.x of my host package, so if you install me, be sure that it's alongside a compatible host." We call this relationship a peer dependency.
The peer dependency idea has been kicked around for literally years. After volunteering to get this done "over the weekend" nine months ago, I finally found a free weekend, and now peer dependencies are in npm!
Specifically, they were introduced in a rudimentary form in npm 1.2.0, and refined over the next few releases into something I'm actually happy with. Today Isaac packaged up npm 1.2.10 into Node.js 0.8.19, so if you've installed the latest version of Node, you should be ready to use peer dependencies!
As proof, I present you the results of trying to install jitsu 0.11.6 with npm 1.2.10:
npm ERR! peerinvalid The package flatiron does not satisfy its siblings' peerDependencies requirements!
npm ERR! peerinvalid Peer flatiron-cli-config@0.1.3 wants flatiron@~0.1.9
npm ERR! peerinvalid Peer flatiron-cli-users@0.1.4 wants flatiron@~0.3.0

As you can see, jitsu depends on two Flatiron-related packages, which themselves peer-depend on conflicting versions of Flatiron. Good thing npm was around to help us figure out this conflict, so it could be fixed in version 0.11.7!

Using Peer Dependencies

Peer dependencies are pretty simple to use. When writing a plugin, figure out what version of the host package you peer-depend on, and add it to your package.json:

  "name": "chai-as-promised",
  "peerDependencies": {
    "chai": "1.x"
Now, when installing chai-as-promised , the chai package will come along with it. And if later you try to install another Chai plugin that only works with 0.x versions of Chai, you'll get an error. Nice!
One piece of advice: peer dependency requirements, unlike those for regular dependencies, should be lenient. You should not lock your peer dependencies down to specific patch versions. It would be really annoying if one Chai plugin peer-depended on Chai 1.4.1, while another depended on Chai 1.5.0, simply because the authors were lazy and didn't spend the time figuring out the actual minimum version of Chai they are compatible with.
The best way to determine what your peer dependency requirements should be is to actually follow semver. Assume that only changes in the host package's major version will break your plugin. Thus, if you've worked with every 1.x version of the host package, use "~1.0" or "1.x" to express this. If you depend on features introduced in 1.5.2, use ">= 1.5.2 < 2" .
Now go forth, and peer depend!

Saturday, May 7, 2016

The final feature set of ECMAScript 2016 (ES7)

We always knew that ECMAScript 2016 (ES2016) would be a small release. It turns out that it will be very small. Read on for a list of its features and an explanation why that is not a problem.

The features of ES2016

Any proposals that were at stage 4 on Thursday, 28 January 2016, will be in ES2016 (source: ECMAScript standard editor Brian Terlson). That means that ES2016 will contain just two new features (in addition to bug fixes and smaller improvements):
The draft of ECMAScript 2016 is online and will be ratified in 2016, probably in June.

The new release process works

ES2016 being so small demonstrates that the new release process works:
  • New features are only included after they are completely ready and after there were at least two implementations that were sufficiently field-tested.
  • Releases happen much more frequently (once a year) and can be more incremental.
If you are disappointed that your favorite stage 3 feature did not make it into ES2016 – don’t worry: With the new release process, it’s more about the stage a proposal is in than what release it is a part of. As soon as a proposal reaches stage 4, it is done and safe to use. You’ll still have to check whether the JavaScript engines that are relevant to you support the feature, but you have to do that with ES6 features, too.

Monday, June 22, 2015

Understanding Loose Typing in JavaScript

FRIDAY, MARCH 14, 2008

For many front end developers, JavaScript was their first taste of a scripting and/or interpretive language. To these developers, the concept and implications of loosely typed variables may be second nature. However, the explosive growth in the demand for Web 2.0-ish applications has resulted in a growing number of back end developers that have had to dip their feet into pool of client side technologies. Many of these developers are coming from a background in strongly typed languages, such as C# and Java, and are unfamiliar with both the freedom and the potential pitfalls involved in working with loosely typed variables.
Since the concept of loose typing is so fundamental to scripting in JavaScript, an understanding of it is essential. This article is a top level discussion of loose typing in JavaScript. Since there may be subtle differences in loose typing from language to language, let me constrain this discussion to the context of JavaScript. OK, let's dig in...
What is Loose Typing?
Well, this seems like a good place to start. It is important to understand both what loose typingis, and what loose typing is not. Loose typing means that variables are declared without a type. This is in contrast to strongly typed languages that require typed declarations. Consider the following examples:
  1. /* JavaScript Example (loose typing) */  
  2. var a = 13; // Number declaration  
  3. var b = "thirteen"// String declaration  
  5. /* Java Example (strong typing) */  
  6. int a = 13; // int declaration  
  7. String b = "thirteen"// String declaration  
Notice that in the JavaScript example, both a and b are declared as type var. Please note, however, that this does not mean that they do not have a type, or even that they are of type "var". Variables in JavaScript are typed, but that type is determined internally. In the above example, var a will be type Number and var b will be type String. These are two out of the three primitives in JavaScript, the third being Boolean.
JavaScript also has other types beyond primitives. The type diagram for JavaScript is as follows (as per Mozilla):
Ya really - Null and Undefined too.
Note, however, that this distinction between primitives and objects will be dismissed in JavaScript 2.0. You can read more about that here.
Type Coercion
Type coercion is a topic that is closely associated with loose typing. Since data types are managed internally, types are often converted internally as well. Understanding the rules of type coercion is extremely important. Consider the following expressions, and make sure you understand them:
  1. 7 + 7 + 7; // = 21  
  2. 7 + 7 + "7"// = 147  
  3. "7" + 7 + 7; // = 777  
In the examples above, arithmetic is carried out as normal (left to right) until a String is encountered. From that point forward, all entities are converted to a String and then concatenated.
Type coercion also occurs when doing comparisons. You can, however, forbid type coercion by using the === operator. Consider these examples:
  1. 1 == true// = true  
  2. 1 === true// = false  
  4. 7 == "7"// = true  
  5. 7 === "7"// = false;  
There are methods to explicitly convert a variable's type as well, such as parseInt and parseFloat (both of which convert a String to a Number).
Double negation (!!) can also be used to cast a Number or String to a Boolean. Consider the following example:
  1. true == !"0"// = false  
  2. true == !!"0"// = true  
This obviously is not a definitive reference to loose typing in JavaScript (or type coercion for that matter). I do hope, however, that this will be a useful resource to those who are not familiar with these topics, and a good refresher for those who already are. I have tried to insure that the above is accurate, but if you notice anything incorrect, please let me know! And as always, thanks for reading!