Study of Dynamically Typed Languages
Dynamic Typing
A pure dynamically typed language
- Has no typechecker as part of the compiler which rejects
programs based on their types
- Detects type faults at runtime, e.g. adding a number and
a function, etc, raising an exception.
- Tends to run slower due to the need for run-time overhead; with
major compiler development can be made to run somewhat fast.
- These languages tend to be better for small- and perhaps
medium-scale applications, and tend to be worse for large-scale
applications.
- Can be more freewheeling: incrementally add code, no need
to mess with types, etc.
- Freewheeling style bites you for larger apps which don't
fit in your mental cache anymore
- Speed penalty limits applicability
- They sometimes run in an environment where the codebase is
itself a mutable data structure
The non-OO school
- Lisp - the original dynamically-typed language
- Scheme - (add1 Lisp)
- Scripting
languages, e.g. the UNIX shells (sh, csh), awk, tcl, etc.
- early Perl (pre-5)
The "classic" dynamic OO languages
- Smalltalk
aka squeak
- CLOS, the Common Lisp Object System
- Dylan - based on CLOS
The "modern" school
Dynamically typed languages and our Fb
series
- Our FbSRXVOB mash contains the core features of
a dynamically typed language.
- We did not cover how run-time type errors lead to exceptions but
its simple: add a bunch of runtime type error handling rules including
| (- Mismatch Bool Left) | | e ==> True |
| | e - e' ==> Raise (#TypeMismatch True) | |
etc -- many such rules are needed. But, thats about all there is to it.
- As with Java there are also some dimensions of these languages we
missed, in particular all the reflection-type stuff and dynamic
code loading.
We will now look at some crosscutting aspects of these languages.
Blocks of code aka higher order functions
- Lisp/Scheme:
(lambda (x) ... ) - Lisp was the first
language with implemented higher-order functions
- Smalltalk: code
blocks
- Ruby: blocks which are similar to Smalltalk's.
- Python: lambda-forms
"Everything is an object"
There are various degrees to what this means.
- Smalltalk is pretty extreme.
- Ruby has most of this:
- Classes are objects in Ruby. For example the
inherited method
of the class is run when a new subclass is defined.
NilClass is also a class, as in Smalltalk (where it is Nil)
- There is also a global dictionary in Ruby that contains the defined classes,
Objects.constants
- Python: classes are also objects.
Public/private/protected
- Smalltalk: fields private, methods public. Put things in a
"private" protocol (category) if they are local
- Python: everything public (but use the C convention of starting private things with a "_")
- Ruby: public/private/protected
First-class methods
This means methods are objects so can pull out a method and stash
it in a variable, then call it later. Our encoding of objects
in
FbOB allows something like
this in how methods are functions so you can extract the method and
then stash it somewhere.
- Smalltalk: not directly.
- Python: yes. Example.
Notice how they are treating objects very similarly to how our
FbOB enoding works.
- Ruby: yes. Example.
Reflection
Given some object at runtime, can you poke around to find its class, methods,
etc? (another term for this is it has a
MOP - a Meta-Object Protocol) This stuff is very easy to
do in a dynamically-typed language because the program data structure
is around explicitly at runtime.
- Smalltalk - yes.
- Can easily turn a string into a method name to
invoke.
- Objects can also
become a completely new behavior.
- Ruby - yes.
- Can turn string into method to invoke - documentation
- Can add methods to existing objects - documentation
- Can take an object an specialize it with its own
singleton class, adding new methods; the objects old
class becomes the superclass of this new class. example
- Python - yes.
- Can change the class of an object at runtime.
Related to
become of Smalltalk
Ruby is much cleaner here, it has clean notions of adding methods and
Smalltalk and Python can blow up because methods will disappear, and
field references are wacky.
Inheritance
- Smalltalk: regular single inheritance
- Python: multiple inheritance (and the associated Diamond
Problem of course)
- Ruby: single inheritance plus arbitrary mixin
modules. Modules are like classes but since these modules are themselves at the top of
the hierarchy (modules cannot have supermodules) there is no
dreaded diamond property -- you can only build three of the four
edges of the diamond.
Overloading and shortcut syntax
- Smalltalk - can do it yourself manually since operators are all only
messages (but ugly); no regular expressions
- Python: built in
- Ruby: built in