Created
May 17, 2011 18:19
-
-
Save DmitrySoshnikov/977034 to your computer and use it in GitHub Desktop.
Classification of classes
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// by Dmitry Soshnikov <dmitry.soshnikov@gmail.com> | |
// 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