SE-0084 spinoff: Newlines as item separators

Could you show me an example of a fictional EDSL that gets better with newline separated lists?

I’ll do better than that. I’ll show and example of a real EDSL I implemented in Ruby in the early days of iOS. It was used to generate very efficient streaming SAX-style XML parsers which parsed the data directly into model objects without building an intermediate DOM (validating the data in the process). The generated parsers were implemented in Objective-C with some use of C code in the implementation.

Here is a sample in Ruby:

object :attribute1, :class => :ObjectiveCClassName do
    integer :id
    string :description
    bool :is_active, :property => :isActive
    date :created_at, :property => :createdAt
    array :items do
        object :item, :class => :AnotherObjectiveCClass do
                float :amount
        end
    end
end

The EDSL was used to build a data structure describing the expected schema and how it maps to the model objects. That schema was used to generate the parser.

You would probably do some things different in Swift but a relatively direct translation will suffice to demonstrate how removing commas is desirable. This example will assume Swift is also the target language.

Operators are used so that the structure of the EDSL follows the Ruby closer rather than nesting the array inside of the parameter list). Please ignore the specific operator “names". I just selected something arbitrary.

Here is what we would have in Swift with commas (I modified the EDSL slightly to make it more type-safe as it was intended to have only one child node for `array` to define the element type):

object (“attribute1”, type: ASwiftType) ++++ [
    integer (“id”),
    string (“description”),
    bool (“is_active”, property: “isActive”),
    date (“created_at”, property: “createdAt”),
    array (“items”) >>>> object (“item”, type: AnotherSwiftType) ++++ [
        float (“amount”)
    ]
]

And here without commas:

object (“attribute1”, type: ASwiftType) ++++ [
    integer (“id”)
    string (“description”)
    bool (“is_active”, property: “isActive”)
    date (“created_at”, property: “createdAt”)
    array (“items”) >>>> object (“item”, type: AnotherSwiftType) ++++ [
        float (“amount”)
    ]
]

The difference isn’t super significant, but IMO every bit of unnecessary / undesirable syntactic noise in an EDSL is a flaw. The less noise the language requires the better it is for creating EDSLs. You want to be able to approximate the syntax you might design from scratch relatively closely.

In this case, items in the list are essentially statements / declarations in the EDSL. You don’t want commas here for the same reason we appreciate the omission of semicolons as line terminators in Swift and other modern languages.

The obvious advantage of using Swift is that you can design the EDSL to have very strict types and reject anything invalid at compile time.

The Ruby still feels slightly cleaner to me because Ruby allows you to omit parentheses for expressions that only involve a single method call. Ruby also has symbols which are lighter syntactically than string literals. Both of these are also features that might be interesting to consider adding to Swift IMO. For the sake of argument (but without considering whether that would be practical in the Swift grammar, and whether Swift would borrow Ruby’s colon for symbols) here is what you might be able to do in Swift if we do get those features:

(object :attribute1, type: ASwiftType) ++++ [
    integer :id
    string :description
    bool :is_active, property: :isActive
    date :created_at, property: :createdAt
    (array :items) >>>> (object item, type: AnotherSwiftType) ++++ [
        float :amount
    ]
]

This roughly as good as the Ruby, a language which is praised for the flexibility it allows in designing EDSLs. Pretty cool! (Of course while I loved it in Ruby, I imagine there would be a lot of controversy if we do ever consider allowing simple expressions to omit parentheses in Swift)

···

On May 18, 2016, at 10:51 AM, David Hart <david@hartbit.com> wrote:

On 18 May 2016, at 16:02, Matthew Johnson <matthew@anandabits.com <mailto:matthew@anandabits.com>> wrote:

Sent from my iPad

On May 18, 2016, at 8:08 AM, David Hart via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

It would cumbersome to transform to newline-separated list to a comma-seperated list, because you’d have to add a character on top of removing the newline.

The way I edit code this would not add any extra keystrokes. Select new line, insert comma rather than select new line and press delete.

This feature would be fantastic when making EDSLs in Swift. It would help them come out much cleaner any time they include a comma separated list that is likely to be formatted on individual lines.

Big +1 from me.

On 18 May 2016, at 14:20, Patrick Smith <pgwsmith@gmail.com <mailto:pgwsmith@gmail.com>> wrote:

I don’t really see what the issue with having to reintroduce commas would be? The losing track of where the items are separated?

Maybe there could be an Xcode key shortcut to toggle commas off and on for newline separated items, like the current toggler for comments.

On 18 May 2016, at 6:28 PM, David Hart via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

-1 I see one big downside. Contrary to statements, which rarely appear on the same line, other list elements are more frequently reformatted, from one line to multiple lines and back. For example, I'll try to find function declarations with too many arguments (formatted on multiple lines) and refactor them to reduce the number of arguments and reformat them on one line. This style refactoring would be made more difficult because it would force me to re-introduce commas if they had been removed. Summary: I'm against this proposal because element lists can be frequently reformatted from one to multiple lines.

On 17 May 2016, at 20:06, Tino Heth via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

[Due to popular demand ;-) in the discussion of SE-0084: Allow trailing commas in parameter lists and tuples]

The option to skip semicolons for statements followed by a newline is only a tiny convinience, yet it is one of the most favored differences to C (and one of the most annoying things to remember when you have to switch from Swift to do some coding in Objective-C).
While lists of statements don't need a special separator character anymore, other lists still rely on commas to separate items:
- method parameters
- array and dictionary literals
- tuples
[anything else?]

SE-0084 targets to make it easier to reorder list elements by allowing an additional comma after the last element; afaics, the same can be achieved by making all of those commas optional, as long as there is a newline to separate the next item (without those newlines, SE-0084 makes less sense as well).

This change is not incompatible with SE-0084, but imho it doesn't make much sense to combine those features (at least in actual source code).

So, first question:
What are the downsides of this change? (question zero is "are there any other places where comma-separeted lists could be turned into newline-separated lists?"...)

Tino

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution