<scon><longvid>op<longvid>❓ Is this the best style for infix operators? Other ideas would be:
op <longvid>, but looks odd in curried scenarios (e.g.,List.foldr op + 0vsList.foldr x + 0)(op <longvid>), except(op * )
{}{ <lab> = <exp> }{ <lab1> = <exp1>, …, <labn> = <expn> }❓ Should the spacing be required next to the braces? Alternative would be {<lab1> = <exp1>, …, <labn> = <expn>}.
{ <lab1> = <exp1>
, …
, <labn> = <expn>
}- Using
{}over()at typeunit(rather than type{})?
#lab()- Using
()over{}at type{}(rather than typeunit)?
(<exp1>, …, <expn>)( <exp1>
, …
, <expn>
)❓ Spaces probably shouldn't be used next the parentheses. Does that influence the decision for records?
[][<exp1>][<exp1>, …, <expn>][ <exp1>
, …
, <expn>
](<exp1>; …; <expn>)( <exp1>
; …
; <expn>
)❓ The multi-line syntax is uniform with other similar syntaxes, but should it be preferred here? If not, what would be better?
let
<dec>
in
<exp1>;
…;
<expn>
end❓ Should there be an allowable short-form if <dec> has one declaration? e.g.,
let val x = 21
in 2 * x
end(* my favorite, I think? *)
let val x = 21
in 2 * x endlet val x = 21 in
2 * x
endlet val x = 21 in
2 * x end❓ Can we line up the ; placement with the raw sequencing operation?
❓ Does it make sense to support a single-line sequence, e.g.
let
<dec>
in
<exp1>; …; <expn>
endwhere the <expi>s aren't "too long"?
- Empty
<dec>
(<exp>)Completely redundant parentheses. These are certainly redundant:
(42)
((42))
(x)
(let val x = 21 in 2 * x end)These probably shouldn't be considered redundant, although not sure (re conversation with @shwestrick):
((* important constant *) 42)
((* should use x, not y *) x)TODO
TODO
TODO
TODO
TODO
struct endstruct <dec (short)> endstruct
<strdec>
end<longstrid><strexp> : <sigexp (short)><strexp> :
<sigexp><strexp> :> <sigexp (short)><strexp> :>
<sigexp>struct
type t = int
val toString = Int.toString
end :> SHOW where type t = intstruct
type t = int
val toString = Int.toString
end :>
sig
type t = int
val toString : t -> string
end<funid> (<strexp (short)>)<funid> (
<strexp>
)let
<strdec>
in
<strexp>
endlet
structure S1 = F (X1)
structure S2 =
G (
structure A = X2
structure B = X3
)
in
struct
open S1 S2
end
endlet
structure S1 = F (X1)
in
H (val foo = S1.x)
endlet
structure S1 = F (X1)
in
H (
structure S = S1
val foo = S1.x
)
end- Empty
<strdec>
<dec>structure <strid> = <strexp (short)>structure <strid> =
<strexp>The same rules apply for subsequent and clauses, where and is indented to match the end of structure.
structure S = struct endstructure S2 = S1structure S =
struct
type t = int
val x : t = 42
endstructure S1 = X1
and S2 = X2❓ So, things like this should be considered good style?
Debatable, but perhaps it's good formatting-level style and just bad programmer style.
(Could consider a nonzero number of and clauses with any clause having a non-short exp to be
structure S1 =
struct
type t = int
val x : t = 42
end
and S2 = X2
and S3 = Foo (X3)
and S4 =
Foo (
type t = int
val x : t = 42
)local
<strdec1>
in
<strdec2>
end- Empty
<strdec1>
<strdec1>
<strdec2>- No space between
<strdec1>and<strdec2> - Semicolon after
<strdec1>
TODO
TODO
Hmm, yeah that's fair. And yep, equivalent to writing
structure, except if you writeandthey can't be mutually recursive (theoretically,X1andX2could be evaluated in parallel). It's definitely not extremely useful, but if we add whitespace between declarations, it's a nice way to group together similar definitions.