[swift-evolution] [Idea] Custom keywords for operators.

Gor Gyolchanyan gor.f.gyolchanyan at icloud.com
Mon Jul 31 16:09:03 CDT 2017

So I was thinking the other day (and by "the other day" I mean "It just occurred to me") that Swift's custom operator declaration mechanism is pretty sweet (it's become even sweeter ever since numeric precedence values were replaced with purely relativistic precedence trees). There are currently only two problems with them that grind my operator-declaring endeavors to a painful halt:
	1. The fact that most punctuation characters on the keyboard (think - ASCII) are reserved, so any custom operator either has to be a long sequence of two or three non-reserved ASCII characters or have to include difficult-to-type unicode punctuation characters.
	2. The fact that anything that passes as an identifier character (which includes a surprisingly wide array of punctuation characters) is off the table as well.

I have no good idea how to deal with the first problem, but the second problem seems to have a bafflingly simple solution that I can't believe I haven't noticed until now.
And the reason to even try to solve that problem is because Swift already has a lot of operators with identifiers in them:
	* infix is
	* infix as
	* infix as?
	* infix as!
	* prefix try
	* prefix try?
	* prefix try!
	* prefix throw
So this is hardly a new concept to Schwifty developers.

The way I think could this could be solved is by introducing custom keywords that can be defined just like custom operators can be.
The custom keyword has to be a valid identifier and is defined much like a non-infix custom operator (by writing `keyword`, followed by an identifier).

Custom operator definitios would now be permitted to have any number of non-adjacent keywords among usual punctuation characters.
Any identifier that matches a custom keyword has to be escaped with backticks just like it's the case for regular keywords.
Prefix operators may not end with a keyword.
Postfix operators may not begin with a keyword.
Infix operators that either begin or end with a keyword may not be used without whitespaces.

Here's an example:

precedencegroup AggregateFormingPrecedence {
	higherThan: TernaryPrecedence
	lowerThan: LogicalDisjunctionPrecedence

precedencegroup DimensionFormingPrecedence {
	higherThan: AggregateFormingPrecedence
	lowerThan: LogicalDisjunctionPrecedence

keyword of
keyword by
infix operator of: AggregateFormingPrecedence
infix operator by: DimensionFormingPrecedence

public struct Matrix<Element> where Element: FloatingPoint {

	public struct Dimensions {
		let rows: Int
		let columns: Int

	public init(dimensions: Dimensions, value: Element) {
		self.elements = .init(repeating: value, count: dimensions.rows * dimensions.columns)

	private var elements: [Element]

public static func by(_ rows: Int, _ columns: Int) -> Matrix.Dimensions {
	return .init(rows: rows, columns: columns)

public static func of<Element>(_ dimensions: Matrix.Dimensions, _ value: Element) -> Matrix<Element> where Element: FloatingPoint {
	return .init(dimensions: dimensions, value: value)

let m = 3 by 4 of 1.0 // m is of type Matrix<Double>

I feel like these kind of changes would be best considered in the early stages of a major release (namely, Swift 5) so that they have time to be refined and tested.
What do you guys think?

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20170801/86834c25/attachment-0001.html>

More information about the swift-evolution mailing list