Skip to content

This issue was moved to a discussion.

You can continue the conversation there. Go to discussion →

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

Multi-line functions and control flow like for/do/while and if/else #518

Closed
stewpend0us opened this issue Dec 15, 2015 · 23 comments
Closed
Labels
category:expressions Issues about the expression parser, variable scoping etc. feature help wanted

Comments

@stewpend0us
Copy link

Hello, I was wondering if there's a plan to support multi-line functions in the future? Also control flows like if/elseif/else and for/while loops? I read in the docs that this is targeting math people not programmers but I feel like these features are critical to solving real world problems.
Thanks!

@josdejong
Copy link
Owner

Definitely! Both loops and function blocks would be very powerful. Thanks for your suggestion.

@stewpend0us
Copy link
Author

I would be willing to help if you point me in the right direction.

@josdejong
Copy link
Owner

Thanks for your offer. Basically, the expression parser must be extended. We probably need a few new types of Nodes. You can find the relevant code here to have a look:

https://github.com/josdejong/mathjs/blob/master/lib/expression/parse.js
https://github.com/josdejong/mathjs/tree/master/lib/expression/node

@stewpend0us
Copy link
Author

So is there an outline or spec for what the expression parser language should look like in the end? Mulit-line functions could follow matlab syntax:

function [output1, output2] = functonName(input1, input2)
...
output1 = 4;
output2 = 5;
end

or something sorta like javascript:

f(input1, input2) = {
...
return 6;
}

@josdejong
Copy link
Owner

Indeed we have to discuss the syntax for functions and loops. We have to keep in mind that the expression parser is mostly useful for a mathematical audience, not a programmer audience, so it makes sense to make it similar syntax from matlab which has a sort of a BASIC style for loops and functions. I don't particularly like the syntax of Matlab without explicit return, though I like being able to return multiple outputs (maybe you could just do the same with destructuring though).

It would also be nice if the multiline function syntax would be similar to the oneline function syntax.

Just to drop some ideas into the discussion:

# idea 1
for i = 1:6
  #...
next
# idea 2
while i < 6
  #...
next
# idea 3
do
  #...
while i < 6
# idea 4
f(x, y) = x^y   # one line 
# idea 5
function g(x, y)
  return x^y
end 
# idea 6: matlab style
function [a, b] = g(x,y)
  a = x + y
  b = x ^ y
end 

@kbiedrzycki
Copy link

hello @josdejong, are there any improvements in that way?

@josdejong
Copy link
Owner

@kbiedrzycki no this feature hasn't been picked up yet.

@kbiedrzycki
Copy link

Okay @josdejong. Just wondering if that could be done using some regular expressions, I need quite qick solution for that, cause I am creating project with worksheets where user could set few lines of code as functions and then parse them, looking for some solution and wondering how to solve that..

@josdejong
Copy link
Owner

That may be possible. When you only accept a function definition enclosing a block of expressions, and not itself as part of a block of expressions, a regexp could work I think.

@josdejong
Copy link
Owner

As discussed in #1906: support for if ... else would be very nice too.

I'll update the title of this topic a bit to make it easier to find.

@josdejong josdejong changed the title multi-line functions/control flow Extend expression parser with support for multi-line functions, for/do/while loops, if/else Jul 4, 2020
@josdejong josdejong changed the title Extend expression parser with support for multi-line functions, for/do/while loops, if/else Extend expression parser with support for multi-line functions and control flow like for/do/while and if/else Jul 4, 2020
@josdejong josdejong changed the title Extend expression parser with support for multi-line functions and control flow like for/do/while and if/else Multi-line functions and control flow like for/do/while and if/else Jul 4, 2020
@josdejong
Copy link
Owner

Help would be very welcome here :)

@AlahmadiQ8
Copy link

I'll try to take a stab on this.
since this is my first time contributing on this repo, I'll search in the PRs for similar type of contributions to can learn from.
@josdejong If you know of any particular PR you recommend learning how to support a new type of nodes, please let me know.

@josdejong
Copy link
Owner

Thanks Mohammad!

I think the easiest is to go through parse.js and some of the Node classes like OperatorNode or FunctionNode and make yourself a bit familiar with how everything is working:

https://github.com/josdejong/mathjs/blob/develop/src/expression/parse.js
https://github.com/josdejong/mathjs/tree/develop/src/expression/node

After that it may be good to first work out a plan and discuss it here. On thing for example that may become relevant when implementing these control flow features is keeping some kind of stack trace or pointer or something, to be able to throw meaningful errors. When you have a larger script with a lot of for loops and if statements, just a message "Error in if statement" is not enough, you want to know which if statement.

@AlahmadiQ8
Copy link

@josdejong thank you so much and i apologize for the delayed reply.

I forked the project so i can play around the codebase and get familiar.

I will use this issue for design discussions, feedback, and implementation details.

@josdejong
Copy link
Owner

👍 enjoy!

@AlahmadiQ8
Copy link

@josdejong I start on a branch on a forked repo. Here is my initial stab on it
AlahmadiQ8@42ac38a

There is still a lot of work left but wanted to get early feedback on the implementation of IfElseNode before digging deeper.

@josdejong
Copy link
Owner

Nice! The code looks neat at first sight.

I think we should think through the exact syntax that we want to have for if/else, for, do, while (do we want do and while?), a multi line function. Do you have any ideas? We could stay close to JavaScript, or look at Matlab or Python for inspiration.

@AlahmadiQ8
Copy link

AlahmadiQ8 commented Jul 23, 2020

I don't have a particular opinion on the exact syntax. I just used if end from matlab as a start to get the ball rolling.

Personally, I'm leaning toward staying close to javascript syntax: If (true) { x = 4 }. The only reason is that it would simplify implementing parsing for each scope. Also we could support single line expressions.

however, with matlab, if end the user is required to use new lines for every if condition even if it's small.

what do you think?

@stewpend0us
Copy link
Author

stewpend0us commented Jul 23, 2020 via email

@josdejong
Copy link
Owner

It makes sense to choose a syntax similar to Matlab: the expression parser is aimed at mathematicians, not hard core C programmers :).

please no required semicolons at the end of a line. Semicolons are already supported though to support multiple expressions on a single line.

I do like the Matlab syntax of for loops and if/else a lot (see source):

for c = 1:ncols
    for r = 1:nrows
        
        if r == c
            A(r,c) = 2;
        elseif abs(r-c) == 1
            A(r,c) = -1;
        else
            A(r,c) = 0;
        end
        
    end
end

As for mutiline functions, I think we need to divert there a bit. The syntax should be somehow consistent with the way we write a single line function, which is:

f(x, y) = x^y

A multiline function could look like:

function f(x, y) 
  return x^y
end

or:

f = function (x, y) 
  return x^y
end

Matlab doesn't work with return and allows you to return multiple variables (see docs). That's a very nice feature though it also required getting used to it. Do you have any preference or ideas in this regard?

@AlahmadiQ8
Copy link

thank you for the feedback.

you are right that Matlab syntax is more friendly to non programmers.

one question i have if how to handle the following case

2;
3
if true
    5;
    6
end

From my understanding of how semi columns work in in the parser, this will return a result set of [3, 6] only. is that correct in this case as well?

@AlahmadiQ8
Copy link

as for functions, my only confusion with the return is that we already have a way to return results on whether or not to omit semi columns on each line.

having another way to return results can potentially be confusing. that said, i do like that return is more explicit and clear when it comes to functions.

@josdejong
Copy link
Owner

Agree, ok let's go for a Matlab-like style 👍

I think we should allow the current solution with semicolon ; and \n to allow entering multiple expressions in a single string only top-level, not nested inside if statements, functions, matrices or anything. What is new is that so far, every expression did return a result. But that is not the case with if and for and multi line functions. Expressions inside if, for, or multi line expressions should not be part of the top-level output I think.

@cshaa cshaa added the category:expressions Issues about the expression parser, variable scoping etc. label Jun 19, 2021
Repository owner locked and limited conversation to collaborators Aug 26, 2022
@josdejong josdejong converted this issue into discussion #2701 Aug 26, 2022

This issue was moved to a discussion.

You can continue the conversation there. Go to discussion →

Labels
category:expressions Issues about the expression parser, variable scoping etc. feature help wanted
Projects
None yet
Development

No branches or pull requests

5 participants