Skip to content

Instantly share code, notes, and snippets.

@DmitrySoshnikov
Created May 17, 2011 18:19
Show Gist options
  • Save DmitrySoshnikov/977034 to your computer and use it in GitHub Desktop.
Save DmitrySoshnikov/977034 to your computer and use it in GitHub Desktop.
Classification of classes
// by Dmitry Soshnikov <[email protected]>
// MIT Style License
*Classification of classes:*
=============================================================================
| Dynamic | Static
-----------------------------------------------------------------------------
| |
| Coffee, Python, Ruby, | SmallTalk, built-in
First-class | JavaScript (w/o sugar), etc. | classes of Python, etc.
| |
-----------------------------------------------------------------------------
Second-class | PHP, etc. | Java, C++, etc.
-----------------------------------------------------------------------------
P.S.:
1. A *first-class* value -- the value which may participate as normal data. E.g. can be created literally
at runtime, passed as an argument, or returned as a value.
An example of a first-class function (JavaScript):
function foo() {
console.log(10);
}
// pass `foo` functions as an argument
// to the anonymous function which is
// created and immediately executed
var foo = (function (funArg) {
// apply the functional argument
funArg();
and return it back
return funArg;
})(foo);
Another example of a first-class class (Ruby):
class Foo
def baz
p "Foo:baz"
end
end
class Bar
def baz
p "Bar:baz"
end
end
def create(classObject)
# test the passed class
if classObject == Foo
p "Foo class is passed"
else
p "Bar class is passed"
end
# create its instance and
# call the `baz` method
(classObject.new).baz
end
create Foo # "Foo class is passed"
create Bar # "Bar class is passed"
2. A *second-class* value (or a *first-order* value) -- the value which is not the first-class value.
*Note*, second-class values can be used partially as first-class values, e.g. passed as arguments
(an example -- pointers to functions in C/C++). So the most important difference of a first-class
value is the ability to be created at runtime and in particular cases to be used as objects.
Regarding functions, "first-class-ness" is also related with static scope, i.e. the ability of
functions to be *closures*.
3. A *dynamic* value -- such a value which may be augmented or mutated at runtime. Mostly related to
objects. A class being a first-class value is also an object, therefore it can be mutated.
An example (Python):
class Foo(object):
def bar(self):
print(self.x)
foo = Foo() # an instance of `Foo` class
foo.bar() # error, no `x` attribute
# augment `Foo` class with `x` property
Foo.x = 10
# and it's available for already created
# instances -- the delegation is used, the
# same in JavaScript: "if a property isn't
# found in the object itself, then it's searched
# in the prototype/class"
foo.bar() # OK, 10
# or we may create own `x` for `foo` object
# thus, we `shadow` the inherited `x`
foo.x = 20
foo.bar() # OK, 20
# when own `x` is removed, it's again
# is found in the inheritance (prototype) chain
del foo.x
foo.bar() # OK, 10
# and now remove it from the class
del Foo.x
foo.bar() # error, no such attribute
4. A *static* value is an immutable entity. It may reflect a constant, or closely to objects,
"frozen" objects.
An example (JavaScript):
var foo = Object.freeze({x: 10});
foo.y = 20; // failure, or error in strict mode
Object.freeze(Object.prototype);
Having written a syntactic sugar for classed in JavaScript, we may freeze them. I.e. we may
transform a first-class dynamic entity to the first-class static. Another example of first-class
static entity as was mentioned are Python's built-in classes which cannot be augmented.
At the same time we may have second-class dynamic entities, for example objects of PHP classes:
class Foo {
function bar() {
return $this->x;
}
}
$foo = new Foo;
$foo->x = 10;
$foo->bar(); // 10
Dmitry.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment