<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... I see your point regarding unnecessary indentation.
Instinctively, I'm not a fan of the "even further" idea, since I think putting the
structuredeclaration at the "same level" as the other declarations can get confusing quickly. (And, it feels like a special case, since presumably putting another structure inside ofSshould incur more indentation.)Not sure how I feel about the standard "no indentation" example. Definitely seems more reasonable, but how would this interact with other cases, like functor application? e.g.,
feels odd, but maybe that's just me.
Personally, I don't mind the extra indentation for the sake of uniformity (especially in the case of other top-level decls), but perhaps I'm an edge case?