Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement loops like for, while, until as functions #2184

Closed
HK-SHAO opened this issue Apr 15, 2021 · 8 comments
Closed

Implement loops like for, while, until as functions #2184

HK-SHAO opened this issue Apr 15, 2021 · 8 comments

Comments

@HK-SHAO
Copy link
Contributor

HK-SHAO commented Apr 15, 2021

I recently used mathjs to build a programming language for mathematical operations.
The language is like this.

if([a<0,-1;
    a=0,0;
    a>0,1
])
a(n)=
    n<0?0: 
        if([
            n<2,1;
            true,a(n-1)+a(n-2)
        ]);
a(3)
a(n)=
    n<0?
        a(n+1)+a(n+2):
    n>1?
        a(n-1)+a(n-2):
    n
while(a>=0,
    a=a-1,
a)

until(a<0, 
    a=a-1, 
a)

for([a=1;b=0],a<=100,a=a+1,[
	b=b+a
],b)
isPrime(n) = [
    ans = true;
    for(a=2, a<n/2, a=a+1,[
        if([n%a == 0,[
            ans = false;
            a = Infinity
        ]])
    ],
    ans)
]

image

@josdejong
Copy link
Owner

Support for loops like for and while is on the wish list for a long time already, see #518. Even when that is supported, you'll not get the exact same syntax as in your examples above. You could consider creating a parser yourself, either by hand or by using a parser generator like jison or peg.js.

@HK-SHAO
Copy link
Contributor Author

HK-SHAO commented Apr 17, 2021

Support for loops like for and while is on the wish list for a long time already, see #518. Even when that is supported, you'll not get the exact same syntax as in your examples above. You could consider creating a parser yourself, either by hand or by using a parser generator like jison or peg.js.

That's cool. Thank you!

@HK-SHAO
Copy link
Contributor Author

HK-SHAO commented Apr 17, 2021

I think we can implement multi branch structure and loop structure based on function, just like the examples I wrote above.
This is the code for my implementation:

{
  if: typed('if', {
      'Matrix': function (mat: Matrix) {
          let shape = mat.size();
          if (shape.length < 2 || shape[1] < 2) {
              throw new Error('The shape of the matrix is incorrect');
          }
          let arr = mat.toArray();
          return import_scope.if(arr);
      },
      'Array': function (arr: Array<[any, any]>) {
          for (let p of arr) {
              if ((p[0] && p[0].evaluate && p[0].evaluate(that.scope)) ||
                  (p[0] && !p[0].evaluate)) {
                  return (p[1] && p[1].evaluate && p[1].evaluate(that.scope)) || p[1];
              }
          }
      }
  }),
  while: function (nodes: MathNode[], _math: Partial<math.MathJsStatic>, _scope: object) {
      const [c, p, r] = nodes;
      const _c = c && c.compile();
      const _p = p && p.compile();
  
      while (_c && _c.evaluate(that.scope)) {
          _p && _p.evaluate(that.scope);
      }
      return r && r.evaluate(that.scope);
  },
  until: function (nodes: MathNode[], _math: Partial<math.MathJsStatic>, _scope: object) {
      const [c, p, r] = nodes;
      const _c = c && c.compile();
      const _p = p && p.compile();
  
      _p && _p.evaluate(that.scope);
      while (!(_c && _c.evaluate(that.scope))) {
          _p && _p.evaluate(that.scope);
      }
      return r && r.evaluate(that.scope);
  },
  for: function (nodes: MathNode[], _math: Partial<math.MathJsStatic>, _scope: object) {
      const [s, c, e, p, r] = nodes;
      const _c = c && c.compile();
      const _p = p && p.compile();
      const _e = e && e.compile();
  
      s && s.evaluate(that.scope);
      while (_c && _c.evaluate(that.scope)) {
          _p && _p.evaluate(that.scope);
          _e && _e.evaluate(that.scope);
      }
      return r && r.evaluate(that.scope);
  }
}
import_scope.while['rawArgs'] = true;
import_scope.until['rawArgs'] = true;
import_scope.for['rawArgs'] = true;

@HK-SHAO
Copy link
Contributor Author

HK-SHAO commented Apr 17, 2021

The advantage of this implementation is that there is no need to modify the parser significantly. Maybe it's cool to put the code in the matrix and then be executed!

@josdejong
Copy link
Owner

Ahh, now I see what you're doing: implementing loops as functions. That's a smart idea!

I have to give this some more thought, for short term this is a great solution, but I'm not sure if it will bite us in the future: if we go this direction now, I think it will not be easy to switch to "real" for/while/until operators later on.

@josdejong josdejong changed the title Need some help and advice for a language based on mathjs Implement loops like for, while, until as functions Apr 18, 2021
@josdejong
Copy link
Owner

I've been thinking about this a bit more. I do like your simple, pragmatic solution, but I think we should not go for this in the long run.

Implementing those loops in the expression parser for real (#518) should not be that complicated, I think it is better to go for the long term solution right away to keep things straightforward for the user. Users that are in bad need for this can of course use your solution as a workaround 😄 .

@HK-SHAO
Copy link
Contributor Author

HK-SHAO commented Apr 26, 2021

long term solution

Yes, you're right, we do need a long-term solution 😆

@josdejong
Copy link
Owner

Ok 👍 , will close this issue now, let's continue any discussion in #518.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants