Work at SourceForge, help us to make it a better place! We have an immediate need for a Support Technician in our San Francisco or Denver office.


Syntax enhancements - programming

  • Cousteau

    It would be nice that there were a way to dynamically create functions and processes as easily as storing variables. This way, Qalculate! could be used as a programmable calculator, and scripts could be written for it.
    Maybe programming is out of the scope of Qalculate!, but I'm posting these suggestions just in case any of them is useful.
    I hope phpBB doesn't mess the syntax.


    * Creating a function object (a sequence):
    {expr1; expr2; expr3}  ::  evaluates expr1, then expr2, and then expr3, and returns expr3
    if(x<10; {expr1; expr2; expr3}; {expr4; expr5; expr6})
    The content of the sequence isn't evaluated until the sequence is evaluated.
    Internally, sequences may be stored in a way that they represent raw code (for example, an array of text strings)

    * Storing a sequence as a variable:
    Sequence variable names end with "(…)"
    myfunc(a; b:=2) := {if(a<0; {a:=0}); a+b}   (doesn't evaluate before storing)
    myfunc := {if(a<0; {a:=0}); a+b}   (does evaluate before storing; use "myfunc()" to not evaluate)
    yourfunc(a; b) := a+b   (may cause problems since a+b is not a sequence)
    yourfunc(a; b) := {a+b}   (this is ok)
    theirfunction(fun(); var) := {if(var<0; {var:=0}); fun(x:=var)}  ::  takes a sequence as 1st argument

    * Calling a function:
    myfunc(3; 6)  ::  evaluates {if(a<0; {a:=0}); a+b} replacing 'a' with 3 and 'b' with 6
    myfunc(5)  ::  use default value 2 as second argument
    myfunc(a:=3; b:=6)  ::  labeled arguments
    {a+b}(a:=1; b:=2)  ::  evaluate an expression or sequence directly


    * "x=" operators:
    a += b  ::  a := a + b
    a -= b  ::  a := a - b
    a *= b  ::  a := a * b

    * Increment and decrement operators:
    a++  ::  a := a + 1
    a-  ::  a := a - 1

    * Allow modification
    a := 10 - a  :: right now this causes Qalculate! to crash; it shouldn't - it should evaluate "10-a" before storing it


    * If-elseif-else:
    Different behavior depending on the number of arguments:
    0 or 1 arguments: error
    Even arguments: condition-expression couples
    Odd arguments: condition-expression couples, and "else" expression
    if(x>10; expr1)  ::  if x>10 then expr1 else 0
    if(x>10; expr1; expr2)  ::  if x>10 then expr1 else expr2
    if(x>10; expr1; x>0; expr2)  ::  if x>10 then expr1 elseif x>0 then expr2 else 0
    if(x>10; expr1; x>0; expr2; expr3)  ::  if x>10 then expr1 elseif x>0 then expr2 else expr3
    Conditions and expressions are only evaluated if they are needed, so sequences can be used instead:
    if(x<0; x:=0)  ::  WRONG: evaluates x:=0 and passes it as an argument
    if(x<0; {x:=0})  ::  passes the sequence as an argument

    * While loop
    while({x<10}; {a:=a*x; x++})   ("x<10" between braces since it's evaluated several times)

    * Foreach loop
    foreach(i; ; {a := a*i})


    * Indexing (4 possible syntaxes):
    (1) Operator "->" or "→" (arrow):
    a -> 1  ::  element(a; 1)
    a ->   ::  element(a; 1; 2)   (=a->1->2)
    (1a) Operator "_":
    a_1  ::  element(a; 1)   (unless "a_1" is a variable name; use "'a'_1" or "a _ 1" in that case)
    (2) "":
    a  ::  element(a; 1)
    a  ::  element(a; 1; 2)
    (2a) "(…)"
    a(1)  ::  element(a; 1)

    * Interpolating:
    element(a; 1.3)  ::  0.7*element(a; 1) + 0.3*element(a; 2)
    Used with (2a) indexing, could be used to define functions from points.

    * Concatenation operation:
    1`2  :: 
    `4  :: 
    `  :: 
    ``  ::  [;;]
    [;] `   ::  [;;]
    [;] ``   ::  [;]
    [;] ` [;]  ::  [;;;]
    [;] `` [;]  ::  [;;;]
    a`=b  ::  a:=a`b   (append)
    a``=b  ::  a:=a``b   (extend)

    * Range creation:
    (1) Operator "..":
    1..5  ::     (may be implemented as an iterator rather than an actual vector)
    1..9..2  :: 
    (2) Operator ".." inside a vector, extrapolating values:
      ::     (extrapolates previous 2)
    (3) Iterate function:
    iter(start(); cond(); next()) := {v:=; k:=start(); while(cond(); {v`=k; next()}); v}
    iter({x:=1}, {x<=5}, {x++})  :: 
    (3a) Use (3) with (1) or (2):


    * File format
    A .qalc file stores comma-, semicolon- or newline-separated expressions, which are evaluated sequentially, returning the last result.
    File locale is english (if that matters), point as decimal separator, no non-ASCII characters
    Files are loaded with "open('file.qalc')"
    Files can also be run from command-line with "qalc -f file.qalc" or "qalculate -f file.qalc"

    * Comments
    Comments begin with a # and end on a newline.

    * Input/output
    It would be nice to have a way to prompt the user for data, and to print intermediate results, but this is not very important.