Is it Time to Replace TI-BASIC?
|
Posted on 21 February 2005
The following text was written by George Limpert:
Anyone who remembers coding in TI-BASIC on the TI-81 or TI-85 and has then has coded
for a more modern calculator knows the language has made great strides. Many of these
changes have been influenced by the collection of nerds and gamers we affectionately refer
to as the TI community. When TI created their original graphing calculator models, they
never envisioned they would be used for the purposes we have found for them. A large
portion of the changes to the language reflect the ideas of students over a decade ago who
envisioned their calculators entertaining them during boring lectures. Despite the many
changes to TI-BASIC, the language is still looked upon by the best game programmers as
inadequate at best.
The complaint of many programmers about TI-BASIC is its speed, or the lack thereof.
Unfortunately this issue is unlikely to be addressed anytime soon. When TI designed the
language, they envisioned a way of adding new math functionality to the calculator, but
with safeguards in place to prevent harmful behavior by programs. Speed of program
execution is nice but doesn't appear to have been one of TI's primary objectives when
creating the language.
Some people will suggest any serious programming ought to be done in assembly language.
Compared with programming in TI-BASIC, it's like going hunting with a rifle instead of a
pocket knife; it's faster, more powerful, and there's nothing to stop you from aiming that
rifle squarely at your foot. If you make an error programming in TI-BASIC, you get an
error message awaiting you to press a key. A mistake programming in assembly might give
you a sudden boost of free RAM in exchange for your valued programs, equations, and notes.
It's probably best to do serious game programming in assembly, but what about other types
of programs?
Not too long ago, a fellow with a fine idea for calculator programming visited the
flagship IRC channel for discussing TI calculators. Instead of compiling TI-BASIC programs
so they run faster, he proposed replacing the language altogether. While he was met with
ridicule, the idea is worthy of further discussion.
Last semester, I took a course on data compression techniques. One project assigned was
to implement a Huffman encoder and decoder in C or Java. The discussion in class about
Huffman coding went in one ear and out the other. Instead of struggling with C, I decided
to implement the project first on my TI-89 because I expected TI-BASIC to be simpler.
After about five minutes into coding, however, I hit a roadblock; there's no easy way to
implement any sort of trees. Sure, it's possible, but to many programmers it's not obvious
how to create or manipulate trees. The solution is to represent each node as a list; the
first element is the value and the second and third elements are the names of child nodes
within the binary tree. The child nodes are then accessed using a wonderful feature of the
language known as indirection. On the TI-83 line of calculators, however, indirection
isn't possible, and one would have to use a matrix, instead. Manipulating a matrix is slow
and makes the programming involved even more complicated.
A tree is one of the fundamental techniques used in programming. It's applicable to
many algorithms including searches and sorts. Unfortunately it can't easily be done within
TI-BASIC.
This discussion also addresses another major limitation of TI-BASIC. What if, instead
of storing the name of a child node, I want to store another data structure, such as a
list, in one of those spots? The answer, of course, is it's not possible. One might ask
why anyone would want to do this. Consider, for example, if a programming task involved
pushing an integer and a list to a stack. While no such task readily comes to mind, it's a
reasonable proposition. Stacks are another fundamental technique of programming. And, of
course, complex data structures alone are useful at times.
There are many other such examples of why TI-BASIC is inadequate. Even if it will never
be a fast language, simple programming techniques in the language ought to be exactly that
-- simple. These limitations make TI-BASIC useless to many applications that are not at
all related to gaming.
Programming in assembly can be difficult and dangerous to your data. It also usually
requires a computer, a link cable, and a lot of patience. If that's not the best option
and TI-BASIC is inadequate, maybe another programming language isn't so absurd of an idea
after all.
The obvious question then becomes what features should such a language have. If a
language is to truly replace TI-BASIC, it ought to have all the features that TI-BASIC
currently has with some additions to fix the limitations with TI-BASIC. It's likely a
replacement for TI-BASIC would need to be interpreted instead of compiled. One might
assume that if we're creating a new interpreted language that has more features than
TI-BASIC that it would be even slower. This is not necessarily the case.
The architecture of compilers and interpreters are very similar. The first step in
either is referred to as a lexical scanner. This scans through the program text for
keywords and symbols. The output generated is a series of tokens which represent the text
of the original program. TI-BASIC does this as well; on some calculators, programs are
always represented as tokens, but on others you will notice a delay when running a program
for the first time due to this conversion. The next step of a compiler or interpreter is a
parser. This deals with the syntax of the language, converting the string of tokens to a
tree structure. A tree in an accurate representation of how a language is actually
evaluated. Following this step is semantic analysis. A statement in a language may be
syntactically correct but still make no sense to the compiler or interpreter. At this
step, actions such as checking type and scope of variables are performed. At this point,
compilers and interpreters diverge. An interpreter will evaluate the parse tree and
execute the statements while a compiler will output another language such as assembly
language or machine code.
This discussion on the architecture of interpreters is relevant because the
implementation of TI-BASIC is not necessarily the most efficient scheme. Most likely,
TI-BASIC stores programs merely as a stream of tokens because of the space required to
store a representation of a parse tree. A parse tree, however, can be converted back to
plain text just as the stream of tokens can. If parsing is only done once instead of being
done constantly during execution, greater speed can be realized. One need not stop after
parsing, however. Much of the semantic analysis step can also be performed at this time
without modifying the parse tree. One may view this as a trade-off between program size
and execution speed, but it need not be the case. A parse tree, when outputted to a file,
can be compressed and then uncompressed at runtime, which may gain back some or all of the
space lost to representing the program as a parse tree.
Another major change to such a new language is in the area of variables. There is no
method within TI-BASIC to store a reference to another variable. Therefore any reference
variables will necessarily be local to the interpreted program. Such a language, however,
would still need to provide easy access to variables from TI-BASIC. This means that any
variables that are to use the additional features of this language will need to be
declared within the program. If this is the case, it allows for a few other enhancements
to the language. One potential enhancement is the concept of aggregate data types.
Dealing with variables is a major slow point of TI-BASIC. The language on some
calculators provides two very useful features for programmers -- dynamic types and dynamic
resizing of variables. Dynamic types mean that if I have an variable currently storing an
integer and I choose to store a string it it, the variable becomes a string variable.
Dynamic resizing of variables means that the space used to store a variable is
automatically expanded or contracted depending on how much space is needed to store the
data. While these are very useful enhancements, they are also slow. A new language could
make these features optional to programmers, providing an additional speed boost.
In spite of these and other possible enhancements, some tasks are better suited for
assembly language. Furthermore, programmers shouldn't have to reinvent the wheel every
time they write a program. PHP had a good idea when it allowed modules to be added to the
interpreter that extend the functionality of the language. While a new calculator language
may be at the core a replacement for TI-BASIC, the ability to extend the language through
modules instead of writing a new interpreter makes the language far more powerful than it
would be otherwise.
TI-BASIC is a fine language suitable for many tasks. Assembly has many advantages over
TI-BASIC and has many uses as well. There are, however, many programming tasks that for
one reason are another are not suited well to either language. A replacement for TI-BASIC,
if sufficiently enhanced, can make TI calculators a far more powerful tool. The question
of a new programming language shouldn't be a question of if but of how and what.
|
|
Reply to this item
|
Re: Is it Time to Replace TI-BASIC?
|
Racer9
(Web Page)
|
I think that this is a good idea except for one thing, Everyone that knows TI-BASIC would have to re-learn everything they know. In my opinion we should keep the language but TI should add more commands and spped it up slightly. I think that if someone made an TI-BASIC to assembly compiler that runs on the calc that would compile a TI-BASIC file to an assembly file most of the speed problems would be solved. I would work on this but I am just learning asm now.
|
Reply to this comment
|
21 February 2005, 16:28 GMT
|
|
|
|
|
Re: Re: Is it Time to Replace TI-BASIC?
|
Rob van Wijk
|
The speed (or slowness) of Basic is not the primary concern at the moment. I know that's what we've been calling for years, but now George Limpert mentioned a way more interesting point.
Even though it's always been widely known there are a lot of things Basic can't do (graphics, memory management, ...), I don't think people have often realized you can't properly create a tree in Basic, or define your own data types for example. For instance, I've personally always known which data types I could use, but I can't remember consiously being aware of the limitation of not being able to create a simple record (Pascal) or struct (C). Working around these limitations quickly became a second nature, and I never even consiously saw them.
The way I see it, the inherent limitations of Basic, and whether they are so severe they warrant the development of another language, should be the central point of this discussion. Speed is quite irrelavant, there will always be enough tricks to get extra speed.
|
Reply to this comment
|
21 February 2005, 22:29 GMT
|
|
Re: Is it Time to Replace TI-BASIC?
|
Travis Evans
|
Does anyone know if Python would be a feasible language for a TI calc? IIRC, you can extend the language with modules written in other languages, like C or ASM. It's also pretty easy to learn, and quite powerful.
|
Reply to this comment
|
21 February 2005, 22:51 GMT
|
|
[ ! ]
|
anykey
(Web Page)
|
I think Ti Basic should work more like Python; you can have modules and dynamic variables.
Here's an example of how Python does modules:
I've got a program called example.py that contains an object that I'd like to use in my main program, main.py
example.py:
def say(text):
(tab)print text
main.py:
import example
say("Hello World!")
See? That was easy. You can also import specific functions without having to import the whole thing.
|
Reply to this comment
|
21 February 2005, 23:12 GMT
|
|
Re: Is it Time to Replace TI-BASIC?
|
Travis Evans
|
I was impressed at the improvement of 89 and 92+ BASIC, but I still have a lot of gripes. Here are some off the top of my head (there may be others that I forgot about):
1. Subroutines are still a pain if you don't want them stored in separate files cluttering everything up. You could use the Local statement to create local subs that are deleted automatically when the program quits, but then they can't call each other. The only other solution I can find is define the subs and functions in your program and delete them manually when it exists, which has its own disadvantages. (One being, if an error occurs or I break the program and choose GOTO, I often forget that my changes will be overwritten when I restart the program unless I remember to edit the *original* program instead (and I have to search for the sub or function there to do that). Changing code only to have it overwritten and have to do it again isn't fun.)
2. Functions can't use instructions or I/O operations. (Whose dumb idea was that, anyway?) If you want something to use instructions or I/O and have it return a value, you have to resort to global variables (ugh).
3. Variables can't be passed to subs or functions by reference, which means that if you want a sub or function to modify a variable, you once again have to resort to globals.
4. Navigating large program files is a pain (the Find... function helps, but it would be nice to have true inline subs/functions and be able to jump to them using a menu).
5. No debugging tools.
6. Local variables are cleared when a program hits a runtime error, making debugging difficult unless you change them to globals or put Disp or Pause statements in your programs.
|
Reply to this comment
|
21 February 2005, 23:16 GMT
|
|
|
|
|
Re: Re: Is it Time to Replace TI-BASIC?
|
Travis Evans
|
Here are the rest (ticalc.org enforces a limit on post length--too bad we can't use a mailing list or something to discuss this).
7. For some reason, when an error occurs and I choose GOTO, the cursor doesn't always appear exactly where the error actually is (and then it takes me forever to figure out what's wrong as a result).
8. Inconsistent syntax/parameters for some functions.
Example 1: RclPic takes picname, picrow (y-axis), and piccol (x-axis), but StoPic takes picname, picrow (y-axis), piccol (x-axis), width (x-axis), and height (y-axis). It would seem more logical for the order to be height (y-axis), width (x-axis) instead, for StoPic.
Example 2: Output takes row, col, expr, but PxlText takes str, row, col. Logically, it should be either expr/str, row col, or row, col, expr/str for both instructions.
9. Toolbar instructions require using Lbls, so they essentially force you to use Gotos. (Even if you don't actually use the Goto command, the menus are essentially Goto statements.)
10. A few instructions would work better as functions (e.g., SortA and SortD), so you could use them in functions (although I think instructions should have been allowed in functions, anyway).
11. Some functions/instructions are too "picky" as far as data types are concerned. Example: checkTmr() gives an Argument error if you pass it a value in the Approx mode setting, even if it is an integer. In that case, you have to use the exact() function on the argument for it to be accepted.
Anyone have any others?
|
Reply to this comment
|
21 February 2005, 23:17 GMT
|
|
|
|
|
|
|
|
Re: Re: Re: Re: Re: George Limpert Asks: Is it Time to Replace TI-BASIC?
|
CajunLuke
(Web Page)
|
1. Local subroutines can too call other local subroutines. I do it all the time.
2. It's common programming practice to disallow/restrict/dissapprove of input/output statements in calculational functions. The point of a function (in 68k locution, function vs. program) is to do a calculation with data input through the parameters, and output through a Return command. It is not supposed to disrupt the calling program's input/output scheme (maybe the end programmer likes a different format than you do). They can, too use instructions, just not all of them. The TI-89/92+ manual has upwards of fifty pages on the commands available built-in, and a list of maybe ten or fifteen commands that function's can't use.
3. Point. (Although I've never had reason to use reference variables.)
4. Point. I get around this by using descriptive comments and searching for those or memorizing a unique line of code in the section (usually the label).
5. Point.
6. That's the point of local variables. Changing them to globals is as simple as commenting out the "local" statement.
7. It appears at the beginning of the line, sometimes. That's all a C or Java or Cocoa compiler gives you anyway, so be happy when the cursor is in the middle of the line.
8. Point.
9. And this is a problem.....how?
10. Point.
11. I leave my calculator in Exact, anyway, so I've never had this problem.
Overall, TI appears to make you use as much of the MVC paradigm as possible in a function-oriented language. Kudos, although it can be irritating at times. It could also be entirely accidental.
|
Reply to this comment
|
27 February 2005, 16:25 GMT
|
|
1 2 3 4 5 6 7
You can change the number of comments per page in Account Preferences.
|