What is Calq?
Calq is a web application that interprets a simple sequence of programming
commands
(click here for a
list of calq commands).
I encourage you to try it out
by putting your commands in the top text-box (the bottom one is for results).
This project started as a teaching tool. In the "old" days, the family
computer came with a version of the BASIC programming language.
Many current computer scientists and computer engineers learned
about programming with this language. They could type in a program,
or even commands one-at-a-time, at the computer would respond.
This experience is about getting the computer to do what you want;
about telling the computer what to do, and having to refine the commands
when they do not work as expected.
Today's typical family computer does not come with a programming
language for curious beginners to explore. Instead, you would need to
download and install the programming language. Free ones do exist,
but the beginner may not even be aware of this. And installing
software takes some level of technical ability that beginners
lack.
This project aims to rectify the situation.
It presents a simple interface; a text-box at the top for your commands,
then an "evaluate" button, then a text-box for the computer-generated
results.
Brief History
The first version was written in C++. A webpage presented the
textbox for the commands, with an "evaluate" button. Pressing the
button accessed the CGI program, which created a web-page as output.
It could do basic calculation, and worked fairly well. I'm comfortable
programming in C++, and I was able to re-use some C code from an earlier
project. Also, C++ allowed some flexibility with the "union" keyword,
where the program could store several different types of data in the
same space, and return whatever form was desired. That is, a variable
could be an integer, a floating-point (double) value, or a character,
even though these have different representations internally.
But one thing bothered me about the above approach. The code would be
interpreted by the CGI program, running on my server. This would not
scale well at all. If the program became popular, then my computer
would be slowed considerably by other people's usage. Also, there is
the possibility that someone could write a program that never ends,
but ties up my computer. A better approach would be for the interpretation
to happen on the user's computer. Languages like Java and JavaScript
would allow this.
I heard about Google's Web Toolkit (GWT), and realized that it could solve
this problem. GWT generates JavaScript from Java programs. While the
names are similar, Java and JavaScript are two different languages.
The end result is that people could use Calq with a minimum of stress
on my server, and could run it as long as they like on their computer.
Could they create a Calq program that would take a lot of their
computer's attention and not end? Yes, but all they would need to do
is close their browser. It's a totally safe environment, even if they
ask their computer to do something that never ends.
What is the difference between calq and Jcalq?
Calq is what I called the original version, from "calculate" only with a
"q". I started calling the Java version "Jcalq". But since it has
worked out well, the "J" was dropped in future versions.
The version number (such as 3.1) is enough to
distinguish between versions.
Current Status
I don't get as much time to devote to this project as I would like.
This means that progress is often made by large jumps, at irregular
intervals. I have a lot of ideas about where this project should go,
especially if I get some assistance.
Consistency has been a problem.
An innocuous-looking change can cause a problem elsewhere.
(For example, I recently standardized the variable access so
that it occurs in only one spot. But this caused a problem with the
FOR loop, where it would give an error because the index variable
did not yet have a value.)
To address this, I have a set of
Test Cases
that should work on the most-recent calq version.
(Older versions may not support all commands in the test cases.)
Currently, it supports the following commands.
- Here is a list of calq commands.
- comments, for example:
% This program is an example
Comments start with the percent-sign, and go to the end of the line.
The computer ignores these.
- calculations with +, -, /, *, and parentheses, for example:
(5-4)/(3*2) + 1
The parentheses give the order of precedence. Otherwise, it goes from
left to right doing division and multiplication first, then scanning
left to right again doing addition and subtraction.
- logic and comparison operations, like
==, >, <, >=, <=, !=, &&, ||,
for example:
5 > 4
which would return a value of 1.0 (true), since five is greater than four.
The double-equal-sign (==) is used to signal comparison for equality.
This differentiates it from assignment.
- assignment, for example:
x = 4
creates a variable called "x" and stores the value 4 in it. Anytime that
we use "x" again, the computer will substitute in the value 4.
Unlike some languages (C++, Java), you do not need to declare your
variables before you use them. All variables are type double by default.
This means that you can store a number like 3.1415926 if you want.
- display (disp), for example:
disp('hello')
displays the word "hello" on the output.
- conditionals (if statements), for example:
if (x == 4)
y = 1
else
y = 2
end
Note that the indentation is a good idea, but not required.
This example sets variable "y" to either 1 or 2, depending on the
value of "x". It is like instructing a person, "if x has the value 4,
then give y the value 1. Otherwise, give y the value 2."
You can nest if-statements inside other if-statements, such as:
if (x == 4)
if (y < 2)
z = 1
end
end
In this example, "z" will be set equal to 1 only if both conditions
are met. You can also do this with the double-ampersands in one
if-statement.
- loops (while and for statements), for example:
x = 1
while (x < 5)
disp('hello')
x = x + 1
end
This example will set x to 1. Then it will write "hello" to the output and
increment x, over and over again until x has the value 5.
Here is another example, using a for loop:
for x = 1:5
disp('hello')
end
It does the same thing, but automatically increments "x". Also, we don't
have to define "x" before this loop.
- functions (such as cos and sin), for example:
pi = 3.14159265
x = cos(2*pi*10)
In later versions, more functions are defined, and pi is pre-defined.
While it would be nice to expand the number of functions available,
I have an idea about making this more flexible that would make a good
research topic.
Version 2.1, supports these additions.
- ranges are supported, with increments of 1, such as:
200:210
generates the numbers 200, 201, 202, ..., 210.
cos(2*pi*(0:99)/100)
generates numbers 0 to 99, multiplies each by 2*pi, then divides
each by 100, and finally finds the cos on each.
- arrays (up to 1000 values)
t = 1:100;
t(50) = 0;
x(11:15) = t(61:65)
Note that in Versions 2.1 to 2.1.2, the arrays are indexed from 0.
For example, t(0) returns the value 1.0 above.
Starting with Version 2.1.3, arrays are indexed from 1.
For example, t(1) returns the value 1.0 above, while t(0) would now generate
an error.
- output suppression with the semi-colon
y = 1:100
prints all 100 of y's values to the output.
x = 1:100;
does not print x's values to the output.
- pi is a built-in value,
disp(pi);
- errors appear as alert messages instead of throwing an exception.
Is this annoying when you have multiple errors? Yes, since a single
error can result in a cascade of error messages. Later versions
starting with 2.1.2 suppress all errors after the first one.
Version 2.1.2 supports these additions.
- multiple errors only generate an alert for the first one.
- plot seems to work! Here's some code to try:
t = 0:99;
x = cos(2*pi*5*t/100);
plot(x)
A graph of x should appear at the bottom of the screen.
- The text entry areas are smaller. While the old size worked well
on a regular computer, it was too large for a small screen like the
iPod touch.
- "whos" gives some information about the variables.
- There is a function called "params", used for debugging.
(This may be deleted later.) It evaluates the parameters
passed to it.
- "length" returns the length of an array, such as:
t = 0:99;
length(t)
returns the number of elements in
t.
Version 2.1.3 supports these additions.
- Change array index to start with 1, not 0
- Fixed problem with embedded function calls, e.g.
myarray(1:length(myarray))
- Fixed problem with nested square brackets, e.g., ([3])
- Added:
floor ceil round fix rand abs min max sqrt exp log log2 log10
tan acos asin atan sum, all of which expect a single
value or an array as parameters.
For example:
floor(1.2)
x = [1.23, 4.56, 7.89, -0.123456789];
floor(x)
- Added: rand
which expects a single, non-zero, integer value as a parameter.
That parameter specifies how many values to return.
For example:
rand(1)
x = 4;
rand(x)
- Added functions for exponentiation,
^ .^,
as in:
3^4
x = 1:4;
x^2
- Added load and ls commands. Try
load('ex1') for an example.
You have to know the filename in advance, though.
This is where the ls command comes in; it gives a list of files
that you can load. (It may also give other information, like
the permissions, the owner, the file's size, and when it was created.)
Try this: enter
ls
then press "evaluate" for an example. You should see "ex1" plus a few
other files.
Version 2.1.4 supports these additions:
- ls command now sends results to the bottom window.
- elseif is now supported. Here is an example:
for x = 0:4
if (x==2)
disp('two');
elseif (x==3)
disp('three');
elseif (x==1)
disp('one');
else
disp('x is not between 1 and 3');
end
end
- conv for convolution, such as:
conv(10:12, 5:9)
or:
y = 1:4;
z = 6:9;
x = conv(y, z)
(This should work now, but could use more testing.)
- tic and toc for recording the elapsed time, e.g.:
tic;
i=0;
for k=1:100
i = i + 1;
end
toc
This reports the elapsed time in seconds.
- there is also a time function, mainly to check that tic and toc
work.
time
It returns the time of day.
Version 2.1.5 supports these additions:
- string support is expanded, e.g. each of the following works:
a = 'string';
a + 4
a = 'value ' + '4'
b = 4.3;
a = 'value= ' + b;
disp(a);
a = strcat('hello ', 'there')
- complex numbers are now supported. i and j are predefined as sqrt(-1).
But currently they need to be multiplied to form the number, i.e.:
a = 4 + 3*j
while (in this version) the following is NOT understood:
a = 4 + 3j
- Most functions and operations were updated to also work with
complex numbers (except atan, acos, and asin).
- fft and ifft, though arrays are expected to be a power of
2 in length, e.g.:
X = fft(1:8);
x = ifft(X)
- a "call" function contacts the server and runs remote CGI programs.
Currently, there is one function called "echo" that just returns
a string with "Echo" in front of it. For example:
call('echo', 'hello')
Another function is called "echo2" that has similar results.
Also, a "dir" function returns a directory of the currently defined
functions. It still expects 2 parameters, but the second is ignored.
call('dir', 'hello')
- The font was changed to courier (monospaced)
Version 2.1.6:
- Fixed bug where disp('hello ' + a); did not work while disp(a + ' hello'); did.
Version 2.1.7:
- Fixed several bugs.
- Allows ranges to be specified with an increment, e.g. 1:0.5:2
- call function was improved
- num2str
- str2num
Version 2.1.8:
- Since HTML5 supports a local storage, this version now has buttons
for "load" and "save". This saves (or loads) the program in the
top text-area, locally, at least until you save something else
or clear your browser data. (You may have your browser configured
to clear data every time you close the browser. Or you could have
it keep this around for years. See the local "preferences".)
Also, make sure you have a recent browser that supports this.
Version 3.0:
- Plot now uses HTML5's canvas, and the graph appears in a pop-up window.
Version 3.1: (March 2013)
- New reshape and setsize commands allow some matrices.
For example, the following code:
a = 1:9;
b = reshape(a, 3, 3);
b .* a
produces the following output:
1 4 9
16 25 36
49 64 81
- whos now returns
size information as NxM, instead of the length.
- Matrix access is working, with reshape and setsize commands.
(These do the same thing.)
c = reshape(1:25, 5,5);
c(1:3, 2:3)
- Matrix specification is also added.
d = [1, 2; 3, 4; 5, 6]
- Matrix commands now include eye, ones, zeros, transpose:
eye(3,3)
ones(3,2)
zeros(2,3)
a = [1, 2, 3; 4, 5, 6]
b = transpose(a)
- It now supports matrix access.
B = [11, 12; 13, 14; 15, 16];
B(2,2)
- It now supports matrix multiplication.
A = [1, 2, 3; 4, 5, 6];
B = [11, 12; 13, 14; 15, 16];
C = A * B
- You can also do element-by-element multiplication.
A = [1, 2, 3; 4, 5, 6];
B = [11, 12; 13, 14; 15, 16];
C = A .* B.'
- It now supports the switch..case..otherwise..end statement.
a = 3;
switch a
case 1
disp('one');
case 2
disp('two');
case 3
disp('Your number is:');
disp('three');
otherwise
disp('not one, two, or three');
end
- It now supports the try..catch..end statement.
try
disp('trying a command that does not exist');
psid('this makes no sense');
disp('did we make it here?');
catch
disp('caught an error');
end
Version 3.2: (July 2013 to March 2014)
- Fixed bugs, such as printing complex numbers without the imaginary part.
- It now supports det, inv commands.
A = [1, 2; -3, 4];
inv(A)
det(A)
Version 4.0: (August 2014)
- It now supports 2 or 3 parameters to the plot function.
x = 1:10;
y = x^2;
plot(x,y,'g');
- It now supports the return statement.
return
- There is a small image under the "Load" button that turns red when
it is busy running your program, then green when it completes.
- It recognizes user-defined functions within the script, and
executes them. It allows recursion.
factorial(5)
function out = factorial(in)
if (in > 1)
out = in * factorial(in - 1);
else
out = 1;
end
This returns the value 120.
Version 4.1: (June, 2016)
- Re-compile and hosting on a new server.
The original server for this project, carmaux.cs.gsu.edu,
will be retired. Originally, the plan was to unplug it on
January 1, 2018, though the move took longer than I expected,
so I'll probably keep it going a while longer.
Accessing calq pages on the old server should redirect your browser
to the current server, hallertau.cs.gsu.edu.
Version 4.2: (October 2017)
- Most recent changes (since 4.0) affect how it works "behind the scenes".
While the updates are important, you are not likely to notice them.
One of the changes is that server-side programs have been rewritten
from one scripting language to another (BASH to PHP). This should make
the project easy to copy to a new location.
- The plot2 function is
no longer supported.
So it's a calculator?
No. While it provides the functionality of a calculator, it is meant
to be a scientific programming environment. While calculations are
important, it also provides the structure and logic of a programming language.
Future Work
This is a work in progress.
See the known bugs page for any problems.
It would be nice to add more functionality, including:
These things can be added or fixed, but it takes time.
Postscript
Let me know if you find any bugs.
I cannot guarantee that I'll answer back, but I appreciate your interest.
If you send me an e-mail, put "calq" somewhere in the subject line
so that my spam checker won't discard it.
I do not have time to answer all e-mails that I receive.
Disclaimer: this is an experimental project. Do not assume that the
results are valid.
This project is licensed through the
GNU General Public License.
If you want a copy of the source code, contact me (the author) below.
I am interested in working collaboratively on this project.
Be sure to put "calq" in the subject line of your e-mail.
How to cite
Citing a resource is when you publicly acknowledge it.
In text, you put a label, like [3], or (Weeks2007),
that corresponds to an entry in your references.
The reference section then includes a lot more information, namely where other
people can find it: the author's full name, the title of his/her paper,
the journal that published it, the publisher, the year, the pages, etc.
Typically, you see this in academic papers, but other places such as
Wikipedia pages often include citations and a reference section.
How do you cite this software? I propose this bibtex entry:
@misc{calq,
title = {Calq -- A Free, Web Browser Based Programming Language},
author = {Michael Weeks},
organization = {Georgia State University},
address = {Atlanta, Georgia, USA},
year = {2007--2021},
note = {version 4.2},
url = {http://hallertau.cs.gsu.edu/calq_latest},
}
If you use bibtex, just copy that and paste it in your references.
If you don't use bibtex, you can copy and paste this instead:
Michael Weeks, "Calq (software)", version 4.2,
Georgia State University,
Atlanta, Georgia, USA,
2007--2019,
Available at http://hallertau.cs.gsu.edu/calq_latest.
It's the same information, just in a different format.
If you need to do this in APA, MLA, or some other format, simply change it as
needed.
Citing is important for people like me! It's the academic equivalent of
a "like" button on social media. The more citations, the bigger the impact,
and the more we are encouraged to continue to do it.
-Michael Weeks, mweeks [at] cs.gsu.edu, copyright © 2007-2019.
Michael Weeks, "What is Calq?",
Digital Wave Systems Lab,
Atlanta, Georgia, USA,
2007--2019,
Available at http://hallertau.cs.gsu.edu/whatiscalq.html.