[HN Gopher] Maxima in the browser using Embedded Common Lisp on ...
       ___________________________________________________________________
        
       Maxima in the browser using Embedded Common Lisp on WASM
        
       Author : v9v
       Score  : 152 points
       Date   : 2025-01-28 15:37 UTC (7 hours ago)
        
 (HTM) web link (maxima-on-wasm.pages.dev)
 (TXT) w3m dump (maxima-on-wasm.pages.dev)
        
       | v9v wrote:
       | Raymond Toy posted this on the ECL mailing list:
       | https://mailman3.common-lisp.net/hyperkitty/list/ecl-devel@c...
        
       | magicalhippo wrote:
       | I've tried Maxima on a few occasions but the syntax somehow fails
       | to agree with me.
       | 
       | Been looking for a self-hosted alternative to Wolfram Alpha, and
       | just stumbled over Mathics, which has a Django front-end[1].
       | Rough but usable Mathematica alternative, at least for basic use.
       | 
       | [1]: https://github.com/Mathics3/mathics-django
        
         | pkaye wrote:
         | There is also Expreduce which is a CAS written in Go that
         | follows Mathematica syntax.
         | 
         | https://corywalker.github.io/expreduce-docs/
        
       | r85804306610 wrote:
       | because nobody knows maxima, some things to try. also
       | plot2d/plot3d work, so that's pretty neat. the whole thing is
       | powered by https://ecl.common-lisp.dev and the op announcement is
       | here https://mailman3.common-lisp.net/hyperkitty/list/ecl-
       | devel@c...                 :lisp (+ 2 2)       solve(f(x)^2-1,x);
       | integrate(x^2,x);       2^1024;       factor(30!);       a:1
       | b:2       a+b;       sqrt(a^2+b^2);       expr:
       | log((x+2)*(x-2))+log(x);       ratsimp(expr);
       | fullratsimp(expr);       trigsimp(2*cos(x)^2 + sin(x)^2);
       | solve(x^3=1,x);       diff(sin(x), x);
       | float([%e,%pi,%phi,%gamma]);       f(x):=x^2;       f(10);
       | taylor(sin(x),x,0,5);       plot2d(x^2-x+3,[x,-10,10]);
       | plot2d([x^2, x^3, x^4 -x +1] ,[x,-10,10]);       f(x,y):= sin(x)
       | + cos(y);       plot3d(f(x,y), [x,-5,5], [y,-5,5]);
        
         | michaelsbradley wrote:
         | Thank you! As someone with no prior Maxima experience, those
         | were some great starting points for me to learn and explore!
         | 
         | Note `plot3d(...);` doesn't seem to work: the output image is
         | missing/broken.
        
           | williamstein wrote:
           | plot3d did work for me (on Chrome). Impressive.
        
           | r85804306610 wrote:
           | you probably didn't define the function, f(x,y), which is the
           | line before plot3d. it's a slightly buggy behavior
        
         | seanhunter wrote:
         | One thing I would add for people who are new to this is you can
         | do
         | 
         | ??something; to get the internal help. So say I want to know
         | how to solve ODEs in maxima, do
         | 
         | ??ode; ...and you'll get help. It generally does a search and
         | presents a numbered list of options and you'll want to type a
         | number and a semicolon.
        
           | seanhunter wrote:
           | Some other useful things:
           | 
           | 1)solve to solve a system and "variable: expression" will
           | assign that expression to that variable. You can then
           | substitute the results into a later expression using a ",".
           | So you might do
           | solns:solve([x+3*y=5,5*x-2*y=4],[x,y]);
           | z:%e^(x,y),solns;
           | 
           | That will solve the system and then substitute those
           | solutions into the expression for z.
           | 
           | 2)pi, e, and the imaginary unit are called %pi, %e and %i
           | respectively.
           | 
           | 3)The symbolic solver is a lot less powerful than mathematica
           | but you can do                  load("to_poly_solve");
           | 
           | To get a polynomial solver that will at least get you all the
           | roots of polynomials and does better on most trigonometric
           | equations.                  load("drawdf");
           | 
           | Is useful for drawing vector fields, phase portraits and that
           | type of thing.
           | 
           | 4) you can use a single quote to delay evaluation of
           | something. Like say you want to write a differential equation
           | and you don't want it to actually try to evaluate the
           | derivative inline, you can write something like
           | osc:'diff(x,t,2) + r*'diff(x,t) + k*x = p*cos(omega\*t);
           | 
           | ...for a forced harmonic oscilator. Or whatever. This is
           | useful if you want to mess with the expression a bit before
           | you try to solve the expression (eg doing substitutions or
           | whatnot).*
        
       | hackernj wrote:
       | Nice. I've been using this Maxima interpreter:
       | http://www.dma.ufv.br/maxima/index.php
        
       | veryveryold wrote:
       | (to_lisp); (loop for i below 1000000 count t) takes 0.34 seconds
       | on my system with vanilla maxima (on gcl). In the browser it
       | takes about 7 seconds, so it must be a factor of 21 in computer
       | time. Using sbcl outside maxima it takes 0.002 seconds. So one
       | can get some idea about performance.
       | 
       | Perhaps it could be combined with J (array language), like in the
       | playground https://code.jsoftware.com/wiki/Playground that is
       | using webassembly
       | 
       | It seems to work very well locally without connection to the web.
        
         | jackdaniel wrote:
         | Web version of ecl when compiler is invoked at runtime, uses
         | one-pass bytecodes compiler, so things tend to lack
         | optimization unless compiled beforehand.
        
         | disentanglement wrote:
         | Apart from the restriction to bytecode interpretation already
         | mentioned, one reason for the slowness is that the sort of C
         | with garbage collection that ECL needs is quite difficult to do
         | in Webassembly. There is no way to scan previous stack frames
         | for pointers in wasm, so all pointers to heap objects (or
         | everything that looks like it might be one) have to be kept
         | around somewhere in the heap where the GC can find them. This
         | is really expensive and slows down the code a lot.
         | 
         | Of course, another approach would be to use the new wasm GC
         | interface. But that requires defining a new ABI for garbage
         | collected C, writing a new backend for LLVM, etc. So that would
         | also be a lot of work to implement. Right now, there just is no
         | efficient way to run programs that depend on bdwgc on wasm.
        
         | ted_dunning wrote:
         | It feels faster than the other web-hosted maxima instances out
         | there and if you take into account the cost of installing
         | common lisp and maxima (I only need to use this about twice a
         | year so I don't keep them live), it can be much faster than a
         | local instance.
        
       | unusual-name wrote:
       | We used maxima extensively in high school. I remember that I
       | forgot to bring my laptop when we had our first maxima lesson. My
       | teachers understandably scolded me for not bringing my laptop to
       | school, but to their surprise I found an online version of
       | maxima. [1] While it was good enough for this period, in contrast
       | to this implementation it was truly awful.
       | 
       | I just think it's kinda sad that a lot of people never heard of
       | maxima, as it is a pretty decent tool once you learn how to use
       | it.
       | 
       | [1] http://www.dma.ufv.br/maxima/index.php
        
         | forgotpwd16 wrote:
         | >scolded me for not bringing my laptop to school
         | 
         | That sounds stupid. What if someone doesn't have a laptop? Even
         | if do, cannot see why one's obligated to bring it along.
         | 
         | >in contrast to this implementation it was truly awful
         | 
         | It surely has the advantage of interactivity. The version you
         | linked seems to restart the session in every query. On the
         | other hand, seems more stable. Both `invert(matrix([2,3,1],
         | [a,0,0], [1,4,8]));` and
         | `draw3d(explicit(x^2+y^2,x,-1,1,y,-1,1));` that run fine in
         | UFV's DMa version fail to run in the submitted one.
        
           | aidenn0 wrote:
           | > That sounds stupid. What if someone doesn't have a laptop?
           | Even if do, cannot see why one's obligated to bring it along.
           | 
           | Where I live, the school issues laptops to students, so not
           | bringing the laptop is today's not bringing your textbook.
           | (As a point of fact, my daughter is in 10th grade and has had
           | exactly one physical textbook so far; the rest have been
           | digital)
        
       | dartos wrote:
       | How did you get Common Lisp running on wasm? I thought wasm
       | didn't support tail call recursive
        
         | jackdaniel wrote:
         | Common Lisp does not require TCO. This runs on emscripten port
         | of Embeddable Common Lisp - this platform support is relatively
         | new. I'm also working on WASI port and an optimizing compiler
         | at runtime (currently we use bytecodes compiler when running).
        
           | dartos wrote:
           | Oh wow.
           | 
           | I always thought TCO was part of the spec itself.
        
             | jackdaniel wrote:
             | Scheme requires TCO. It is a different Lisp (it also has
             | standard[s]).
        
               | ted_dunning wrote:
               | And revisions[n].
        
         | aidenn0 wrote:
         | The platform supporting tail-recursion is irrelevant to hosting
         | languages that support it; e.g. the JVM does (or at least did)
         | not support tail recursion, but kawa scheme (which does) runs
         | just fine on the JVM.
        
         | p_l wrote:
         | WASM supports tail calls and multiple return values now
        
       | openrisk wrote:
       | omg, macsyma is still alive and I can now manipulate _real_
       | tensors in the browser?
        
         | dreamcompiler wrote:
         | This is maxima, not macsyma.
         | 
         | https://en.m.wikipedia.org/wiki/Maxima_(software)
        
           | openrisk wrote:
           | How different is it?
           | 
           | > While this has resulted in some incompatibilities between
           | Macsyma and Maxima, programs written in the Macsyma algebraic
           | language can often be run, with only minor changes, in either
           | system.
           | 
           | Symbolic tensor manipulation is still supported
           | https://maxima-on-wasm.pages.dev/doc/html/Package-
           | itensor#Pa...
        
           | dokyun wrote:
           | It's the only Macsyma anyone's running these days, so maybe
           | if Symbolics hadn't killed it off there'd be another version
           | more deserving of the title.
        
       | fsckboy wrote:
       | tangential: can Macsyma/Maxima do symbolic boolean algebra,
       | reducing formulae to bog standard "OR of ANDs" form?
       | 
       | (I've tried looking at the doc, and it's clearly not a feature
       | they showcase, and as others have said, the way it works is not
       | intuitive to me. I really need this, but trying to do it in lisp
       | is becoming its own project and I want to get back to my project.
       | I found some really nice online reducers, but the UIs are not
       | conducive to pasting/putting in simultaneous equations, and using
       | those outputs as inputs again)
        
         | r85804306610 wrote:
         | maxima has logic package, written in 2009 by alexey beshenov.
         | it lives in share/logic which is also where the texi docs are.
         | it's included with the op version,                 load(logic);
         | logic_simp (a or (b or false or (a or b)));
         | characteristic_vector (a xor b);       zhegalkin_form ((a
         | implies b) or c);       e : ((a or b) xor c) and d$
         | logic_equiv (e, zhegalkin_form (e));       logic_diff (a or b
         | or c, a);       demorgan (boolean_form (a nor b nor c));
         | 
         | etc. there's more stuff in docs
        
       | maple3142 wrote:
       | Similar project: PARI/GP on WASM
       | https://pari.math.u-bordeaux.fr/gpexpwasm.html
        
       | azakai wrote:
       | It looks like the wasm file here is not fully optimized. Reading
       | the wasm and JS, I'd guess -O1 perhaps? Linking with -O3 would
       | make it smaller and possibly faster (10% smaller binary in a
       | quick local test, and it removes 90% of locals, which should
       | speed things up too)
       | 
       | But it is possible that it's already fast enough for the purposes
       | here, and this doesn't matter.
        
         | jackdaniel wrote:
         | It's worse, it is -O0 -- this is because of the GC and
         | binaryen/llvm interaction. For GC to work we need to spill
         | stack call pointers (and binaryen has such a flag!), but for
         | the optimization level 1 and above said pointers are sometimes
         | optimized away :3
         | 
         | I'm experimenting with WASI and the GC extension for WASM, but
         | that's months from today if we speak about complete port (given
         | my time capacity at the moment).
        
       | phkahler wrote:
       | Is there a place to get a wxmaxima installer for Windows other
       | than SourceForge? I no longer trust stuff from there.
        
         | v9v wrote:
         | There seems to be a github repo here with binaries (but you
         | need to get maxima separately, probably from sourceforge):
         | https://github.com/wxMaxima-developers/wxmaxima
        
       | gtpedrosa wrote:
       | This brings back memories. We used this in my mechanical
       | engineering mechanisms class. It was cool to have the
       | (simplified!) symbolic formulas describing the movements we were
       | designing.
        
       | soegaard wrote:
       | This is great?
       | 
       | Feature request: A way to easily copy old expressions into the
       | current input field (to fix mistakes).
        
       | phoe-krk wrote:
       | It's called "Embeddable Common Lisp", not "Embedded Common Lisp".
       | 
       | https://ecl.common-lisp.dev/
        
       ___________________________________________________________________
       (page generated 2025-01-28 23:00 UTC)