I am developing functional domain specific embedded language within C++ to translate formulas into working code as concisely and accurately as possible.
I posted a proto
I would give a good read to the Project Fortress blog, it has some inspiring posts on mathematical concise notations for a programming language.
You should have a look at syntax used for Haskell's list comprehension.
I am not sure how complicated those formulas will be, but if get to the point when your API looks more like that math domain than standard C++ (which is using operator overloading and template metaprogramming done quite easily), I would guess you should consider developing a Domain Specific Language (DSL). When you are trying to do it in a language (like in your case) it is called internal DSL and although it has some advantages, it has many disadvantages. You should know your requirements best, however I want to suggest you looking at tools for external DSLs, which are small external languages specialized for certain domain. Look at Jetbrains MPS and Eclipse Xtext, those are two open source tools, which can be used for rapid external DSL development.
I would consider expressing math formulas as they are done in LaTeX. After all, LaTeX is already well-defined and well-documented in this area.
If you're looking for simplicity you should take the implicitness of the loops even further. E.g., something like this
T( i < j , j < N ) = ( T(i,j) - T(j,i) )/e(i+j)
will work if you rewrite the assignment operator =
to behave normally for something like a(i) = b(i) + c(i)
but behave like a summation for a(i<5) = b(i) + c(i)
. Assume summation starts from 0 unless the lower limit is specified, e.g. a(3<i<5)
, check for symbolic upper/lower limits that appear as summation indices and make double sums as necessary. If you want the syntax to force explicitness you could define a separate sum operator s=
T( i < j , j < N ) s= ( T(i,j) - T(j,i) )/e(i+j)
I don't think you can get any cleaner than this and still have some general purpose usability. As for your short term goal, using the notion of specifying the summation index at the same time that the index first appears you could write.
E_MP2 s= EV( i < n1 , j < n2 , a < n3 , b < n4 ) *
2 ( EV(a,b,i,j) - EV(a,b,j,i) ) / ( e(i)+e(j)-e(a)-e(b) )
where you explicitly state that this is a sum (using s=
) making that operator then take the summation indices and limiting values from the first instance an index appears. Specifically you could also use a syntax like (assuming now a,b fixed and i,j as per your example)
E_MP2 s=(i<j,j<N) EV(i,j,a,b) *
2 ( EV(a,b,i,j) - EV(a,b,j,i) ) / ( e(i)+e(j)-e(a)-e(b) )
which is quite clear notationally.
You could then go on and take this concept even further by, e.g., defining an integration operator i=
that does the same thing. I.e. it looks for instances of variables that are marked down with limits and then proceeds to integrate the expression with respect to those variables
F i=(0<x<Pi) x^-1 * exp(-I x^2)
similarly to the summation you could specify the limit when x first occurs
F i= x[0,Pi]^-1 * exp(-I x^2)
where the square brackets serve to differentiate the notation from summation, so that you don't have to use i=
or s=
and can use both summation and integration at the same time:
F(i) = G(i,j<10) * x[0,inf]^-1 * H(i,j,x)
I would prefer a more solid separation between loops. For example, I'd prefer this alternative notation to your second example:
sum(range(j) < N)[sum(range(i) < j)[(T(i,j) - T(j,i))/e(i+j)]]
I also find the range syntax difficult. I think a range should be a single component. I'd prefer something like so:
j = range_iter(0,N)
That would open for range x(0,N); j = range.begin();
or alternatives I can't think up right now.
You could even:
j = range_iter(inc(0) => exc(N));
for j iterates over [0,N).
Anyway, interesting idea. Can your resulting functions be composed? Can you request domain information?