Showing posts with label JavaScript. Show all posts
Showing posts with label JavaScript. Show all posts

2011-03-05

Type Coercion

A type conversion is an operation that takes a value of one type and returns a value of another type such that the two values are somehow equivalent. Examples include:

  • float(5)5.0 // integer to float
  • string('s')"s" // character to string
  • codepoint('A')0x41 // character to integer
  • A (Java) FileInputStream converted to a ByteArrayInputStream by first loading into memory

If no conversion operator explicitly appears in the code, the conversion is called a type coercion. Like all implicit operations, coercions can be convenient (less source code to type and read), but also dangerous (as things happen without the programmer's explicit authorization).

How can languages make conversions and coercions available to programmers? Coercions are usually dealt with in one of three ways:

  • Allow all corecions
  • Disallow all coercions
  • Allow only certain coercions, such as subtypes to supertypes

No Coercions Ever

Languages like Ada and ML have a very simple rule: no coercions ever. One cannot even use an integer where a floating point value is expected, without explicitly casting the integer to a float.

Implicit Upcasting

Some languages, such as Java, allow casting in only one way, from subtypes to supertypes. This is called upcasting. You can use an integer where a float is expected, and the integer value will be coerced to the right floating point value. You can't go the other way automatically, though.

Implicit Downcasting

Coercions from a supertype to a subtype (downcasting) are inherently dangerous because information is being lost. In C:

int x = 8.2;            // x gets 8
int y = 8.5;            // does y get 8 or 9?

Directly assigning a floating point value to an integer variable in its declaration is unrealistic; here's something that is more likely to occur:

void f(char* s, int n) { ... }
.
.
.
f("some text", z);   // z is a float, coerced to a int within f

Again, this may not be too bad in practice; z will be truncated or rounded and the resulting value will be passed to the parameter n. Unless z is a global variable and is assigned the value of n within f, there's no problem, right? People would never do such a thing, right?

Never say never! SAP has a product called Business Objects Data Integrator (BODI), with an embedded database programming language. In the Data Integrator Reference Guide, on page 453, they describe this function:

ifthenelse: Allows conditional logic in expressions.
Syntax
ifthenelse(condition, true_branch, false_branch)
Return value
true_branch or false_branch
Returns one of the values provided, based on the result of condition. The data type of the return value is the data type of the expression in true_branch. If the data type of false_branch is not convertible to the data type of true_branch, Data Integrator produces an error at validation. If the data types are convertible but don’t match, a warning appears at validation.

"The type of the return value is the datatype of the expression in true_branch"? That's not exactly intuitive. Combined with the fact that BODI (or the underlying database it may use) does implicit coercions from floats to integers, users are opened up to the following disaster:

P.latitude = ifthenelse(P.latitude is null, 0, P.latitude)

This is an attempt to clean up a null value by setting it to 0. But assuming the latitude is a regular floating point value, this assignment destroys the value, turning 43.2, say, into 43. If latitudes and longitudes are both "adjusted" this way, places in good neighborhoods end up in bad neighborhoods or in the middle of a river or ocean.

Coercions and Type Systems

Why would BODI even create an ifthenelse operator that would coerce an argument? This is a classic case of mixing static typing with weak typing. Note:

  • Static Typing means that all expressions must be fully typed at compile time, while dynamic typing means that types are resolved at run time.
  • Strong Typing means that operators applied to arguments of the wrong type generate errors, while weak typing means that the values will be coerced (wherever possible) to make the operation valid.

Static typing goes well with strong typing (ML, Ada), while dynamic typing can be combined with either strong (Ruby) or weak (Perl, JavaScript) typing, without too many surprises.

How should BODI's ifthenelse operator have been defined? Using static and weak typing together is not really the worst element at play here; it's the implicit downcasting of P.latitude to an integer. Why did they do this? Perhaps the designers of this language thought it would be "too complicated" to define the return type as "the most general type of true_branch and false_branch" and thought it "too restrictive" to force the two types to match exactly. They could have at least detected the fact that the false_branch had a more general type then the true_branch and generated and error there. Perhaps they thought that "too confusing." But wait, taking the type of true_branch as the result type is asymmetric and confusing on its own! How is that intuitive?

Note that with dynamic typing this problem never would have arisen since the ifthenelse expression would have produced either its second or third argument and hence taken on the type of the value returned, whatever that was. A dynamically typed language would never have even considered a coercion in that case at all! And a statically typed language with strong typing would have rejected the expression outright.

Static + weak is the problem. Language designers would be wise to avoid this combination.

2010-10-30

Anonymous Functions

A function is something you invoke, passing zero or more inputs (called arguments) and getting back zero or more outputs (called results). Functions generally have parameters (which match up with the arguments they accept), and a body, which contains the code that the function executes. What isn't necessary is that the function have a name. A function without a name is called — not surprisingly — an anonymous function.

How can we make anonymous functions easy to read and write?

Preliminaries

A few things to consider when designing support for anonymous functions:

  • Should the function body be a single expression or a block with a return statement or statements?
  • What kind of syntactic device should be used to delimit the function?
  • Are functions first-class values (as in Scheme, Haskell, or JavaScript) or are simple "blocks" or "continuations" sufficient?

Terse Designs

When the function body is a simple expression, there are a number of very terse ways to denote a function, many of which are used in existing languages. Here are some sketches for a function whose sole input is (an integer) x, and whose result is x/2 if x is even and 3*x+1 otherwise:

[x -> if x mod 2 = 0 then x div 2 else 3 * x + 1]
{x → x % 2 === 0 ? x / 2 : 3*x + 1}
λ x . (x / 2 if x % 2 == 0 else 3 * x + 1)
(LAMBDA (x) (IF (= (% X 2) 0) (/ X 2) (+ (* 3 X) 1)))
fn x => if x mod 2 = 0 then x / 2 else 3 * x + 1
{|x| x % 2 === 0 ? x / 2 : 3*x + 1}
function from x to x % 2 === 0 ? x / 2 : 3*x + 1 end
x to x % 2 === 0 ? x / 2 : 3*x + 1
fun (x) returning x % 2 === 0 ? x / 2 : 3*x + 1 end fun

For those forms which do not have special outer brackets to indicate a function expression, regular parentheses can be used to delineate them when they appear in the middle of a larger expression.

Verbose Designs

Function expressions that have complex bodies, such as those with several statements, including return statements can simply be written as function declarations without a name. See the JavaScript example below.

Uses of Anonymous Functions

There are two main uses of anonymous functions:

  • Arguments to functions like map, filter, and reduce.
  • To act as a module, in which local variables play the role of private variables. An example in JavaScript, in which a variable is shared between two exported global functions:
    (function () {
        var x = 0;
        f = function () {return x -= 5;}
        g = function () {return x = 2 * Math.abs(x);}
    }());
    

2010-09-30

Values and No Values

Consider something as simple as recording a property for an object, say, a person's supervisor. What kind of possibilities exist? Here are some:

  1. I have a supervisor and her name is Alice.
  2. I definitely have no supervisor.
  3. I may or may not have a supervisor; I really don't know.
  4. I do know whether I have a supervisor, but I don't care to make this information public; in other words, it's none of your business.

How can we capture these cases in a programming language?

Strings Only

For languages with unsophisticated type systems (say, strings or symbols only), you might try:

var supervisor1 = "Alice";
var supervisor2 = "None";
var supervisor3 = "Unknown";
var supervisor4 = "Private Info";

The obvious problem here is that people can have any name at all, even "None", "Nobody", "N/A", "Robert'); drop table students;--", or even "". You'd have to express in comments, and add logic to your application, that certain strings really aren't names. This isn't what we'd call a clean solution. What we want is a solution in which the values representing no (or an unknown) supervisor belong to a type or types other than plain string.

Disjoint Sum Types

ML and related languages feature a very clean syntax for defining flexible datatypes:

datatype Person = None | Unknown | WillNotSay | Actual of string;
val supervisor1 = Actual "Alice";
val supervisor2 = None;
val supervisor3 = Unknown;
val supervisor4 = WillNotSay;

This works very nicely: the type of None is Person, not string. In fact, the type of each supervisor variable above is (inferred to be) Person. While this is a nice statically-typed solution, a programmer would need to add the special constants None, Unknown, and WillNotSay to all types for which this kind of information is relevant. You can do this "once" with a polymorphic type:

datatype 'a info = None | Unknown | WillNotSay | Actual of 'a;
val supervisor1 = Actual "Alice";
val supervisor2: string info = None;
val supervisor3: string info = Unknown;
val supervisor4: string info = WillNotSay;

Here we've given explicit types to supervisor2, supervisor3, and supervisor4, since the None, Unknown, and WillNotSay constructors are polymorphic.

JavaScript's null and undefined

In a dynamically typed language like JavaScript we often have values in distinct types that represent nothingness or lack of knowlege. In JavaScript, for example:

  • null is the sole member of the Null type and represents the certainty of having no real value.
  • undefined is the sole member of the Undefined type and represents the lack of knowledge about its real value.

JavaScript doesn't natively distinguish between cases 3 and 4 — lack of knowledge and the refusal to share that knowledge. It could be argued that isn't really a common case anyway. Now you could, if you really wanted to, make this distinction somewhat like this:

var alice = {name: "Alice"; supervisor: null};
var bob = {name: "Bob"; supervisor: alice};
var eve = (name: "Eve"; supervisor: undefined};
var mallory = {name: "Mallory"}

This uses the lack of a supervisor property of Mallory to say she makes no claim to even having a supervisor, and isn't telling you if she has one at all. This approach is a little ugly in practice since, in JavaScript anyway, evaluating mallory.supervisor produces undefined! You'd have to dig into the object and examine its properties in order to pick up on the difference.

Marker Objects

Another approach that works well in a dynamically-typed language is to create the special values yourself, as simple, plain old objects. In JavaScript:

var NONE = {};
var UNKNOWN = {};
var WILL_NOT_SAY = {};

It should be fairly easy to figure out how to use these values.

This approach doesn't quite work as well in a statically-typed language. In Java, for example, marker objects would be implemented like this:

public static final Object NONE = new Object();
public static final Object UNKNOWN = new Object();
public static final Object WILL_NOT_SAY = new Object();

But, this means, of course, properties such as supervisor will have to be given the Java type Object, which goes against the whole point of using a statically typed language. ML's disjoint sum types are better for static languages.

2010-06-22

Eval

A common feature in many scripting languages is an eval function. Pass it a string representing source code, and the function will compile it and then interpret it. This function is called eval if the source code string represents an expression that produces a value, and might be called exec if it does not.

Eval is controversial and much-maligned because it is (1) so often abused, (2) so often used when much better alternatives exist, (3) is slow, and (4) can lead to disaster if misused. It is not rare to hear the claim "eval is evil." So the questions are: should a language allow eval and if so, how should this feature be designed?

Problems with eval

Things to watch out for:

  • Eval is slow because a compiler has to be launched to lex and parse the code string, prior to evaluating it.
  • Eval is lame because programmers may sometimes use eval without thinking. While it would be rare for anyone to blatantly pass a fixed string to eval, such as
    eval("x = 3;");
    

    one can usually get away with creating an anonymous function.

  • Eval is a security hole. Since the only reason for using eval is to run code that is supplied at run time, it's possible that this code may come from an untrusted or malicious source. Allowing just anyone to run code on your own machine is crazy.

When is eval not evil?

If you are going to use eval, the string must be completely sanitized. You need to check it for infinite loops, assignments, or calls with side-effects that might destroy the integrity of your application. For example, here is a JavaScript application that accepts an arithmetic expression from a user and evaluates it, first checking to make sure the input consists only of digits, parentheses, and the four basic arithmetic operators:

var s = prompt("Enter a numeric formula");
if (/[^\d()+*/-]/.test(s)) {
    alert("I don't trust that input");
} else {
    alert(eval(s));
}

Eval and Language Design

Either a language will allow evaluation of code strings or it will not. If it does, we can provide that functionality through a function or an operator. Because it is dangerous, it is definitely a candidate construct for being required to appear inside a "warning" construct, or similarly, disallowed from strict modes. Examples:

UNSAFE module Calcuator {
    ....
    // use eval here
    ....
}
use module UNSAFE;
application Calcuator {
    ....
    // use UNSAFE.eval here
    ....
}

Eval as a function

Generally, we see eval as a global function, or a member of a module entitled something like Kernel, System, or perhaps better, UNSAFE.

Eval as an operator

Another way to call attention to the use of eval is to simply make it a unary operator on strings. Perhaps:

var s = prompt("Enter an expression");
alert( `` s );

Alternatively, we might see the string to be evaled enclosed in angle or other brackets.

Disallowing Eval

Clearly we could imagine a language without an eval function or operator. C is one such language.

Forced Sanitization

An interesting new idea is for the eval function to take a second parameter which is (1) a block or anonymous function that performs sanitization, or (2) a regex which will be applied to the string so that the string will only be applied if the regex pattern matches. Example:

var s = prompt("Enter a numeric formula");
alert(eval(s, /[^\d()+*/-]/));

Throwing an exception on not matching would likely be the best course of action here.

2010-05-20

List Comprehensions

A list comprehension is a compact syntactic form for a list (or array) that is built from applying an operation to certain elements of an existing list (or array). For example:

[7*x-3 | x in 1..n | x mod 3 == 1] 

means the list of all values made by computing 7 * x - 3, for each x in 1 through n where x mod 3 is 1. If n is 10, for example, the generated list is [4, 25, 46, 67]. The three parts of the comprehension are called the output (expression), the input (range) and the filter (predicate).

Common uses of comprehensions

[7*x-3 | x in 1..n | x mod 3 == 1]  // operate on (map) and filter a range 
[7*x-3 | x in a | x mod 3 == 1]     // map and filter an existing list
[7*x-3 | x in 1..n | true]          // no filtering, just map
[x | x in 1..100 | isPrime(x) ]     // just a filter, no map

Sketches

{7*x-3 | x in 1..n | x mod 3 == 1}
[7*x-3 for x in a where x mod 3 == 1]
[7*x-3 for x in a if x mod 3 == 1]              // Python
[7*x-3 for each (i in a) if (x % 3 == 1)]       // JavaScript 1.7 (uncommon)
for (i <- (1 to 10) if x % 3 == 1) yield 7*x-3  // Scala
[7*x-3, x in 1..n, x mod 3 == 1]
{7*x-3 : x ∈ 1..n ∧ x mod 3 == 1}               // Plain old Math!!
[7*x-3 : x ∈ 1..n, x mod 3 == 1]
[7*_-3 | a | _ mod 3 == 1]                      // implicit variable

Complex input sets

How do we handle the idea of two range variables for the input set? We can write two range expressions or range over a set of tuples:

[2*x+y | x in 1..n, y in 'a'..'z' | x mod 3 == 1 and isVowel(y)]
[(x, y*y) | (x, y) ∈ a × (1..10) | x < y]
[x + y for x in a for y in b]                   // Python

Life without comprehensions

If you don't have comprehensions, or a compact, symbolic list append operator, you end up writing this:
List<Integer> a = new List<Integer>();
for (int x = 1; x <= n; x++) {
    if (x % 3 == 1) {
        a.append(7 * x - 3);
    }
} 
Many programmers like that kind of coding. More verbose, but everyone can understand it.
In languages that treat for and if as suffixes to simple statements (like Perl and Ruby), we get compact forms that can be nearly as terse as comprehensions:
a = [];
for x in 1..n
  a << 7 * x - 3 if x mod 3 == 1
end
a = [];
a << 7 * x - 3 if x mod 3 == 1 for x in 1..n
a = [];
a << 7 * x - 3 for x in 1..n where x mod 3 == 1

And, of course, there are map and filter (or select as it is called in Ruby)...

(1..n).filter(x -> x mod 3 == 1).map(x -> 7 * x - 3)
(1..10).select{|x| x % 3 == 1}.map{|x| 7 * x - 3}         // Ruby
(1 to n) filter { _%3==1 } map { 7*_-3 }                  // Scala
map((x -> 7 * x - 3), filter((x -> x mod 3 == 1), (1..n)))

Try the previous examples with your favorite form of lambda expression.

Here's an interesting variation, in Ruby that uses map but not select. Instead we add a if clause to the map, which generates extra nils, which we squeeze out with compact. Not pretty, but it gets that nice little "if" in there. Fun.

(1..n).map{|x| 7 * x - 3 if x % 3 == 0}.compact

2010-05-02

Reserved Words

Many languages reserve words for their own use, meaning that you, the programmer, cannot use these words for your own purposes. Reserved words are related to keywords which are words used for certain purposes by the language, but which you can also use as you wish.

What is the motivation for a language to have reserved words? Are reserved words a good thing or not? Is there such thing as different degrees of being reserved?

Why reserve words at all?

A language might want to reserve words to limit confusion. The following are legal statements in PL/1, a language which chose not to reserve IF, THEN, ELSE, DO, and similar keywords:

IF THEN THEN THEN = ELSE; ELSE ELSE = THEN;
IF IF THEN ELSE = IF; ELSE THEN = ELSE;
DO WHILE (WHILE = DO); END = WHILE + DO; END;

Would anyone really write code like that? Even if someone felt the need to abuse keywords like that, simply reserving them doesn't completely prevent programmers from writing confusing code in other ways. There's no stopping this:

int subtract(int x, int y) {
    return x + y;
}

Perhaps the real reason languages reserve words is to make things easier for the compiler, or to give the language authors an outlet in which to be funny. For example, the word goto is reserved in Java, even though it isn't used for anything. Of course, nothing prevents a Java programmer from using the word in package names, comments, and string literals. And, as Java is case-sensitive, there's always class Goto ... .

Why not reserve words?

There are a few reasons for not reserving words:

  • Programmers should have the freedom to choose their own identifiers. It's the compiler's job to figure out when words are used in a particular context.
  • It's annoying to programmers. There are thousands of Java programs in the world using variable and parameter names called klass, clazz, or c, because class is verboten. (Awesome hackers might even use clаss — haha, the third letter there is a Cyrillic small letter a, not a Latin one!)
  • As a language evolves, the addition of new reserved words will break old code.

Keywords versus symbols

Here are three alternative syntaxes for a certain statement:

if greater(x, y) and w then begin assign x plus 4 to z; print z; end;
if (x > y && w) {z = x + 4; print z}
(x > y && w ==> z = x + 4, !z)

The obvious things to notice are that too many keywords make code too verbose and readability goes down. Too few keywords gives you cryptic code. Most people understand + and * and /, but really, a ! for "print"? In fact, most symbols aren't obvious at first. Different languages use = differently. And what about these things: <=>. =~. %. ===, ^, *., #, ??, and who knows what else? Anyone use APL?

Symbols are sometimes preferred to keywords for another reason: if keywords are in a language you don't speak, they might be harder to learn than symbols. Programmers that know Spanish but not English may prefer 'y' to 'and' and 'mientras' to 'while'. This is one use for macros, I suppose. In C:

#define mientras while

Symbols as keywords

In ML, identifiers can be alphanumeric or symbolic. So +, <=*=> and ====> are all identifiers. You can define functions with these names. And you can define + to do subtraction. You can even do that in Ruby. Is this okay? The choices seem to be:

  • Allow symbolic identifiers, but treat some as reserved words so that no programmer can override such basic operators as +.
  • Allow symbolic identifiers but place no restrictions on them. After all, the reason languages allow "operator overloading" is to allow addition on vectors and other structured objects.
  • Disallow symbolic identifiers but permit operator overloading (for the fixed set of predefined symbolic operators).
  • Prohibit both symbolic identifiers and operator overloading.

How reserved is reserved?

When a language specification says that a word is reserved, it generally means one of two things:

  • The word cannot, under any circumstances, be used as a name for any programmer-defined entity (e.g., a variable, constant, function, type, object property name, method, function parameter, statement label, etc.)
  • The word can be used to name some programmer-defined entities, but its position in the source code text is restricted to simplify language processing (specifically, tokenization).

The former case may be stricter than necessary because quoting, for one thing, works pretty well for object properties (at least):

point["long"] = 118.3532;

You can't stop people from using reserved words in string literals, after all. Similar to quoting is escaping; for example, you would write something like :

var @while = 2;

The @ is not part of the variable name, it's just an escape character that tells the compiler the variable is really named 'while' but we're going to use it as an identifier and not as the beginning of a while statement.

The second case is interesting. JavaScript, for example, reserves the word "long" and while it allows

point["long"] = 118.3532;

it does not allow

point.long = 118.3532;

The probable reason for this is that it wants its lexical analyzer to be independent of context: for it to simply look that the above text and tokenize it into

    IDENTIFIER ("point")
    DOT
    KEYWORD_LONG
    ASSIGNMENT_OPERATOR
    NUMBER ("118.3532")

But is that really important in practice anymore? Lexical analyzers can easily choose a different meaning for a token if, say, the previous token is a dot! That would allow point.long. Now what about var point = {lat: 40, long: -110}? It would seem we'd have to allow the lexical analyzer to have access to the parser's state, but really, just wait until the semantic analysis phase and allow certain known keyword tokens to be just as good as identifiers when it comes to object property names.

2010-04-17

Global Variables

The concept of a global variable seems pretty simple, especially to beginning programmers writing a single-file program in a block-structured language. But for languages with modules, or languages that support multithreading or multiprocessing, or with scripting languages embedded in other systems that expose "host" objects via script variables, things are not so clear.

Most programmers would warn that globals should be used sparingly, for various reasons:

  • Because they can be written to from anywhere, it's harder to tell what might be going on just by looking at local portions of code. Code is harder to debug.
  • Globals make multithreaded programming harder to reason about, and make race conditions more likely to pop up.
  • Parameters are almost always a more readable and understandable way to "share" data among routines.

How do we live with, or manage, global variables? What constructs can a language have to mitigate these problems?

Languages that Require Global Variables

There's an interesting distinction between languages that allow global variables and those that require them. If a language allows pieces of a program to be brought together from different physical components (such as files), but does not provide a programming language construct like a module or package, then global variables are basically required to share information. Even if you adopt a message-passing type of communication between functions in different files, without a nice module construct, those functions are referenced with global variables.

Modules

Many languages have modules for the express purpose of limiting the number of global variables and hence minimizing the number of name collisions. The simplest example is that of a math module, found in most modern languages. Instead of global variables for E, PI, sin, cos, tan, etc., these values are wrapped in a module construct (usually called Math), which is the only top-level name exposed to the rest of the code. Examples:

# Ruby-like
module Math
  def sin(x) ... end
  def cos(x) ... end
  PI = 3.141592653589793
  E = 2.718281828459045
end
// JavaScript-like
var Math = {
    sin: function (x) {...},
    cos: function (x) {...},
    PI: 3.141592653589793,
    E: 2.718281828459045
};
# Java-like
public class Math {
    private Math() {}
    public static double sin(double x) {...}
    public static double cos(double x) {...}
    public static double PI = 3.141592653589793;
    public static double E = 2.718281828459045;
}

Modules create a namespace for these values which would otherwise be global. If there is a chance of having too many modules (that is, a possibility of having names of modules collide), modules can be grouped into some higher level named collection (Java calls this a package). Whether or not the additional construct is used, one can always use a hierarchical naming convention for global entities, starting, for instance, with a (reversed) DNS name that the programmer "owns."

Multithreading

The dangers of unprotected global variables in multithreading code (e.g., race conditions, lost updates) are so well known we don't need to explain them here. If you are stuck with a global, shared, variable for communication between threads, your language might provide some mechanism for atomic updating. For example:

atomic var balance = 0;

or

AtomicInteger balance = new AtomicInteger(0);

Internet Explorer Events

In most event-driven systems, an event object is passed to event handlers. If you are using JavaScript, and are writing event handlers to function on any browser except Internet Explorer, this will be the case. You write code like:

document.body.onclick = function (e) {
    alert("Clicked at (" + e.clientX + "," + e.clientY + ")");
}

With Internet Explorer, the event object is not passed to your handler; instead, the most recently fired event is accessed by a global variable (no kidding!) called event. IE gets away with this because client-side JavaScript is single-threaded: all events are queued and are handled sequentially. To make your code work on multiple browsers you can use the following idiom:

document.body.onclick = function (e) {
    if (!e) e = event;
    alert("Clicked at (" + e.clientX + "," + e.clientY + ")");
}

Sigils

Because local variables are usually better than global variables, one interesting design choice is to make locals the default and make globals ugly. Ruby does exactly this: global variables begin with a $ character. That's a sigil — a character used within a variable name to indicate its type, category, or (in this case) scope.

Example:
$x = 10
def f
  x = 3
  puts x
  puts $x
end
def g
  puts $x
end
def h
  puts x
end
f        # writes 3 then 10
g        # writes 10
puts $x  # writes 10
h        # raises a NameError

Another example:

x = 5
def f
  puts x
end
f        # raises a NameError

Hiding in Closures and Anonymous Functions

TODO

2010-03-13

Lambdas

Lambda-expressions, or anonymous functions, are common in many languages, but are either missing or approximated in others.

Simple Expressions

There are many ways to write lambda expressions when the body is a single expression:

λ x . x + 1
{x -> x + 1}                 // Curly braces are common
[x -> x + 1]                 // Not so common, looks like an array
(x -> x + 1)                 // Let the -> operator imply function type
fn x => x + 1                // ML
lambda (x) x + 1
(lambda (x) (+ x 1))
sub {$0 + 1}                 // Perl
{$0 + 1}
{_ + 1}                      // Scala
λ x y . 2 * x + y
{x y -> 2 * x + y}
fn x y => 2 * x + y
fn (x,y) => 2 * x + y
lambda (x, y) 2 * x + y
sub {2 * $0 + $1}
{2 * $0 + $1}

Some of these require a bit more lookahead to parse than others.

Complex Function Bodies

If your language has a sequencing expression, like C's comma expression, where e1, e2, e3 means to evaluate each expression in order and return the value of the last expression encountered, then you can use the sequencing expression in any of the forms above. Operator precedence becomes the only real issue, but parentheses can make it clear exactly what the function is.

{ p, i -> k = p * 0.45359237, m = 0.0254, k / (m * m) }

Let-expressions work well here, too

{ p, i -> let k = p * 0.45359237 and m = 0.0254 in k / (m * m) end }

Lambdas can be arbitrarily complex, with return statements. Some languages allow you to omit the return statement if the expression to return is the last one in the sequence.

TODO

Recursion

To arrange for an anonymous function to be called recursively, it needs to have a name or the language should reserve a special keyword to refer to the currently executing function (watch for scoping rules here).

{[f] n -> n <= 1 ? 1 : f(n - 1) * n}
{n -> n <= 1 ? 1 : CALLEE(n - 1) * n}

Allowing recursion in lambda expressions is far better than requiring the applicative Y combinator.

Closures

Lambdas often refer to variables in outer scopes. Within the lambda expression, these outside variables are called free variables.

function incrementer(int start, int delta) {
    var current = start - delta;
    return function () {return current += delta;}
}

Calling Lambda Expressions

Calling, or applying a function, is normally done with juxtaposition, though again precedence rules will often come into play.

(x -> x + 1)7
(x -> x + 1)(7)
[x -> x + 1](7 * y - 2)
[x -> x + 1] 7 * y - 2         // application or multiplication first? 
fn (x, y) => 2 * x + y (7, y)  // too confusing 
(fn (x, y) => 2 * x + y)(7, y)   

Currying

Sketches:
[x -> [y -> 2 * x + y]]
[x -> y -> 2 * x + y]
[x y -> 2 * x + y]
fn x => fn y => 2 * x + y
fn x y => 2 * x + y

Fake Lambdas

TODO

Delegates

TODO

2010-03-03

Prototypes

There are two primary ways that languages allow you to create a set of objects with the same (or similar) structure and behavior. In the classical approach, you define classes and then create objects from constructors associated with the class; in this case, objects are instances of the class. In the prototypal approach, you create a prototype object, and then instantiate new objects based on the prototype. Generally, a language is either classical (e.g., Java, Ruby, C#), or prototypal (e.g, JavaScript, Self, Io, Lua), though some languages let you construct objects both ways (e.g., ActionScript, Falcon).

What might prototype-based instantiations look like?

Simple Differential Inheritance

Perhaps the purest approach to a prototypal mechanism is one in which every object has an implicit link to another object, called its prototype. Whenever we look up a property in an object and it is not present, we go look in its prototype. If the property isn't present in the prototype, we search the prototype's prototype, and so on. (Writing a property is different, however; if the property doesn't exist in the object it is created right there.) Such a language might have an operator called beget which might be used like this:

var protoCircle = {x: 0, y: 0, radius: 1, color: "black"};
var c1 = beget protoCircle;
c1.x = 4;
c1.color = "green";

Here we have c1.x == 4, c1.y == 0, c1.radius == 1, and c1.color == "green".

We can create more circles:

var c2 = beget protoCircle;
c2.x = 4;
c2.radius = 15;
c3 = beget protoCircle;
which gives us this:

If we change any of the fields in the prototype, this change is picked up at run time by all the derived objects that haven't overridden those fields. Ditto for adding new fields to the prototype. To some people, this is convenient and flexible; to others it is ugly and error-prone. It's all those things, of course.

The prototype is also a great place to store function properties:

protoCircle.area = function () {return π * (this.radius ** 2);}

Here we've assumed we have a "this" operator which refers to the object through which the function was called (not necessarily the one along the prototype chain which ultimately contained the function).

Direct Cloning

Another approach is to define a prototype with default field values then clone it to make new objects. Cloning is different from simple differential inheritance because with cloning the new object automatically gets copy of all of the fields in the prototype, even for those that you wanted to keep the default values in the prototype. A clone operator might look like this:

var protoCircle = {x: 0, y: 0, radius: 1, color: "black"};
var c1 = clone protoCircle;
c1.x = 4;
c1.radius = 8;
c1.color = "green";

Cloning means c1 is going to get all four fields:

Cloning via user-defined functions

If a language does not have a built-in clone operator, or you just don't like the look of creating an object and then doing multiple assignments to override defaults, you can do the cloning and field assignments in a function. Default fields can be nicely managed with default parameters, in languages that have them:

function newCircle(x = 0, y = 0, r = 1, c = "black") {
    return {x: x, y: y, radius: r, color: c};
}
var c1 = newCircle(x => 4, r => 8, color => "green");
var c2 = newCircle(color => "yellow", r => 5);
var c3 = newCircle(_, 5, _, "blue"); 

or with a short circuit disjunction if you have that but no default parameters:

function newCircle(x, y, r, c) {
    return {x: x || 0, y: y || 0, radius: r || 1, color: c || "black"};
}
var c1 = newCircle(x => 4, r => 8, color => "green");

With cloning, we have the problem of where to put the objects' methods. How about global variables?

function circleArea(c) {return π * c.radius ** 2;}
function circlePerimeter(c) {return 2 * π * c.radius;}

That's awful! It pollutes the global namespace. What about putting them inside the objects?

function newCircle(x = 0, y = 0, r = 1, c = "black") {
    return {
        x: x, y: y, radius: r, color: c,
        area: function () {return π * this.radius ** 2;}
        perimeter: function () {return 2 * π * this.radius;}
    };
}

That's no good either — every time a circle object is created, two additional function objects are created for its area and perimeter. If we create thousands of circles we end up with thousands of identical area functions and thousands of perimeter functions sucking up memory. We should make sure we have only one copy of each (without defining global variables to access them). We want that nice little implicit link to the prototype back.

JavaScript Constructors

In JavaScript, prefixing a function call with new calls the function in a context in which the this expression refers to a newly constructed object, and, unless a return statement explicitly returns some other object, returns this newly constructed object.

function Circle(x, y, r, c) {
    this.x = x || 0;
    this.y = y || 0;
    this.radius = r || 1;
    this.color = c || "black";
}

It's also the case that JavaScript is prototypal, and weirdly so: every function is itself an object, with a property called prototype, whose value is the object that will be used as the prototype of every object created with that function. As usual, the prototype is the place where you drop in shared properties, like functions. Here's an example:

function Circle(x, y, r, c) {
    this.x = x || 0;
    this.y = y || 0;
    this.radius = r || 1;
    this.color = c || "black";
}
Circle.prototype.area = function () {return Math.PI * this.radius * this.radius;}
Circle.prototype.perimiter = function () {return Math.PI * 2 * this.radius;}
var c1 = new Circle(3, 8, 4, "green");
var c2 - new Circle(1, 7);
var c3 = new Circle();

Better Prototypal Patterns for JavaScript

It's pretty clear that JavaScript's new operator and the associated semantics for construction were designed to make the langusge look more classical. Douglas Crockford characterizes this beautifully by saying that "JavaScript is conflicted about its prototypal nature." He shows how to make JavaScript implement simple differential inheritance:

if (typeof Object.beget !== 'function') {
    Object.beget = function(o) {
        var F = function () {};
        F.prototype = o;
        return new F();
    };
}

Our running circle example can now be written like this in JavaScript:

var protoCircle = {x: 0, y: 0, radius: 1, color: "black"};
var c1 = Object.beget(protoCircle);
c1.x = 4;
c1.color = "green";

One of the nice things about using beget is we can hide away JavaScript's crazy new operator and never have to use it again. This operator is fairly confusing and error-prone. For example, when you call functions that are supposed to be called with new but aren't, the code ends up creating or overwriting global variables. Object.beget is a nicer approach.

ECMAScript 5 Improvements to JavaScript

Current JavaScript versions (as of mid-2010) are based on the 3rd Edition of ECMAScript, known as ECMAScript 3. The newly standardized ECMAScript 5 adds many properties to the Object object, including create, which is like the beget example above. In new JavaScript:

var protoCircle = {x: 0, y: 0, radius: 1, color: "black"};
var c1 = Object.create(protoCircle, {
    x: {value: 4}, 
    color: {value: "green"}
});

Much better.

2010-02-27

Object-Specific Methods

Sometimes a programmer likes to attach a method to a single object, instead of attaching it to all objects of a class. How can this be done?

We'll make three dogs, Sparky, Spot, and Spike. All dogs bark, but only Spike can bite.

Classless Languages

In JavaScript, just add function properties directly to the object:

var Dog = function (name) {this.name = name;};
Dog.prototype.bark = function () {return "woof";};
var d1 = new Dog("Sparky");
var d2 = new Dog("Spot");
var d3 = new Dog("Spike");
d3.bite = function () {return "GOTCHA";};

It is hard to imagine improving on that.

Singleton Classes

In Ruby, you add the method to the object's singleton class:

class Dog
  def bark(); "woof"; end
end
d1 = Dog.new("Sparky");
d2 = Dog.new("Spot");
d3 = Dog.new("Spike");
class <<d3
  def bite(); "GOTCHA"; end
end

The use of "<<" isn't as readable as it could be, at least for English speakers, so might there be other ways to do this for classes languages?

Object.add_method(d3, "bite", {"GOTCHA"});

d3.add_method("bite", {"GOTCHA"});

def d3.bite(); "GOTCHA"; end;

Regardless of the syntax, with a class-based language, each object will have an internal reference not only to its class, but to its bundle of object-specific methods.

Subclasses

In a language where classes are closed, you "extend" classes by making new subclasses. This seems a little uglier in our contrived example. In Java:

class Dog {
    private String name;
    public Dog(String name) {this.name = name;}
    public String bark() {return "woof";}
}
class BitingDog extends Dog {
    public BitingDog(String name) {super(name);}
    public String bite() {return "GOTCHA";}
}
Dog d1 = new Dog("Sparky");
Dog d2 = new Dog("Spot");
BitingDog d3 = new BitingDog("Spike");

This may be clunky, but it does make a lot more static analysis possible.