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

Feature request: add operator to allow break lines in matrix definition #27533

Closed
ronisbr opened this issue Jun 11, 2018 · 55 comments
Closed

Feature request: add operator to allow break lines in matrix definition #27533

ronisbr opened this issue Jun 11, 2018 · 55 comments
Labels
design Design of APIs or of the language itself parser Language parsing and surface syntax

Comments

@ronisbr
Copy link
Sponsor Member

ronisbr commented Jun 11, 2018

Hi guys,

I have started a discussion in Discourse [1] about how can we define a matrix with break lines without creating a new row. For example:

A = [1 2 3 4 5
     6 7 8 9 10]

is translated as a 2x5 matrix, because the break line character is interpreted as the end of the first row (which is good). However, I was implemented MSIS model [2] which requires the definition of matrices with 150 columns. In this case, if I choose to hard-coded those matrices in the source code to maintain compatibility, I will have to type 150 floats in one line, which is not good.

Matlab has the ... operator for this:

A = [1 2 3 4 5 ...
     6 7 8 9 10]

which translates into a 1x10 matrix.

Finally, I am wondering if we can have something like this in Julia. Currently, the only workaround as proposed in [1] is to trick the parser as follows:

A = [1 2 3 4 [5
     ] 6 7 8 9 10]

which works but it is not "optimal".


[1] https://discourse.julialang.org/t/declare-a-matrix-with-break-lines/11568/18
[2] https://ccmc.gsfc.nasa.gov/pub/modelweb/atmospheric/msis/nrlmsise00/nrlmsise00_sub.for

@JeffBezanson JeffBezanson added parser Language parsing and surface syntax design Design of APIs or of the language itself labels Jun 11, 2018
@stevengj
Copy link
Member

stevengj commented Jun 11, 2018

A = [1 2 3 4 5  #=
  =# 6 7 8 9 10]

also works, and does not involve allocating an extra temporary [5] array. Multiline comments (#69) FTW!

@stevengj
Copy link
Member

stevengj commented Jun 11, 2018

(Though honestly I don't see the problem with having 150 floats on one line. Don't editors have horizontal scroll bars these days? If you have a 150×150 matrix in your code it's just going to be a wall of 22500 numbers anyway, and scrolling seems as good a way as any to look at it in your code. You can also turn on soft wrapping in your editor if you like short lines.)

@AboAmmar
Copy link

AboAmmar commented Jun 11, 2018

I don't know if the two-dots .. are used some where, but I think it is very suitable for line continuation, or \dots (), --, etc. A comparison of different languages is here.

@ronisbr
Copy link
Sponsor Member Author

ronisbr commented Jun 12, 2018

Hi @stevengj ,

I am still used to wrap my code at column 80. IMHO, the code becomes much more readable and easier to work with because you can split your editor into two parts and still see all the code without scrolling.

Besides that, all languages that I recall have some mechanism for line continuation. This really improves code readability in some occasions. I think Julia should have also. Of course you can do everything the way it is today, but with such feature, I think we will be able to write a little bit more clear.

@stevengj
Copy link
Member

Can’t your editor do soft wrapping at column 80 if that is what you prefer?

@stevengj
Copy link
Member

stevengj commented Jun 12, 2018

(For most of the Julia language, you can insert line breaks without hacks, e.g. after any paren, comma, or binary operator. Literal matrices are a rare exception.)

@stevengj
Copy link
Member

stevengj commented Jun 12, 2018

Two dots (..) and ellipses (…) are already parsed as binary operators, and in general operators are much more useful than a continuation syntax that would only rarely arise (and is already possible with #= =#).

@ronisbr
Copy link
Sponsor Member Author

ronisbr commented Jun 12, 2018

Hi @stevengj

I use vim (actually neovim), I can do soft wrapping but it usually breaks things like multiple line cursors and macros. That is why I always prefer to actually break lines.

However, feel free to close this issue if you think such feature does not play well with Julia language design.

@StefanKarpinski
Copy link
Sponsor Member

StefanKarpinski commented Jun 12, 2018

I think what we'd really want is something more general: a way to continue any line, not specific to the matrix syntax. The best thing I've been able to come up with is \ as the last non-whitespace on a line, which would be a breaking change since this is currently valid but weird syntax:

x = y \
    z

We could even continue to support that usage of \ in non-whitespace sensitive contexts since y z is invalid syntax but that's probably a bit too clever. I'm not sure this is worth it but most languages do have a way to continue lines. The multiline comment trick works too but is a bit verbose.

@mschauer
Copy link
Contributor

Very breaking...

julia> 2\
       10
5.0

julia> 2#=
       =#10
20

@StefanKarpinski
Copy link
Sponsor Member

It's definitely breaking but I would be surprised if \ is used like that often.

@martinholters
Copy link
Member

Maybe #\? Sure, associating a new behavior to a previously ignored comment is also breaking, but having #\ as a comment is probably even less common than breaking a line after \ (used as operator).

@stevengj
Copy link
Member

stevengj commented Jun 12, 2018

The fact that multiline comments are a relatively verbose way to do this is a good thing, in my mind, to discourage people from using it casually. Python has backslash line continuation but it is now viewed as a feature of last resort. Similarly, in the vast majority of Julia syntax there is already a way to insert a linebreak without using any special continuation syntax, and that should be strongly preferred.

@ronisbr
Copy link
Sponsor Member Author

ronisbr commented Jun 12, 2018

Hi @stevengj ,

I am not sure why should people be discouraged to use line breaks. See for example this code:

            xndot = d2201 * sin(2ω + xli  - G22) +
                    d2211 * sin(   + xli  - G22) +
                    d3210 * sin(+ω + xli  - G32) -
                    d3222 * sin(-ω + xli  - G32) -
                    d5220 * sin(+ω + xli  - G52) +
                    d5232 * sin(-ω + xli  - G52) +
                    d4410 * sin(2ω + 2xli - G44) -
                    d4422 * sin(     2xli - G44) +
                    d5421 * sin(+ω + 2xli - G54) +
                    d5433 * sin(-ω + 2xli - G54)

IMHO, the operation sign at the end is not as good as having them at the beginning:

            xndot = + d2201 * sin(2ω + xli  - G22) \
                    + d2211 * sin(   + xli  - G22) \
                    + d3210 * sin(+ω + xli  - G32) \
                    - d3222 * sin(-ω + xli  - G32) \
                    - d5220 * sin(+ω + xli  - G52) \
                    + d5232 * sin(-ω + xli  - G52) \
                    + d4410 * sin(2ω + 2xli - G44) \
                    - d4422 * sin(     2xli - G44) \
                    + d5421 * sin(+ω + 2xli - G54) \
                    + d5433 * sin(-ω + 2xli - G54)

It just feels way more natural for me. Again, it is a cosmetic change, each one will have a different opinion about it. The question is: will it harm in any sense the language design?

@KristofferC
Copy link
Sponsor Member

Seems easier to just put an extra pair of enclosing parentheses in that case.

@ronisbr
Copy link
Sponsor Member Author

ronisbr commented Jun 12, 2018

Yes, it can be done. But, again IMHO, it is not common. Let's say someone sees this:

            xndot = (+ d2201 * sin(2ω + xli  - G22)
                     + d2211 * sin(   + xli  - G22)
                     + d3210 * sin(+ω + xli  - G32)
                     - d3222 * sin(-ω + xli  - G32)
                     - d5220 * sin(+ω + xli  - G52)
                     + d5232 * sin(-ω + xli  - G52)
                     + d4410 * sin(2ω + 2xli - G44)
                     - d4422 * sin(     2xli - G44)
                     + d5421 * sin(+ω + 2xli - G54) 
                     + d5433 * sin(-ω + 2xli - G54))

From a mathematical point of view, those parenthesis have no meaning. Someone could inadvertently remove them, Julia will not show any warnings, and the code will be completely wrong.

@ssfrr
Copy link
Contributor

ssfrr commented Jun 12, 2018

The best thing I've been able to come up with is \ as the last non-whitespace on a line, which would be a breaking change since this is currently valid but weird syntax

What about using # for the same purpose? The interpretation is that you're commenting out the line break. (thanks @oxinabox for bringing up this interpretation of LaTeX's use of % as comment/line continuation)

@ronisbr
Copy link
Sponsor Member Author

ronisbr commented Jun 12, 2018

Well, from my point of view, a # at the end of line without any character following, should be very nice and seems to break less things.

@oscardssmith
Copy link
Member

The one potential issue I see here is that going from

a=1 #because reasons
 +2

to

a=1 #
 +2

produces different results. This probably doesn't matter though.

@ronisbr
Copy link
Sponsor Member Author

ronisbr commented Jun 12, 2018

What about something Julia is not using like \\? Is it too ugly?

@oxinabox
Copy link
Contributor

oxinabox commented Jun 12, 2018

I would expect doing latex style "Commenting out the new like" to break things.

Unless it was restricted to only a # without any non-whitespace after.
For example:

colors = [ 0.5 0.2 0.1 0.9 # Red
                0.4 0.4 0.1 0.6 # Green
                0.1 0.2 0.1 0.1] # Blue

In LaTeX that not have any new lines in it.
And having an empty comment act differently to a non-empty one sounds weird.

I was not actually suggesting it for julia.
I think \\ would be much less confusing.
But I think @stevengj solution of a multiline comment might be nicest. It is very explicitly commenting out the new line

Though making giant multiline literals seems pretty niche.
Even more so than having literals for Array{T, 3}.

One should be able to construct them just as efficiently using the vect and the cat commands that literal lowers to anyway.

@ronisbr
Copy link
Sponsor Member Author

ronisbr commented Jun 12, 2018

I think the proposal was to have a # followed by new line character only (or only spaces probably).

@ssfrr
Copy link
Contributor

ssfrr commented Jun 12, 2018

Yeah, I meant doing @StefanKarpinski's suggestion of special handling of # at the end of a line, definitely not counting the case where there's other non-whitespace stuff after the #. Perhaps the LaTeX comparison was more confusing than clarifying for what I was trying to say.

@DNF2
Copy link

DNF2 commented Jun 13, 2018

Co-opting # seems risky to me. I sometimes have #s scattered in my code, for reasons I don't quite remember, comments that I sort of changed my mind about, etc. It would be very easy to inadvertently remove a trailing #s when 'cleaning up'.

I do occasionally miss a line continuation operator, but would prefer it to be very explicitly obvious, like \ or .... The #= or [] seem a bit too much like a trick.

(If the use is to be discouraged, maybe something slightly ugly, like \\\ would work?)

@DNF2
Copy link

DNF2 commented Jun 13, 2018

It is also quite normal for me to put comments after a line continuation operator, so I would not like having to rely on it being the last non-whitespace character on the line.

@thchr
Copy link
Contributor

thchr commented Jun 13, 2018

Not sure if they are already used elsewhere, or should be reserved for user-specific operators, but one of these Unicode arrows might make appealing, intuitive options for explicit line-continuation:

, , or

(made accessible e.g. with some meaningful tab-completed alias, like \continueline)

@JeffBezanson
Copy link
Sponsor Member

I think it's fortunate that #= =# works for this and we should leave it at that.

I don't agree that putting backslashes at the end of every line is somehow better than adding parentheses or just putting the operators at the end of the line. I also don't think abusing backslash or # will be an improvement; that would just add surprises. If we used something multi-character, it wouldn't then be much of an improvement over #= =#.

@StefanKarpinski
Copy link
Sponsor Member

I don't agree that putting backslashes at the end of every line is somehow better than adding parentheses or just putting the operators at the end of the line.

The reason this issue was opened was that neither of those work for matrix literals. Still, I agree that we probably shouldn't do anything for this since #= =# already works.

@StefanKarpinski
Copy link
Sponsor Member

I suspect we could spare one.

@ronisbr
Copy link
Sponsor Member Author

ronisbr commented Jun 13, 2018

Good options IMHO:

⤸ (2938) ↩ (8617) ↵ (8629) 

@MikeInnes
Copy link
Member

Perhaps it's time to make whitespace an operator, and we can overload it in large-matrix contexts with Cassette. Happily, Bjarne Stroustrup already did the hard design work for us – http://www.stroustrup.com/whitespace98.pdf

@DNF2
Copy link

DNF2 commented Jun 14, 2018

If we used something multi-character, it wouldn't then be much of an improvement over #= =#.

I would like to forward three arguments against this.

Firstly, this can be mistaken for a comment. Even if I know this, my brain registers "Comment".

Secondly, you have to put it on two lines, not just on one. (How will this interact with indentation?)

Thirdly, it's a more complicated combination of keypresses (on my computer it's shift-3 shift-0 enter shift-0 shift-3). I guess some sort of keyboard shortcut could be used. \\ is, by contrast, two quick presses of the same key (followed by enter.)

Three-and-a-halfly: IMHO it looks a bit awkward, and feels like a trick.

@ronisbr
Copy link
Sponsor Member Author

ronisbr commented Jun 14, 2018

Even if the \\ is not accepted because it maybe "reserved" for future use, I really think @thchr suggestion looks very nice. Look how it will be:

            xndot = + d2201 * sin(2ω + xli  - G22) ⤸
                    + d2211 * sin(   + xli  - G22) ⤸
                    + d3210 * sin(+ω + xli  - G32) ⤸
                    - d3222 * sin(-ω + xli  - G32) ⤸
                    - d5220 * sin(+ω + xli  - G52) ⤸
                    + d5232 * sin(-ω + xli  - G52) ⤸
                    + d4410 * sin(2ω + 2xli - G44) ⤸
                    - d4422 * sin(     2xli - G44) ⤸
                    + d5421 * sin(+ω + 2xli - G54) ⤸
                    + d5433 * sin(-ω + 2xli - G54)

And, besides that, no one will be forced to use this and it will not break anything. But I'm sure there will be good use cases for this (the big matrices that led me to open this issue is one):

pd = [
     1.09979E+00 -4.88060E-02 -1.97501E-01 -9.10280E-02 -6.96558E-032.42136E-02  3.91333E-01 -7.20068E-03 -3.22718E-02  1.41508E+001.68194E-01  1.85282E-02  1.09384E-01 -7.24282E+00  0.00000E+002.96377E-01 -4.97210E-02  1.04114E+02 -8.61108E-02 -7.29177E-041.48998E-06  1.08629E-03  0.00000E+00  0.00000E+00  8.31090E-021.12818E-01 -5.75005E-02 -1.29919E-02 -1.78849E-02 -2.86343E-060.00000E+00 -1.51187E+02 -6.65902E-03  0.00000E+00 -2.02069E-030.00000E+00  0.00000E+00  4.32264E-02 -2.80444E+01 -3.26789E-032.47461E-03  0.00000E+00  0.00000E+00  9.82100E-02  1.22714E-01-3.96450E-02  0.00000E+00 -2.76489E-03  0.00000E+00  1.87723E-03-8.09813E-03  4.34428E-05 -7.70932E-03  0.00000E+00 -2.28894E-03-5.69070E-03 -5.22193E-03  6.00692E-03 -7.80434E+03 -3.48336E-03-6.38362E-03 -1.82190E-03  0.00000E+00 -7.58976E+01 -2.17875E-02-1.72524E-02 -9.06287E-03  0.00000E+00  2.44725E-02  8.66040E-021.05712E-01  3.02543E+04  0.00000E+00  0.00000E+00  0.00000E+00-6.01364E+03 -5.64668E-03 -2.54157E-03  0.00000E+00  3.15611E+02-5.69158E-03  0.00000E+00  0.00000E+00 -4.47216E-03 -4.49523E-034.64428E-03  0.00000E+00  0.00000E+00  0.00000E+00  0.00000E+004.51236E-02  2.46520E-02  6.17794E-03  0.00000E+00  0.00000E+00-3.62944E-01 -4.80022E-02 -7.57230E+01 -1.99656E-03  0.00000E+00-5.18780E-03 -1.73990E-02 -9.03485E-03  7.48465E-03  1.53267E-021.06296E-02  1.18655E-02  2.55569E-03  1.69020E-03  3.51936E-02-1.81242E-02  0.00000E+00 -1.00529E-01 -5.10574E-03  0.00000E+002.10228E-03  0.00000E+00  0.00000E+00 -1.73255E+02  5.07833E-01-2.41408E-01  8.75414E-03  2.77527E-03 -8.90353E-05 -5.25148E+00-5.83899E-03 -2.09122E-02 -9.63530E-03  9.77164E-03  4.07051E-032.53555E-04 -5.52875E+00 -3.55993E-01 -2.49231E-03  0.00000E+000.00000E+00  2.86026E+01  0.00000E+00  3.42722E-04  0.00000E+000.00000E+00  0.00000E+00  0.00000E+00  0.00000E+00  0.00000E+000.00000E+00  0.00000E+00  0.00000E+00  0.00000E+00  0.00000E+00;
     1.02315E+00 -1.59710E-01 -1.06630E-01 -1.77074E-02 -4.42726E-033.44803E-02  4.45613E-02 -3.33751E-02 -5.73598E-02  3.50360E-016.33053E-02  2.16221E-02  5.42577E-02 -5.74193E+00  0.00000E+001.90891E-01 -1.39194E-02  1.01102E+02  8.16363E-02  1.33717E-046.54403E-06  3.10295E-03  0.00000E+00  0.00000E+00  5.38205E-02...

instead of

pd = [
     1.09979E+00 -4.88060E-02 -1.97501E-01 -9.10280E-02 -6.96558E-03 #= 
 =#  2.42136E-02  3.91333E-01 -7.20068E-03 -3.22718E-02  1.41508E+00 #=
 =#  1.68194E-01  1.85282E-02  1.09384E-01 -7.24282E+00  0.00000E+00 #=
 =#  2.96377E-01 -4.97210E-02  1.04114E+02 -8.61108E-02 -7.29177E-04 #=
 =#  1.48998E-06  1.08629E-03  0.00000E+00  0.00000E+00  8.31090E-02 #=
 =#  1.12818E-01 -5.75005E-02 -1.29919E-02 -1.78849E-02 -2.86343E-06 #=
 =#  0.00000E+00 -1.51187E+02 -6.65902E-03  0.00000E+00 -2.02069E-03 #=
 =#  0.00000E+00  0.00000E+00  4.32264E-02 -2.80444E+01 -3.26789E-03 #=
 =#  2.47461E-03  0.00000E+00  0.00000E+00  9.82100E-02  1.22714E-01 #=
 =# -3.96450E-02  0.00000E+00 -2.76489E-03  0.00000E+00  1.87723E-03 #=
 =# -8.09813E-03  4.34428E-05 -7.70932E-03  0.00000E+00 -2.28894E-03 #=
 =# -5.69070E-03 -5.22193E-03  6.00692E-03 -7.80434E+03 -3.48336E-03 #=
 =# -6.38362E-03 -1.82190E-03  0.00000E+00 -7.58976E+01 -2.17875E-02 #=
 =# -1.72524E-02 -9.06287E-03  0.00000E+00  2.44725E-02  8.66040E-02 #=
 =#  1.05712E-01  3.02543E+04  0.00000E+00  0.00000E+00  0.00000E+00 #=
 =# -6.01364E+03 -5.64668E-03 -2.54157E-03  0.00000E+00  3.15611E+02 #=
 =# -5.69158E-03  0.00000E+00  0.00000E+00 -4.47216E-03 -4.49523E-03 #=
 =#  4.64428E-03  0.00000E+00  0.00000E+00  0.00000E+00  0.00000E+00 #=
 =#  4.51236E-02  2.46520E-02  6.17794E-03  0.00000E+00  0.00000E+00 #=
 =# -3.62944E-01 -4.80022E-02 -7.57230E+01 -1.99656E-03  0.00000E+00 #=
 =# -5.18780E-03 -1.73990E-02 -9.03485E-03  7.48465E-03  1.53267E-02 #=
 =#  1.06296E-02  1.18655E-02  2.55569E-03  1.69020E-03  3.51936E-02 #=
 =# -1.81242E-02  0.00000E+00 -1.00529E-01 -5.10574E-03  0.00000E+00 #=
 =#  2.10228E-03  0.00000E+00  0.00000E+00 -1.73255E+02  5.07833E-01 #=
 =# -2.41408E-01  8.75414E-03  2.77527E-03 -8.90353E-05 -5.25148E+00 #=
 =# -5.83899E-03 -2.09122E-02 -9.63530E-03  9.77164E-03  4.07051E-03 #=
 =#  2.53555E-04 -5.52875E+00 -3.55993E-01 -2.49231E-03  0.00000E+00 #=
 =#  0.00000E+00  2.86026E+01  0.00000E+00  3.42722E-04  0.00000E+00 #=
 =#  0.00000E+00  0.00000E+00  0.00000E+00  0.00000E+00  0.00000E+00 #=
 =#  0.00000E+00  0.00000E+00  0.00000E+00  0.00000E+00  0.00000E+00;
     1.02315E+00 -1.59710E-01 -1.06630E-01 -1.77074E-02 -4.42726E-03 #=
 =#  3.44803E-02  4.45613E-02 -3.33751E-02 -5.73598E-02  3.50360E-01 #=
 =#  6.33053E-02  2.16221E-02  5.42577E-02 -5.74193E+00  0.00000E+00 #=
 =#  1.90891E-01 -1.39194E-02  1.01102E+02  8.16363E-02  1.33717E-04 #=
 =#  6.54403E-06  3.10295E-03  0.00000E+00  0.00000E+00  5.38205E-02 #=
     ...

@stevengj
Copy link
Member

stevengj commented Jun 14, 2018

To the extent that a wall of numbers like that can ever "look nice", it looks a lot nicer to me to put each row on a single line. At least that way I can tell how many rows the matrix has, and whether the rows have the same length.

pd = [ 1.09979E+00 -4.88060E-02 -1.97501E-01 -9.10280E-02 -6.96558E-03 2.42136E-02  3.91333E-01 -7.20068E-03 -3.22718E-02  1.41508E+00 1.68194E-01  1.85282E-02  1.09384E-01 -7.24282E+00  0.00000E+00 2.96377E-01 -4.97210E-02  1.04114E+02 -8.61108E-02 -7.29177E-04 1.48998E-06  1.08629E-03  0.00000E+00  0.00000E+00  8.31090E-02 1.12818E-01 -5.75005E-02 -1.29919E-02 -1.78849E-02 -2.86343E-06 0.00000E+00 -1.51187E+02 -6.65902E-03  0.00000E+00 -2.02069E-03 0.00000E+00  0.00000E+00  4.32264E-02 -2.80444E+01 -3.26789E-03 2.47461E-03  0.00000E+00  0.00000E+00  9.82100E-02  1.22714E-01 -3.96450E-02  0.00000E+00 -2.76489E-03  0.00000E+00  1.87723E-03 -8.09813E-03  4.34428E-05 -7.70932E-03  0.00000E+00 -2.28894E-03 -5.69070E-03 -5.22193E-03  6.00692E-03 -7.80434E+03 -3.48336E-03 -6.38362E-03 -1.82190E-03  0.00000E+00 -7.58976E+01 -2.17875E-02 -1.72524E-02 -9.06287E-03  0.00000E+00  2.44725E-02  8.66040E-02 1.05712E-01  3.02543E+04  0.00000E+00  0.00000E+00  0.00000E+00 -6.01364E+03 -5.64668E-03 -2.54157E-03  0.00000E+00  3.15611E+02 -5.69158E-03  0.00000E+00  0.00000E+00 -4.47216E-03 -4.49523E-03 4.64428E-03  0.00000E+00  0.00000E+00  0.00000E+00  0.00000E+00 4.51236E-02  2.46520E-02  6.17794E-03  0.00000E+00  0.00000E+00 -3.62944E-01 -4.80022E-02 -7.57230E+01 -1.99656E-03  0.00000E+00 -5.18780E-03 -1.73990E-02 -9.03485E-03  7.48465E-03  1.53267E-02 1.06296E-02  1.18655E-02  2.55569E-03  1.69020E-03  3.51936E-02 -1.81242E-02  0.00000E+00 -1.00529E-01 -5.10574E-03  0.00000E+00 2.10228E-03  0.00000E+00  0.00000E+00 -1.73255E+02  5.07833E-01 -2.41408E-01  8.75414E-03  2.77527E-03 -8.90353E-05 -5.25148E+00 -5.83899E-03 -2.09122E-02 -9.63530E-03  9.77164E-03  4.07051E-03 2.53555E-04 -5.52875E+00 -3.55993E-01 -2.49231E-03  0.00000E+00 0.00000E+00  2.86026E+01  0.00000E+00  3.42722E-04  0.00000E+00 0.00000E+00  0.00000E+00  0.00000E+00  0.00000E+00  0.00000E+00 0.00000E+00  0.00000E+00  0.00000E+00  0.00000E+00  0.00000E+00
       1.02315E+00 -1.59710E-01 -1.06630E-01 -1.77074E-02 -4.42726E-03 3.44803E-02  4.45613E-02 -3.33751E-02 -5.73598E-02  3.50360E-01 6.33053E-02  2.16221E-02  5.42577E-02 -5.74193E+00  0.00000E+00 1.90891E-01 -1.39194E-02  1.01102E+02  8.16363E-02  1.33717E-04 6.54403E-06  3.10295E-03  0.00000E+00  0.00000E+00  5.38205E-02 ...
       ...

c42f added a commit that referenced this issue Sep 19, 2018
@c42f
Copy link
Member

c42f commented Sep 19, 2018

I think it's great that there's one obvious way to write expressions which cross multiple lines because consistency across the ecosystem is more important than flexibility in this kind of formatting.

This suggests we leave things as is, except for one thing: in contexts where whitespace is significant (macros, but also matrix construction) there's currently zero obvious ways to continue lines. The multi line comment hack is clever, but also ugly, IMO.

We can solve both of these at once by adding a line continuation which is only valid in space-sensitive parsing contexts:

# Valid - space sensitive context
@info "A message which could be rather long"  ⤸
      my_variable my_variable2                ⤸
      some_other_variable

# Invalid - there should only be one way to do this
x = some_variable ⤸
    + other_variable
# Valid - the current, perfectly good convention for writing this
x = some_variable +
    other_variable

@c42f
Copy link
Member

c42f commented Sep 19, 2018

I've implemented unicode ⤸ for line continuation in the cjf/line-continuation branch. This is a simpler version not restricted to space sensitive contexts but that should be easy with a bit of rearrangement.

@mschauer
Copy link
Contributor

It would be really good to have an explicit combined column separation, row continuation operator. It would solve OP's problem and enhace readability of matrix expressions with formulas. Mock example using |,

       [ x .+ 1 | 3*(x .+ 2) |
        12 + x | -x ]

@StefanKarpinski
Copy link
Sponsor Member

StefanKarpinski commented Sep 19, 2018

Why would more than one line continuation character be required?

@c42f
Copy link
Member

c42f commented Sep 19, 2018

For the sake of having a concrete proposal, I've made a PR for this - see #29273

@ronisbr
Copy link
Sponsor Member Author

ronisbr commented Sep 19, 2018

@c42f, IMHO, I think it will be somewhat confusing to allow the line continuation character only in specific occasions. Why can't we let it be global?

@mschauer
Copy link
Contributor

Stefan: Only for readability. This would only suggest to allow line continuation characters within a line to emphasise and force field separation in whitespace separated context.

@c42f
Copy link
Member

c42f commented Sep 19, 2018

@ronisbr the fact that there's only one obvious way to continue lines in most expressions like

x = a +
    b +
    c

is rather appealing to me and I didn't want to change that.

Allowing this to also be written as

x =   a  ⤸
    + b  ⤸
    + c

just introduces unnecessary variation IMO.

The language already has the concept of "space sensitive" contexts where the parsing rules are different, and this slots neatly in there.

c42f added a commit that referenced this issue Sep 19, 2018
@ronisbr
Copy link
Sponsor Member Author

ronisbr commented Feb 5, 2019

Hi guys!

Now that we have 1.1, can we discuss this feature for 1.2? At least, can we decide if this will eventually become a new feature or this issue should be closed?

@StefanKarpinski
Copy link
Sponsor Member

cc @JeffBezanson, aka the syntax czar.

@tpapp
Copy link
Contributor

tpapp commented Mar 27, 2019

Having found multiline comments as suggested by @stevengj perfectly adequate for this purpose (and in general), I wonder if we could just mention this in the manual and thus resolve the issue without any change to the language. If yes, I would be happy to make a PR in the relevant places (one for matrices, one as general advice).

I realize that some language have special syntax for this, and that is occasionally useful. However, I don't think that writing super-long lines or including large literal matrices in source should become a habit encouraged by the language, rather than something we just have some support for in the rare case it is needed.

@c42f
Copy link
Member

c42f commented Mar 27, 2019

I agree that the case for multiline matrix wrapping is sufficiently unusual to be covered by using #= =# and it would be worth documenting this option for line continuation. For multi-line macro invocations I use this syntax, but I still find it ugly and cumbersome.

@stevengj
Copy link
Member

stevengj commented Mar 27, 2019

For multi-line macro calls you could use parentheses.

@c42f
Copy link
Member

c42f commented Mar 28, 2019

I'm well aware of the option to use parens for macros but I find it dissatisfying as I've described before. Namely, using parentheses and commas makes the macro invocation very visually distinct from the way that macros "usually look" in most juila code. Code which looks different is harder to read.

@ronisbr
Copy link
Sponsor Member Author

ronisbr commented Nov 28, 2020

Hi guys!

@JeffBezanson do you have a final word on this?

People seem to dislike the ideia. Although I am someone who loves to stick with 80 columns, I have to acknowledge that even the kernel has removed this limitation.

I would love to have an UTF-8 only character to do this in certain situations, and I think that it would not hurt, IMHO, since it is not enforced.

However, I understand if you think this is not required, given that workaround, and then we can close this issue.

@ronisbr ronisbr closed this as completed Nov 28, 2022
@ronisbr
Copy link
Sponsor Member Author

ronisbr commented Nov 28, 2022

I am closing because I am not even sure I would have used this feature :)

@c42f
Copy link
Member

c42f commented Dec 7, 2022

Actually the original feature request for this was implemented a while ago! Not a general line continuation character (which I still kind of want for macros), but as part of the syntax for general multidimensional array literals:

julia> [1 2 3 4 5 ;;
        6 7 8 9 10]
1×10 Matrix{Int64}:
 1  2  3  4  5  6  7  8  9  10

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
design Design of APIs or of the language itself parser Language parsing and surface syntax
Projects
None yet
Development

Successfully merging a pull request may close this issue.