|
LIMA - a high-rise programming language
|
 |
 |
 
I thought about making
my own programming language in mid 2005, because I was bothered by the
weirdness and inefficiency of C programming. Since then I've seen the
even greater weirdness and inefficiency of other languages, and come to
the conclusion that a big change in programming languages needs to
happen. Most languages seem to rely heavily on library functions
which are not part of the core language. Since they aren't part of
the core language, they don't always have consistent usage and
aren't integrated in a way that helps you program concisely.
Lima (pronounced "Lie-muh")
is designed to be easy to learn, write, and read while incorporating all
the control and more one would expect after coming from C, C++, and
Java. Here's a few attributes of the language:
- Powerful type system
- Strong typing gives the programmer fine
control over the data flow in their programs.
- Static typing allows automated error checking
and method validation.
- Assertions, and pre- and post- conditions augment the static types variables to be very specific as to what
values a variable can take on, and when they can take on those values.
- Dynamic typing - The var type provides
a flexible dynamic type that can be used to hold a value of any
type.
- First-class types - the type 'type'
can be used to define a variable that holds a type. These types can
be passed into functions and manipulated like any other variables.
This allows for the maximum flexibility in defining generic
functions and objects - flexibility other languages like Java and
C++ don't allow.
- Object-oriented
- Everything is an object - even types and
functions are first-class.
- Multiple-inheritance is supported in an
unambiguous way. In the case of inheritance name conflicts, if a
variable or function name conflicts, the programmer must explicitly
specify which class a variable or function name will come from.
- A simple public/private variable scheme
allows any class in a module (i.e. in a source file) to access the private
variables of other classes in the same module (i.e. in the same
source
file).
- Transparent getter, setter, and accessor
methods (like python and ruby have) make getter/setter code both
easy and unnecessary in most cases.
- Generics syntax like object<type<int>> is
supported - albeit in a different and more flexible way than other
languages that use similar syntax.
- Static and dynamic function dispatch are both
supported through two different variables types: className
and className+. Variables declared as "class" can only hold
that class, while variables declared as "class+" can hold that class
and any other class that inherits from that class. This provides a
concrete dispatch mechanism that doesn't exist in any other language.
- Imperative programming
- The paradigm you're familiar with.
- Declarative programming
- Lima is designed with the thinking that
machines should do optimization, not humans. Some core functions in
lima don't use a specific algorithm, but will use an algorithm that
the compiler determines best suits your specific program. If you so
choose, you can specify an algorithm to use in these cases. But
instead, consider writing an optimization plug-in that can optimize
for your specific case. If you then release that plug-in, everyone
can benefit from your optimization work, and you won't have to solve
that optimization problem again.
- Pass by reference - no catch
- You can modify variables inside functions
without restrictions or special syntax
- The editor will tell you which functions are
mutators, and which variables they mutate.
- Meta-programming - custom languages
- The "custom function" and "custom class"
constructs allow you to easily create domain specific languages that
can be used directly inside lima code. These allow you to quickly
produce your own syntax and design practical and experimental
languages for general or specific use.
Like Ruby's philosophy, Lima is designed for
the human, not for the machine. Lima has high-level constructs in
the core language that have implementations depending on use (but
consistent meaning despite implimentation). The
general list type can be used like an array, set, queue, stack,
associative array, etc. Lima also has a graph type that allows the
programmer to associate data in an arbitrarily complex way - but in a
way also supported by the core language. Separating meaning from
implementation is important for program readability and programmer
productivity. It also encourages programmers to add to and improve
compiler optimization algorithms, rather than hacking together original
(or not so original) implementations on their own.
Unlike other languages, Lima relies on an active development environment
to make reading, writing, and debugging Lima code easier than sleeping.
Lima's terse non-redundant syntax means that some properties of
variables and functions can be discerned from use rather than being
explicitly declared (like function return types, whether or not an
argument may be modified by a function, etc).
The ability to produce "custom functions" using
the
parse
function makes Lima ideal for creating micro-languages and domain
specific languages for use in normal programs. The parse function goes
far beyond functions like strtok() and "regular" expressions that have
limitations, poor readability, and a high learning curve. It
allows arbitrary parsing of any type of list, not only strings.
Lima is a high-rise language,
which means that it has all
low-level constructs but also has high level constructs that allows
the programmer to choose the level they want to interact on at every
step in the program.
Lima is a
transparent language. Lima is built to collapse complexity rather
than hide it. The final Lima editor should allow a programmer to examine
various lower levels of code generated by the optimizer, even down to
the assembly language level. Hiding complexity is fine enough for
programmers that don't care about the inner workings of their computer,
but de-collapsing such complexity can be extremely enlightening - which
is why Lima incorporates this idea.
Lima is a
multi-paradigm language. Lima is based
heavily on "imperative", "functional", and "object-oriented"
programming. In addition to this, the language also uses "constraint
programming" paradigm in Lima's
parse
function. "Concurrent" and "distributed"
programming will also be incorporated as well as easy graphics and application
programming.
Lima makes readable projects. Makefiles are evil.
Open source
projects generally have a source tree that is more or less
unintelligible, because they rely on makefiles to tell the computer
which files to compile how and when. Unfortunately, makefiles are not written
for humans in most cases. Lima is designed to need no compiler flags (and no makefiles) to be easily compiled. A Lima program contains one
main file, which must contain all the information it needs to compile.
Linked libraries and included modules are all declared in the main .lima file.
Every other file should be a .lh file that is used by the .lima file.
Compiling the project is as simple as compiling the .lima file.
|
 |
 | |
 |
 |
 
The syntax of Lima is designed to be as
consistent as possible, so that both new and experienced programmers can
learn the language quickly. Being consistent also produces a concise
language, so that old programmers never have to look up old concepts.
The syntax is based off of C++ but also takes from Java, Python, D,
Verilog, Boo, Ruby, Lisp, and Water. Like python and Boo, unnecessary semicolons don't
appear everywhere. Like C++, Java, and D, blocks are delimited by
brackets (though they are square brackets in Lima). And like most of
those languages, whitespace (tabs, spaces, and newlines) is generally ignored
(except as a delimiter between language tokens/keywords).
Lima gets its white-space delimited lists from Lisp and
Water (an xml-based programming language). Lima takes the concept
of blocks and its syntax partially from Ruby and Boo, its getter and
setter ideas from Ruby, a high impedance value from Verilog, object type
assertion function from Java generics, auto documentation and
iteration syntax from Java, and different modes of type casting from
newer versions of C++.
Some claim that lisp makes no distinction between run-time and
compile-time, but lisp's macros are evaluated at compile-time, while
functions and the like are evaluated at run-time. Lima really does
make no distinction between run-time and compile-time, but attempts
to
perform at compile-time as many of the statements that it can or make any number of simplifications and
substitutions at compile-time to make the run-time more efficient.
In cases where program size is at odds with execution efficiency,
the programmer should be able to decide which takes precedence and
by how much.
Lima treats the whole process from a blank source file to a
completed and executed program as a single event that should be
optimized.
|
 |
 | |
 |
 |
 
Industry has
shown us that customization is really an alias for lazy-design -
where designers add options and preferences because they don't know
what the defaults should be. Even if companies would (please)
produce good quality customizable products, one would always be
lacking if they didn't have the ability to program themselves. Some
people see a future where everyone will have the knowledge and
ability to program their own computers to do what they want them to
do.
Lima is
designed to be a programming language that is both simple and
powerful - a programming language that anyone can use effectively,
for any task. This may be ambitious, but it has to be to compete
with today's languages. Because of this, Lima shouldn't be bogged down with obscure
libraries which could be needed to provide necessary functionality.
Lima can't be a second C++ that uses antiquated syntax. Lima can't
be a second Java, which uses long fully specified class names and a
huge set of libraries. Lima can't be a second Basic either, because
it should be able to perform any function that the computer allows.
Here are the
current goals:
1. Write the Parse Standard Function so that it works for programming
Lima.
2. Write a program to parse some basic Lima
4. Rewrite the Parse Standard Function in Lima.
3. Modify the Parse Standard Function so that it works for any input.
4. add the rest of the basic features of Lima
5. add graphics, sound, and application creation specifications
to Lima - based on OpenGL, GLSL, and SDL and maybe OpenAL
6. add networking and threading specifications to Lima
7. Get some people (whoever's still reading this) interested in Lima
8. Get some of *those* people ^ to help me work on all these things.
9. Start a wiki where people can discuss how to improve the language.
Here are some
of the lofty goals:
1. Provide a concise core vocabulary that allows efficient and simple
programming for any application without need for extra libraries.
3. Be able to translate into and from a wide variety of languages including C,
C++, mips, Java, PHP, Fortran, and html+javascript+css.
4. Be able to translate into machine code for any notable platform.
5. Be able to translate into machine code that runs without an OS (most
likely this would be used to program an OS).
6. Implement a way to write interactive web pages using dynamic
programs instead of static HTML.
7. Also formulate a way to translate lima into HTML and javascript so
that Lima can create working classic web pages.
8. Implement a garbage collection system for the language as an *option*, allowing both explicit garbage collection calls and automatic collecting.
Here are some
of the more specific long-term goals:
1. Be portable, while everyone seems to be coming to x86, not everyone's
coming to [insert your favorite OS here].
2. Use in-code comments to produce out-of-code documentation.
3. Provide a comprehensive and well thought-out compiler and development
environment that provides the ability to run Lima as an interpreted language
(allowing run-time user modification of code, helping in debugging).
4. Provide unobtrusive smart error checking and semi-automatic error
correcting in the development environment.
5. Have the compiler provide default error messages to the user so
that those types of things don't have to be programmed explicitly every
time. Errors that are manually handled would automatically disable the
default error messages.
5. Allow the user to specify how optimized they want the code to be.
Less optimized code compiles faster, and allows the programmer to build
and test faster when optimized code is not imperative. Also allow full
program optimization to optimize the entire project rather than just by
section or file.
|
 |
 | |
|
 |
 |
 |
|
|