Interesting, I'm working on such a language at the moment. My last effort
sort of worked but being still statically linked lacked the spontaneity of a
proper dynamic language.
Well, if you are working on a language, may I give you my opinion?
Please stay away from pure dynamic typing. It seems like a good idea,
and can make initial coding easier, but run-time type conflicts are an
error that is impossible to exhaustively test for yet is easily
handled by strong typing. Implicit typing is a much better idea.
This way you can remain strongly typed, while still saving a lot of
the redundant type declarations. I think that C++ is trying to move
in that direction, but will not be able to escape the complications
from its C heritage.
I was thinking about doing a language design myself based on this
idea, but I don't really have the time and energy to see it all the
way through. My idea was to, in part, revive BASIC, by leveraging
explicit variable suffix naming conventions: a % suffix is a number, a
$ suffix is a string, and I would add # for associative arrays
(arbitrary mapped hash tables). The idea would be to have a type
system equivalent to Lua's except for strong typing by virtue of the
variable suffixes. (I thought it would be a good idea to have some
nice features like pervasive serialization, but that means its hard to
encode functions or system objects such as an open file, or a thread
as first class values.)
But so long as the associative array was not an explicitly described
type, you still had runtime type conflict potential. Perhaps it
could be saved by having a grammar of suffixes for variables names,
and some sort of declarations like:
#$ ::= { $ -> % }
#@ ::= { $ -> #$, % -> %, @(% <- setradius(%),% <- getarea()) }
where % means integer, @ means methods, and #$ and $@ are used defined
suffixes (and types). The idea, then would be that a variable that
had no suffix would, somehow or another, be implicitly typed. If a
function declaration had ambiguously defined parameters, then the
function becomes a template; the parameter types would be determined
at call site time. (Ambiguous or conflicting local variable types
would lead to a compile time error.) The idea would be to make sure
it was directly translatable to a C back-end. I also had a lot of
ideas for the optimizer (which for this language, it would be to infer
that a number was an integer, for example, or that a hash was really a
vector, or a fixed length array, or that a string was static, etc.)
My goals would be: Real type checking, but easy to program due to
implicit typing and automatic templating, and truly comparable to C in
terms of performance by way of very good translation to C code. But I
haven't really thought it all the way through.
All I can get out of OO are examples of things I've been able to do in
dynamic/interpreted languages for years. Maybe a bit of nice syntax and the
ability to package things neatly.
Hmmm ... as must be clear from my posts here, the ability to use the
type system to essentially have an "algebra on interfaces" is what
makes OO have some sort of relevance to me. Hiding an implicit "this"
pointer, or associating certain functions to certain data, just
doesn't do anything for me. But inheritance? Its the one real reason
to use OO as far as I am concerned.
Getting back to C (this is c.l.c), that's great as an implementation/target
language. For that purpose it should stay simple (ideally get even simpler
and shed baggage, but that's not going to happen).
Actually C is not a really great target language because I have never
seen one callable as a library. So the possibilities for
introspection are basically taken away from you, unless you demand
that your deployed software also have access to a local C compiler
(which generally cannot be relied upon). A lot of scripting languages
have a kind of x = dostring("a = b + c; return a;") kind of
functionality, which basically demand that you have a built-in
interpretor, but you are denied the possibility of compiling it
because the compiler is not a callable library. For this and other
reasons, scripting languages typically target a custom bytecode
machine.