lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


tl;dr: argument lists feel like they should be one line. Block scope is multiple lines. Swift (and Ruby) allow a block as argument outside the syntactic arglist parens.

Since the nature of arglists is in the news, I decided to resurrect this draft.

On Jun 3, 2014 2:32 AM, "Dirk Laurie" <dirk.laurie@gmail.com> wrote:
>
> 2014-06-02 21:12 GMT+02:00 Petite Abeille <petite.abeille@gmail.com>:
>
> > https://developer.apple.com/swift/
>
> var sortedStrings = sort(stringArray) {
>    $0.uppercaseString < $1.uppercaseString
> }

Let's look at the Smalltalk version of that:

sortedStrings := stringArray sorted: [:a :b |
    a uppercaseString < b uppercaseString ]

We've discussed and/or implemented terse lambda syntax before, so you know of the appeal of eliminating ":a :b |" at least in toy examples.

Smalltalk multiword selector syntax is syntactic sugar for a symbol formed from the concatenation of keywords, with an interspersed parameter list. When you see Smalltalk something like:

o rangeFrom: 17 to: 0 by: -1

it's really doing something like this Lua syntax:

o:rangeFrom_to_by(17, 0, -1)

Objective C inherits Smalltalk's strategy for naming methods, and so does Swift. In Swift, the names of keyword arguments are part of the name of the method...except for the first argument. In Swift, I think the syntax would be:

o.rangeFrom(17, to: 0, by: -1)

but it means exactly the same thing as the Smalltalk. Note that "keywords are a part of the name" is a characteristic of methods, not functions. There are some other baroque things in Swift args. And Dylan 1.0 spent a *lot* of effort on getting named defaulting arguments to work right. I think my initial reaction to Swift came from that.

Going back to string sorting, Swift picks up something I first saw in Ruby, which is allowing a single closure argument to be placed outside the parenthesized argument list. Consider the following Lua syntax:

sortedStrings = stringArray:sorted(function (a,b)
    return a:uppercaseString() < b:uppercaseString()
    end)

Something in my brain sees "end)" and says, "that's wrong!" because argument lists are "one line". Block structure is what spans multiple lines. So in an argument list, a block closer like "end" does not belong there.

This is equally distasteful to me in _javascript_ and Java; I think it is inherent to how I learned Algol syntaxes.

In fake Lua syntax, the Ruby approach would look like:

sortedStrings = stringArray:sorted() doing (a, b)
    return a:uppercaseString() < b:uppercaseString()
end

In this syntax, all parentheses close on the same line they open.

The restriction to zero or one blocks seems wrong; why stop at one? I don't know.

An interesting thing about Ruby's implementation was that the block parameter had no name. It was like the Lua "..." syntax: you could not capture it. This could allow a less dynamic, Pascal-style nested procedure implementation of the block in the calling context (given restrictions on returning closures). If you are looking for a syntax and mechanism for control flow which is significantly weaker/simpler than terse lambdas, this is it.

Jay