Menu

REDUCE <-> JavaScript

Developers
2024-03-02
2024-03-29
  • Hermann Rolfes

    Hermann Rolfes - 2024-03-02

    Hello all, I'm very excited to learn REDUCE. I just learned about it a few days ago and I'm trying my first steps.

    I'm using JavaScript for many years and so I'm in search of equivalent code in REDUCE:

        JS  IN: [1,-1,2,-3,3].filter(w => w > 0)
        JS OUT: [1, 2, 3]
    REDUCE  IN: select(~w>0 , {1,-1,2,-3,3});
    REDUCE OUT: {1, 2, 3}
    
        JS: for (let i=1; i<=5; i++) console.log(i, "**", i, "=", i ** 2);
    REDUCE: for i:=1:5 do write i, "**", i, "=", i^2;
    
        JS: [1, 2, 3].length
    REDUCE 1: arglength({1, 2, 3});
    REDUCE 2: length({1, 2, 3});
    QUESTION: What's better?
    
        JS: "Hello" + "World"
    REDUCE: ?
    
        JS: [1,-1,2,-3,3].map(w => w > 0)
    REDUCE: ?
    

    CONS:

        JS: [...['a'], ...['b', 'c']]
    REDUCE: a . {b, c};
    
        JS: [10, 20, 30][0];
    REDUCE: first {10, 20, 30};
    
        JS: [10, 20, 30][1];
    REDUCE: second {10, 20, 30};
    
        JS: [10, 20, 30][2];
    REDUCE: third {10, 20, 30};
    
        JS: [10, 20, 30].slice(1);
    REDUCE: rest {10, 20, 30};
    

    If you have more examples, please post them, I would love to learn from them!

     

    Last edit: Hermann Rolfes 2024-03-03
  • arpi

    arpi - 2024-03-03

    Joining strings:

    procedure joinstring(a, b); begin; write a, b; end;
    joinstring("Hello", " world!");
    
     
    👍
    1
    • Hermann Rolfes

      Hermann Rolfes - 2024-03-03

      Hello arpi, thank you for your answer! I think it doesn't actually concatenate anything though. You can test that by:

      both := joinstring("Hello", "World");
      write both; % prints nil
      

      Any ideas to have a real string concatenation?

       
      • arpi

        arpi - 2024-03-03

        You're absolutely right, sorry. I have a second try here:

        symbolic procedure joinstr(a, b); begin; return concat(a, b); end;
        symbolic operator joinstr;
        s:=joinstr("Hello", " world!");
        s;
        

        You could also just use concat in symbolic mode:

        a:="Hello";
        b:=" world!";
        share a, b;
        symbolic;
        c:=concat(a, b);
        share c;
        algebraic;
        c;
        
         
        ❤️
        1

        Last edit: arpi 2024-03-03
        • Hermann Rolfes

          Hermann Rolfes - 2024-03-03

          Thank you so much for the symbolic operator/procedure trick, that's exactly what I searched for - and I also didn't see share in any PDF yet, it works great for simple data types.

          I also try to find a solution for JavaScript's "Hello World".split(''); and tried this:

          symbolic procedure explodeAndReverse(a);
          begin;
          return reverse(explode(a));
          end;
          symbolic operator explodeAndReverse;
          s:=explodeAndReverse("Hello");
          s;
          

          But then "sharing" stops working - do you happen to know how to share a symbolic list with algebraic mode?

           
          • arpi

            arpi - 2024-03-03

            On the recuce homepage, www.reduce-algebra.com, there is a symbolic mode primer, and share is in the section "Communication between algebraic and symbolic modes".

            I think the problem with your solution to reverse a string here is that with explode you convert it to a list of characters, and try to return that to algebraic mode. If you compress it back, it works:

            symbolic procedure rev(a); begin;
              return compress(reverse(explode(a)));
            end;
            symbolic operator rev;
            rev("hello");
            
             

            Last edit: arpi 2024-03-03
            • Hermann Rolfes

              Hermann Rolfes - 2024-03-03

              Thank you! I really want to share the list/array, so I worked something out:

              % Some kind of string representation magic from symbolic mode.
              operator !";
              a := "Hello";
              share a;
              symbolic;
              c := explode(a);
              share c;
              algebraic;
              realRet := sub(!" = list, c);
              share realRet;
              realRet;
              

              I only have one last issue: to remove the last list element, which is just there because of the substitution for: (!" !H e l l o ! !W o r l d !")

               
          • Arthur Norman

            Arthur Norman - 2024-03-29

            I have just returned from a trip that means I could not join in this
            diuscussion. Maybe everything is now sorted so I do not need to worry. But
            still here are some thoughts/questions...

            Reduce as a whole has these two modes - algebraic and symbolic. I think
            that he concept from early days was that "ordinary users" would use (just)
            algebraic mode and (just) use it to express algebraic evaluation,
            simplification and transformation. So the only data type really provided
            there is a "formula" where numbers are merely a special case. Well lists
            and arrays got implemented but in various respects they are not quite
            "first class" so eg passing a matrix as a parameter or trying to embed one
            within some other data may or may not behave nicely. Strings went in
            rather with the expectation that they would probably only be used by
            appearing directly in statements like
            write "the result is", answer;
            so at that time there was no expectation that people would try to do
            transformations on strings - because Reduce was for doing algebra not
            string processing.

            But then symbolic mode was there to support implementers and developers
            and the facilities it supports encompass all data types and all operations
            that you might have expected to find in a Lisp system in say the mid
            1970s. So there strings do exist and there are primitives for working with
            them, but the design expected that anything that was not primitive would
            be coded in Rlisp and included within the Reduce source - and so far few
            developers have felt motivated to implement pattern matching and
            substing operations etc etc. Maybe the biggest code segment that is there
            is the printf stuff in rtools/rprintf.red. That is not exectly heavily
            used through the rest of the Reduce sources - but bldmsg() is used to help
            (mostly) when interfacing with the outside world such as file-name
            contruction. And occasionally when building diagnostic messages.

            There are schemes that provide ways to move between algebraic mode where
            for instance "x" tends to stand for an indeterminate and "" expands a
            formula that is the product of its operands and symbolic mode where "x" is
            a programmer's variable while "'x" (with a quote mark) is a Lisp atomic
            symbol whose name is x and that may or may not have extra properties. In
            Symbolic moded "
            " is jusst for multiplying integers or machine-style
            floating point numbers (typically IEEE 64-bits). These schemes are OK for
            experienced users not are not smooth and comfortable for everybody.

            If a design emerged it would be liable to be straightforwared to extend
            Reduce with string processing support that could be used directly in
            algebraic mode - and that is sort of what I believe several people have
            felt that wanted. There would be several steps:
            (1) Check and think about string values stored in variables, passed
            as arguments, delivered as results. Eg at present "z"+1; leads to the
            sensible complaint "* String z invalid as identifier" but I for one am
            not certain that strings are detected and handled EVERYWHERE.
            (2) Work out what string functions would actually be useful. In some sense
            drafting the associated sections of the manual to give a specification
            would maybe be good. A key issue here is to avoid a design just aimed at
            one user but to end up with something that will satisfy many.
            (3) Implement (2), and given that symbolic mode is liable to provide
            adequate support (sometimes needing clumsy or inefficient code!) this
            would be the easy bit.
            (4) Provide a test suite to verify/validate behaviour.

            I think I view (2) and (4) as the ones most in need of input from somebody
            who can imagine wanting to use strings (etc??) in general algebraic mode
            code. So if some kind person were to start fleshing those out maybe I or
            maybe one of the other old-hands could join in starting (1) and (3) and
            after a few parts of (3) had been provided by one of us then the people
            keen on this could discern from it how to finish the job?????

            Are there any volunteers?

            Arthur
            

            On Sun, 3 Mar 2024, Hermann Rolfes wrote:

            Thank you so much for the symbolic operator/procedure trick, that's exactly what I searched for - and I also didn't see share in any PDF yet, it works great for simple data types.

            I also try to find a solution for JavaScript's "Hello World".split(''); and tried this:

            symbolic procedure explodeAndReverse(a); begin; return reverse(explode(a)); end; symbolic operator explodeAndReverse; s:=explodeAndReverse("Hello"); s;

             
  • Eberhard Schruefer

    Hello,
    For some reason string manipulation comes up here once in a while. It is not really something that is used in Reduce. What are you trying to accomplish? Anyway, to answer your question the following should do

    symbolic procedure explode_string u; 'list . cdr reverse cdr reverse explode u;
    symbolic operator explode_string;
    
    15: explode_string "Hello world";
    
    {H,
    
     e,
    
     l,
    
     l,
    
     o,
    
      ,
    
     w,
    
     o,
    
     r,
    
     l,
    
     d}
    
    16: 
    

    Eberhard

     
    ❤️
    1
    • Hermann Rolfes

      Hermann Rolfes - 2024-03-03

      That works like a charm, thank you Eberhard! I'm reading Application of Geometric Algebra to Electromagnetic Scattering which is the only reason I learned about REDUCE. The nature of multivector equations etc. is that it is rather slow in interpreted code, therefore one should generate code e.g. for C or JavaScript. It's strange to not have a good set of string functions, since you require them for meta programming. Mathematica e.g. comes with all kinds of string functions, which allow for quick prototyping and code generation for other languages - it simply streamlines the workflow.

      Thank you again for the short, precise and ingenious answer - I will build on this approach to bring more string manipulation functions into REDUCE algebraic mode. A big reason for me is also to simply learn REDUCE algebraic mode and strings are nice to work with, e.g. for Huffman trees.

       
    • John ffitch

      John ffitch - 2024-03-03

      I have used reduce for 53 years but have never tried to concatenate two
      strings. Normally I use reduce for algebraic calculations.

      =-John ff

       
      👍
      1
      • Hermann Rolfes

        Hermann Rolfes - 2024-03-05

        Indeed you are right, I'm just learning! I realized most code is written in symbolic mode aswell by fitting the gnuplot procedures. So seeing string code in algebraic mode is probably an anti pattern?

         
  • Hermann Rolfes

    Hermann Rolfes - 2024-03-06

    Is it possible to print the source code of a function itself?

    In JavaScript you can do:

    function test(a, b) {
        return a + b;
    }
    console.log(test.toString()); // Prints source code of function
    

    Is there something like globalThis or window? I need it to implement auto-complete of possible commands in WebREDUCE, e.g. Object.keys(window);

     
    • Arthur Norman

      Arthur Norman - 2024-03-06

      First let me note that I’m on a trip so internet is uncertain for me right now.

      If foo is an inter[preted function then gets ‘foo returns the lisp code for it and print may render that in lisp. For csl reduce the version but as bootstrapreduce puts the lisp version of any code to be accessed via get(‘foo, “saved). In each case id foo was introduced in algebraic mode then it may not look like what you ``”expect”..

      There was once a scheme (cedit?) for people to edit the most recent input they had types. I` bet it has not been used for decades.

      So do you mean ALL “functions`’ and why do you need the full source code - or do you need some info about user defined procedures? If you can wait until after Easter I will be able to help a lot better. Eg some “functions” like gcd and solve and so on do not have a single function definition to be returned. Consider what say “int” would need to return to tell you how integration is done. But by hacking the build system almost any data from the source code could be saved for your use. And for the bulk of Reuece doing that one off statically at system build time to build the bulk of your database might then let you need something more dynamic to reflect info about user-entered stuff?????

      Arthur

      On 6 Mar 2024, at 14:33, Hermann Rolfes kungfooman@users.sourceforge.net wrote:

      Is it possible to print the source code of a function itself?

      In JavaScript you can do:

      function test(a, b) {
      return a + b;
      }
      console.log(test.toString()); // Prints source code of function

      Is there something like globalThis or window? I need it to implement auto-complete of possible commands in WebREDUCE, e.g. Object.keys(window);


      REDUCE <-> JavaScripthttps://sourceforge.net/p/reduce-algebra/discussion/899365/thread/7fd6486c05/?limit=25#4cba


      Sent from sourceforge.net because you indicated interest in https://sourceforge.net/p/reduce-algebra/discussion/899365/

      To unsubscribe from further messages, please visit https://sourceforge.net/auth/subscriptions/

       
      👍
      1
  • Hermann Rolfes

    Hermann Rolfes - 2024-03-08

    Hey Arthur, thank you for your reply!

    In JavaScript I'm used to simply write a function name and double-click on it in F12/DevTools in order to move to its source for inspection. I want to implement something similiar for WebREDUCE - If you know how, I will take any information present, be it the entire original source, function bytecodes or function pointers. Every piece can help to debug a system.

    Is this how you mean it? I tried different variations, but couldn't get it to work so far:

    procedure foo(a, b); a + b;
    get('foo, ''saved);
    

    (sorry for replying late, I tried yesterday but SF had some problems it seems)

     
    • Arthur Norman

      Arthur Norman - 2024-03-09

      Hi from Kathmandu, with time after this evening less certain re email.

      I reduce consider the function name "cos". At the level of lisp/rlisp it is a fn to compute the cosine of a double precision float. It May be implemented by rlisp code or with psl or csl at least it is a function implemented within the lisp kernel. In that case after some wrapper code to disentangle the lisp representation of a float it uses code from the crlibm correctly rounded maths library and the c source for that is in the source tree but well buried by runtime.
      In algebraic mode chose is for cosine. Some pattern matching probably detects if the arg is a neat multiple od the symbol pi (nb not of any floating point value). Then if the arg is floating and on rounded is set the established fp precision is used to evaluate. Otherwise it may be transformed by Let rules or may remain as such but with its argument "simplified". There is no one place in the code that implements all that and there are fragments in c, c++ for csl, lisp for psl and who knows what for other lisps, plus a combination of generic simplification code guided by tables.
      Similar issues arise for almost all other builtins.

      If you go on defn then rlisp shows the internal ie lispish form of things youenter and does not instate defs. Eg for lops in input may be expanded to prog plus cond plus go. Look at that for examples in both symbolic and algebraic mode.

      For csl the full build first makes bootstrap reduce.img that contains all parsed source, then make-c-code compiles the most heavily used stuff to c++. To do that it needs to go load! - source since those defs are not clogging memory unless asked for, then the! *savedef properly of things gives the source. But only for code written in rlisp.
      I have or has a csl byte code decoder but can certainly not comment on that until I am home.
      So reflection to access source code is sort of OK if you are working in symbolic mode ans read lisp happily. If you build redyce without compiling also the getd function returns the definition but also in lispish form. There is print code to map back from lisp to rlisp but it will not deliver nice stuff.

      Lokk on the property lisp of things and in csl eg plist 'cos or plist' addsq; may be useful. At least in bootstrapredue that gives the file name and line number for source and that may be more what you want?
      There are typos in this email. Reduce as generic runs atop psl, csl, common lisp, emactslisp, jlisp, vsl and some system level details will vary, with webreduce being csl built via emscrpten plus some useful extra interfacing.....

      I hope this overview gives more of a picture... Arthur


      From: discussion@reduce-algebra.p.re.sourceforge.net discussion@reduce-algebra.p.re.sourceforge.net on behalf of Hermann Rolfes kungfooman@users.sourceforge.net
      Sent: Friday, March 8, 2024 8:34:03 PM
      To: [reduce-algebra:discussion] 899365@discussion.reduce-algebra.p.re.sourceforge.net
      Subject: [reduce-algebra:discussion] REDUCE <-> JavaScript

      Hey Arthur, thank you for your reply!

      In JavaScript I'm used to simply write a function name and double-click on it in F12/DevTools in order to move to its source for inspection. I want to implement something similiar for WebREDUCE - If you know how, I will take any information present, be it the entire original source, function bytecodes or function pointers. Every piece can help to debug a system.

      Is this how you mean it? I tried different variations, but couldn't get it to work so far:

      procedure foo(a, b); a + b;
      get('foo, ''saved);

      (sorry for replying late, I tried yesterday but SF had some problems it seems)


      REDUCE <-> JavaScripthttps://sourceforge.net/p/reduce-algebra/discussion/899365/thread/7fd6486c05/?limit=25#7ba3


      Sent from sourceforge.net because you indicated interest in https://sourceforge.net/p/reduce-algebra/discussion/899365/

      To unsubscribe from further messages, please visit https://sourceforge.net/auth/subscriptions/

       
      👍
      1
    • Francis Wright

      Francis Wright - 2024-03-09

      I think Arthur meant that you should use

      get('foo, 'saved);

      It's very unusual to have a doubled single quote in Lisp. But the above doesn't seem to produce any output in Web REDUCE either.

      The REDUCE parser generates Lisp code, which by default is saved in the system and interpreted when you call a function. This is probably the closest that REDUCE gets to Javascript. You can see the saved Lisp for your procedure foo by doing

      getd 'foo;

      but it doesn't look much like the REDUCE input. However, most of REDUCE consists of compiled Lisp, which getd just displays as a placeholder!

      If you want access to the source code for a (probably compiled) procedure that is part of REDUCE, you can find it like this. Consider the differentiation operator, df. If you do

      plist 'df;

      you will see the property list of this identifier, which includes

      (simpfn . simpdf)

      That means the df operator is implemented by a function called simpdf. If you now do

      plist 'simpdf;

      the resulting property list shows the file (in the packages directory) and the line on which this procedure is defined. (The arguments to df get passed to simpdf in a list, which is why simpdf takes only one argument, so the argument count is often not very useful.)

      I hope that's some help.

      Francis


      From: discussion@reduce-algebra.p.re.sourceforge.net discussion@reduce-algebra.p.re.sourceforge.net on behalf of Hermann Rolfes kungfooman@users.sourceforge.net
      Sent: 08 March 2024 3:04 PM
      To: [reduce-algebra:discussion] 899365@discussion.reduce-algebra.p.re.sourceforge.net
      Subject: [reduce-algebra:discussion] REDUCE <-> JavaScript

      Hey Arthur, thank you for your reply!

      In JavaScript I'm used to simply write a function name and double-click on it in F12/DevTools in order to move to its source for inspection. I want to implement something similiar for WebREDUCE - If you know how, I will take any information present, be it the entire original source, function bytecodes or function pointers. Every piece can help to debug a system.

      Is this how you mean it? I tried different variations, but couldn't get it to work so far:

      procedure foo(a, b); a + b;
      get('foo, ''saved);

      (sorry for replying late, I tried yesterday but SF had some problems it seems)


      REDUCE <-> JavaScripthttps://sourceforge.net/p/reduce-algebra/discussion/899365/thread/7fd6486c05/?limit=25#7ba3


      Sent from sourceforge.net because you indicated interest in https://sourceforge.net/p/reduce-algebra/discussion/899365/

      To unsubscribe from further messages, please visit https://sourceforge.net/auth/subscriptions/

       
      👍
      1
      • Arthur Norman

        Arthur Norman - 2024-03-09

        Check the property list with list or read cslbase/make-c-code to see the property name which is nor just saved. And saved definitions are put within fasl files and need explicity loading to get them back and they are only generally kept in bootstrap reduce. I will be able to help a lot better after Easter unless this is very urgent. Also psl does not do savedef. Arthur


        From: discussion@reduce-algebra.p.re.sourceforge.net discussion@reduce-algebra.p.re.sourceforge.net on behalf of Francis Wright fjwright@users.sourceforge.net
        Sent: Saturday, March 9, 2024 6:12:27 PM
        To: [reduce-algebra:discussion] 899365@discussion.reduce-algebra.p.re.sourceforge.net
        Subject: [reduce-algebra:discussion] Re: REDUCE <-> JavaScript

        I think Arthur meant that you should use

        get('foo, 'saved);

        It's very unusual to have a doubled single quote in Lisp. But the above doesn't seem to produce any output in Web REDUCE either.

        The REDUCE parser generates Lisp code, which by default is saved in the system and interpreted when you call a function. This is probably the closest that REDUCE gets to Javascript. You can see the saved Lisp for your procedure foo by doing

        getd 'foo;

        but it doesn't look much like the REDUCE input. However, most of REDUCE consists of compiled Lisp, which getd just displays as a placeholder!

        If you want access to the source code for a (probably compiled) procedure that is part of REDUCE, you can find it like this. Consider the differentiation operator, df. If you do

        plist 'df;

        you will see the property list of this identifier, which includes

        (simpfn . simpdf)

        That means the df operator is implemented by a function called simpdf. If you now do

        plist 'simpdf;

        the resulting property list shows the file (in the packages directory) and the line on which this procedure is defined. (The arguments to df get passed to simpdf in a list, which is why simpdf takes only one argument, so the argument count is often not very useful.)

        I hope that's some help.

        Francis


        From: discussion@reduce-algebra.p.re.sourceforge.net discussion@reduce-algebra.p.re.sourceforge.netdiscussion@reduce-algebra.p.re.sourceforge.net on behalf of Hermann Rolfes kungfooman@users.sourceforge.netkungfooman@users.sourceforge.net
        Sent: 08 March 2024 3:04 PM
        To: [reduce-algebra:discussion] 899365@discussion.reduce-algebra.p.re.sourceforge.net899365@discussion.reduce-algebra.p.re.sourceforge.net
        Subject: [reduce-algebra:discussion] REDUCE <-> JavaScript

        Hey Arthur, thank you for your reply!

        In JavaScript I'm used to simply write a function name and double-click on it in F12/DevTools in order to move to its source for inspection. I want to implement something similiar for WebREDUCE - If you know how, I will take any information present, be it the entire original source, function bytecodes or function pointers. Every piece can help to debug a system.

        Is this how you mean it? I tried different variations, but couldn't get it to work so far:

        procedure foo(a, b); a + b;
        get('foo, ''saved);

        (sorry for replying late, I tried yesterday but SF had some problems it seems)


        REDUCE <-> JavaScripthttps://sourceforge.net/p/reduce-algebra/discussion/899365/thread/7fd6486c05/?limit=25#7ba3


        Sent from sourceforge.net because you indicated interest in https://sourceforge.net/p/reduce-algebra/discussion/899365/

        To unsubscribe from further messages, please visit https://sourceforge.net/auth/subscriptions/


        REDUCE <-> JavaScripthttps://sourceforge.net/p/reduce-algebra/discussion/899365/thread/7fd6486c05/?limit=25#7ba3/c741


        Sent from sourceforge.net because you indicated interest in https://sourceforge.net/p/reduce-algebra/discussion/899365/

        To unsubscribe from further messages, please visit https://sourceforge.net/auth/subscriptions/

         
  • Hermann Rolfes

    Hermann Rolfes - 2024-03-09

    Thank you all a lot for your input! I figured there is even a package called gentran which can generate code (e.g. C code) - I will play around with all and see what I can come up with. I like LISP as being sort of an abstract syntax tree, so it shouldn't be too hard from now on - thank you all again!

    And have a nice time in Kathmandu, Arthur - there is no time pressure here, just learning and testing around

     

Log in to post a comment.