Allowing Characters for use as Custom Operators


(Jo Albright) #1

As my obsession grows with custom operators. I have come across wanting to use small words or 1-2 alphabetical characters as custom operators. I noticed that “as” and “is” are character based operators and figured it wouldn’t hurt to propose the allowance of character based custom operators.

Here are my reasons for allowing them:

1. easier to read “within” vs “>*<“ or “|*|”

2. potential opportunity to build an educational library to help explain expressions (see below)

infix operator plus { associativity left precedence 200 }

public func plus (lhs: Int, rhs: Int) -> Int {
    
    return lhs + rhs
    
}

let totalApples = 5 plus 5

3. potential to write more like a sentence (this isn’t as high of a need, but again a good for entry into the language)

postfix operator oz { }
postfix operator cup { }
postfix operator gal { }

public func oz (inout _ lhs: Double) -> Double {
    
    return lhs
    
}

public func cup (inout _ lhs: Double) -> Double {
    
    return lhs *= 8.0
    
}

public func gal (inout _ lhs: Double) -> Double {
    
    return lhs *= 128.0
    
}

let totalLiquidInOunces = 5oz plus 2cup plus 1gal

I spent awhile looking to make sure this hasn’t been proposed before. I apologize if it is a repeat.

Thanks

 Nerd . Designer . Developer
Jo Albright


Declaring a Bool and its inverse counterpart in one line
(Félix Cloutier) #2

In a discussion about adding $ to the operator character set (it currently is an identifier character), Chris said that any token must be unambiguously either an identifier or an operator even before operators are "discovered", and that's why the identifier character sets and operator character sets have no overlap right now.

"as" and "is" are not operators, they're keywords that were hard-coded into the grammar.

Félix

···

Le 7 janv. 2016 à 04:31:10, Jo Albright via swift-evolution <swift-evolution@swift.org> a écrit :

As my obsession grows with custom operators. I have come across wanting to use small words or 1-2 alphabetical characters as custom operators. I noticed that “as” and “is” are character based operators and figured it wouldn’t hurt to propose the allowance of character based custom operators.

Here are my reasons for allowing them:

1. easier to read “within” vs “>*<“ or “|*|”

2. potential opportunity to build an educational library to help explain expressions (see below)

infix operator plus { associativity left precedence 200 }

public func plus (lhs: Int, rhs: Int) -> Int {
    
    return lhs + rhs
    
}

let totalApples = 5 plus 5

3. potential to write more like a sentence (this isn’t as high of a need, but again a good for entry into the language)

postfix operator oz { }
postfix operator cup { }
postfix operator gal { }

public func oz (inout _ lhs: Double) -> Double {
    
    return lhs
    
}

public func cup (inout _ lhs: Double) -> Double {
    
    return lhs *= 8.0
    
}

public func gal (inout _ lhs: Double) -> Double {
    
    return lhs *= 128.0
    
}

let totalLiquidInOunces = 5oz plus 2cup plus 1gal

I spent awhile looking to make sure this hasn’t been proposed before. I apologize if it is a repeat.

Thanks

 Nerd . Designer . Developer
Jo Albright

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


(Chris Lattner) #3

Check out Replace Logical Operators (&&, ||, etc) with words like "and" and “or":

There is very small win here of “x foo y” over "x.foo(y)”?

-Chris

···

On Jan 7, 2016, at 1:31 AM, Jo Albright via swift-evolution <swift-evolution@swift.org> wrote:

As my obsession grows with custom operators. I have come across wanting to use small words or 1-2 alphabetical characters as custom operators. I noticed that “as” and “is” are character based operators and figured it wouldn’t hurt to propose the allowance of character based custom operators.

Here are my reasons for allowing them:

1. easier to read “within” vs “>*<“ or “|*|”


(Dennis Lysenko) #4

Jo, it sounds like you're describing infix functions. If you want to bring
up a concrete example, Kotlin has this implementation and it's fantastic
for creating your own syntactic sugar.

···

On Thu, Jan 7, 2016, 11:31 AM Félix Cloutier <swift-evolution@swift.org> wrote:

In a discussion about adding $ to the operator character set (it currently
is an identifier character), Chris said that any token must be
unambiguously either an identifier or an operator even before operators are
"discovered", and that's why the identifier character sets and operator
character sets have no overlap right now.

"as" and "is" are not operators, they're keywords that were hard-coded
into the grammar.

Félix

Le 7 janv. 2016 à 04:31:10, Jo Albright via swift-evolution < > swift-evolution@swift.org> a écrit :

As my obsession grows with custom operators. I have come across wanting to
use small words or 1-2 alphabetical characters as custom operators. I
noticed that “as” and “is” are character based operators and figured it
wouldn’t hurt to propose the allowance of character based custom operators.

Here are my reasons for allowing them:

1. easier to read “within” vs “>*<“ or “|*|”

2. potential opportunity to build an educational library to help explain
expressions (see below)

infix operator plus { associativity left precedence 200 }

public func plus (lhs: Int, rhs: Int) -> Int {

    return lhs + rhs

}

let totalApples = 5 plus 5

3. potential to write more like a sentence (this isn’t as high of a need,
but again a good for entry into the language)

postfix operator oz { }
postfix operator cup { }
postfix operator gal { }

public func oz (inout _ lhs: Double) -> Double {

    return lhs

}

public func cup (inout _ lhs: Double) -> Double {

    return lhs *= 8.0

}

public func gal (inout _ lhs: Double) -> Double {

    return lhs *= 128.0

}

let totalLiquidInOunces = 5oz plus 2cup plus 1gal

I spent awhile looking to make sure this hasn’t been proposed before. I
apologize if it is a repeat.

Thanks

 Nerd . Designer . Developer
Jo Albright

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

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


(Jo Albright) #5

Chris - I really appreciate that you take the time to entertain & respond to proposals.

As my obsession grows with custom operators. I have come across wanting to use small words or 1-2 alphabetical characters as custom operators. I noticed that “as” and “is” are character based operators and figured it wouldn’t hurt to propose the allowance of character based custom operators.

Here are my reasons for allowing them:

1. easier to read “within” vs “>*<“ or “|*|”

Check out Replace Logical Operators (&&, ||, etc) with words like "and" and “or":
https://github.com/apple/swift-evolution/blob/master/commonly_proposed.md

I completely agree with that proposal being rejected. I am not asking to replace existing language grammar. My desire is for the support of alphabetical characters for custom operators to allow third party libraries to have their own unique grammar.

There is very small win here of “x foo y” over "x.foo(y)”?

And I completely agree that function/method syntax can easily suffice for normal circumstances. Just trying to see how far Swift can be stretched.

 Nerd . Designer . Developer
Jo Albright

···

On Jan 7, 2016, at 7:24 PM, Chris Lattner <clattner@apple.com> wrote:

On Jan 7, 2016, at 1:31 AM, Jo Albright via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:


(Jo Albright) #6

Answers inline.

 Nerd . Designer . Developer
Jo Albright

Jo, it sounds like you're describing infix functions. If you want to bring up a concrete example, Kotlin has this implementation and it's fantastic for creating your own syntactic sugar.

I am not looking to make the language change. Just want to open up flexibility for naming custom operators.

Currently working on a syntax sugar library for CoreGraphics drawing. Would be nice if I could do something like this :

typealias Point = (x: CGFloat,y: CGFloat)
typealias Curve = (a1: Point, a1: Point, p: Point)

infix operator m { associativity left precedence 200 }
infix operator l { associativity left precedence 200 }
infix operator c { associativity left precedence 200 }
infix operator fill { associativity left precedence 200 }

public func m (lhs: CGContextRef?, rhs: Point) -> CGContextRef? {
    
    CGContextMoveToPoint(lhs, rhs.x, rhs.y); return lhs
    
}

public func l (lhs: CGContextRef?, rhs: Point) -> CGContextRef? {
    
    CGContextAddLineToPoint(lhs, rhs.x, rhs.y); return lhs
    
}

public func c (lhs: CGContextRef?, rhs: Curve) -> CGContextRef? {
    
    CGContextAddCurveToPoint(lhs, rhs.a1.x, rhs.a1.y, rhs.a2.x, rhs.a2.y, rhs.p.x, rhs.p.y); return lhs
    
}

public func fill (lhs: CGContextRef?, rhs: UIColor) {
    
    rhs.set()
    CGContextFillPath(lhs)
    
}

func drawRect(rect: CGRect) {
    
    UIGraphicsGetCurrentContext() m (10,10) l (20,20) fill UIColor.redColor()
    
}

I am also dreaming up a library that is not for app development, but education purposes only. I would love to have the ability to build multiple libraries that are based on different fields (economics, food, sports, etc). These libraries would be written to help students learn to write code with the focus on their favorite activities. This library would be for kids and teens to explore how to write code (possibly even adults that are looking to change fields and trying to get their head around how code works).

Football : (note… just through this together, would be more polished and thought out if it becomes a possibility)

typealias Score = Int
typealias Yardage = Double

struct Team {

  var totalYards = Yardage

}

infix operator gain { associativity left precedence 200 }

public func gain (inout lhs: Team, rhs: Yardage) {
    
    lhs.totalYards += rhs
    
}

func runPlay() {
    
    offense gain 12
    
}

In a discussion about adding $ to the operator character set (it currently is an identifier character), Chris said that any token must be unambiguously either an identifier or an operator even before operators are "discovered", and that's why the identifier character sets and operator character sets have no overlap right now.

"as" and "is" are not operators, they're keywords that were hard-coded into the grammar.

I believe having them on the operator page is confusing then. Maybe there should be an explanation on there that they are not actually operators, but just work like them… thoughts?
...
Closed range
None
Range, 135
is
Type check
Left associative
Cast, 132
as, as?, and as!
Type cast
Left associative
Cast, 132
??
Nil Coalescing
Right associative
Nil Coalescing, 131

···

On Jan 7, 2016, at 11:53 AM, Dennis Lysenko <dennis.s.lysenko@gmail.com> wrote:
On Thu, Jan 7, 2016, 11:31 AM Félix Cloutier <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

Félix

Le 7 janv. 2016 à 04:31:10, Jo Albright via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> a écrit :

As my obsession grows with custom operators. I have come across wanting to use small words or 1-2 alphabetical characters as custom operators. I noticed that “as” and “is” are character based operators and figured it wouldn’t hurt to propose the allowance of character based custom operators.

Here are my reasons for allowing them:

1. easier to read “within” vs “>*<“ or “|*|”

2. potential opportunity to build an educational library to help explain expressions (see below)

infix operator plus { associativity left precedence 200 }

public func plus (lhs: Int, rhs: Int) -> Int {
    
    return lhs + rhs
    
}

let totalApples = 5 plus 5

3. potential to write more like a sentence (this isn’t as high of a need, but again a good for entry into the language)

postfix operator oz { }
postfix operator cup { }
postfix operator gal { }

public func oz (inout _ lhs: Double) -> Double {
    
    return lhs
    
}

public func cup (inout _ lhs: Double) -> Double {
    
    return lhs *= 8.0
    
}

public func gal (inout _ lhs: Double) -> Double {
    
    return lhs *= 128.0
    
}

let totalLiquidInOunces = 5oz plus 2cup plus 1gal

I spent awhile looking to make sure this hasn’t been proposed before. I apologize if it is a repeat.

Thanks

 Nerd . Designer . Developer
Jo Albright

_______________________________________________
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


(Félix Cloutier) #7

What I meant is that they're not operators in the sense that they are defined in a library. These two keywords may semantically be operators, but they are hardcoded in the language grammar to be recognized as operators. Most operators (+, -, /, %, *, etc) are not. See https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/zzSummaryOfTheGrammar.html#//apple_ref/doc/uid/TP40014097-CH38-ID480

Félix

···

Le 7 janv. 2016 à 14:14:23, Jo Albright <me@jo2.co> a écrit :

Answers inline.

 Nerd . Designer . Developer
Jo Albright

On Jan 7, 2016, at 11:53 AM, Dennis Lysenko <dennis.s.lysenko@gmail.com <mailto:dennis.s.lysenko@gmail.com>> wrote:

Jo, it sounds like you're describing infix functions. If you want to bring up a concrete example, Kotlin has this implementation and it's fantastic for creating your own syntactic sugar.

I am not looking to make the language change. Just want to open up flexibility for naming custom operators.

Currently working on a syntax sugar library for CoreGraphics drawing. Would be nice if I could do something like this :

typealias Point = (x: CGFloat,y: CGFloat)
typealias Curve = (a1: Point, a1: Point, p: Point)

infix operator m { associativity left precedence 200 }
infix operator l { associativity left precedence 200 }
infix operator c { associativity left precedence 200 }
infix operator fill { associativity left precedence 200 }

public func m (lhs: CGContextRef?, rhs: Point) -> CGContextRef? {
    
    CGContextMoveToPoint(lhs, rhs.x, rhs.y); return lhs
    
}

public func l (lhs: CGContextRef?, rhs: Point) -> CGContextRef? {
    
    CGContextAddLineToPoint(lhs, rhs.x, rhs.y); return lhs
    
}

public func c (lhs: CGContextRef?, rhs: Curve) -> CGContextRef? {
    
    CGContextAddCurveToPoint(lhs, rhs.a1.x, rhs.a1.y, rhs.a2.x, rhs.a2.y, rhs.p.x, rhs.p.y); return lhs
    
}

public func fill (lhs: CGContextRef?, rhs: UIColor) {
    
    rhs.set()
    CGContextFillPath(lhs)
    
}

func drawRect(rect: CGRect) {
    
    UIGraphicsGetCurrentContext() m (10,10) l (20,20) fill UIColor.redColor()
    
}

I am also dreaming up a library that is not for app development, but education purposes only. I would love to have the ability to build multiple libraries that are based on different fields (economics, food, sports, etc). These libraries would be written to help students learn to write code with the focus on their favorite activities. This library would be for kids and teens to explore how to write code (possibly even adults that are looking to change fields and trying to get their head around how code works).

Football : (note… just through this together, would be more polished and thought out if it becomes a possibility)

typealias Score = Int
typealias Yardage = Double

struct Team {

  var totalYards = Yardage

}

infix operator gain { associativity left precedence 200 }

public func gain (inout lhs: Team, rhs: Yardage) {
    
    lhs.totalYards += rhs
    
}

func runPlay() {
    
    offense gain 12
    
}

On Thu, Jan 7, 2016, 11:31 AM Félix Cloutier <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
In a discussion about adding $ to the operator character set (it currently is an identifier character), Chris said that any token must be unambiguously either an identifier or an operator even before operators are "discovered", and that's why the identifier character sets and operator character sets have no overlap right now.

"as" and "is" are not operators, they're keywords that were hard-coded into the grammar.

I believe having them on the operator page is confusing then. Maybe there should be an explanation on there that they are not actually operators, but just work like them… thoughts?
...
Closed range
None
Range, 135
is
Type check
Left associative
Cast, 132
as, as?, and as!
Type cast
Left associative
Cast, 132
??
Nil Coalescing
Right associative
Nil Coalescing, 131

Félix

Le 7 janv. 2016 à 04:31:10, Jo Albright via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> a écrit :

As my obsession grows with custom operators. I have come across wanting to use small words or 1-2 alphabetical characters as custom operators. I noticed that “as” and “is” are character based operators and figured it wouldn’t hurt to propose the allowance of character based custom operators.

Here are my reasons for allowing them:

1. easier to read “within” vs “>*<“ or “|*|”

2. potential opportunity to build an educational library to help explain expressions (see below)

infix operator plus { associativity left precedence 200 }

public func plus (lhs: Int, rhs: Int) -> Int {
    
    return lhs + rhs
    
}

let totalApples = 5 plus 5

3. potential to write more like a sentence (this isn’t as high of a need, but again a good for entry into the language)

postfix operator oz { }
postfix operator cup { }
postfix operator gal { }

public func oz (inout _ lhs: Double) -> Double {
    
    return lhs
    
}

public func cup (inout _ lhs: Double) -> Double {
    
    return lhs *= 8.0
    
}

public func gal (inout _ lhs: Double) -> Double {
    
    return lhs *= 128.0
    
}

let totalLiquidInOunces = 5oz plus 2cup plus 1gal

I spent awhile looking to make sure this hasn’t been proposed before. I apologize if it is a repeat.

Thanks

 Nerd . Designer . Developer
Jo Albright

_______________________________________________
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


(Chris Lattner) #8

Hi Jo,

The rationale is the same - the design of Swift really wants operators and identifiers to be partitioned into different namespaces. Violating that would make it impossible to parse a swift file without parsing all of its imports. This is a mistake that C made (you have to parse all the headers a file uses to reliably parse the file) that we don’t want to replicate in Swift.

-Chris

···

On Jan 7, 2016, at 5:26 PM, Jo Albright <me@jo2.co> wrote:

Chris - I really appreciate that you take the time to entertain & respond to proposals.

On Jan 7, 2016, at 7:24 PM, Chris Lattner <clattner@apple.com <mailto:clattner@apple.com>> wrote:

On Jan 7, 2016, at 1:31 AM, Jo Albright via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

As my obsession grows with custom operators. I have come across wanting to use small words or 1-2 alphabetical characters as custom operators. I noticed that “as” and “is” are character based operators and figured it wouldn’t hurt to propose the allowance of character based custom operators.

Here are my reasons for allowing them:

1. easier to read “within” vs “>*<“ or “|*|”

Check out Replace Logical Operators (&&, ||, etc) with words like "and" and “or":
https://github.com/apple/swift-evolution/blob/master/commonly_proposed.md

I completely agree with that proposal being rejected. I am not asking to replace existing language grammar. My desire is for the support of alphabetical characters for custom operators to allow third party libraries to have their own unique grammar.

There is very small win here of “x foo y” over "x.foo(y)”?

And I completely agree that function/method syntax can easily suffice for normal circumstances. Just trying to see how far Swift can be stretched.


(Jacob Bandes-Storch) #9

Some other languages provide special syntax to use a binary function as
infix:

Haskell:
    foo a b -- is equivalent to
    a `foo` b

Mathematica:
    Foo[a, b] (*is equivalent to*)
    a~Foo~b

Jacob

···

On Thu, Jan 7, 2016 at 9:42 PM, Chris Lattner via swift-evolution < swift-evolution@swift.org> wrote:

On Jan 7, 2016, at 5:26 PM, Jo Albright <me@jo2.co> wrote:

Chris - I really appreciate that you take the time to entertain & respond
to proposals.

On Jan 7, 2016, at 7:24 PM, Chris Lattner <clattner@apple.com> wrote:

On Jan 7, 2016, at 1:31 AM, Jo Albright via swift-evolution < > swift-evolution@swift.org> wrote:

As my obsession grows with custom operators. I have come across wanting to
use small words or 1-2 alphabetical characters as custom operators. I
noticed that “as” and “is” are character based operators and figured it
wouldn’t hurt to propose the allowance of character based custom operators.

Here are my reasons for allowing them:

1. easier to read “within” vs “>*<“ or “|*|”

Check out Replace Logical Operators (&&, ||, etc) with words like "and"
and “or":
https://github.com/apple/swift-evolution/blob/master/commonly_proposed.md

I completely agree with that proposal being rejected. I am not asking to
replace existing language grammar. My desire is for the support of
alphabetical characters for custom operators to allow *third party
libraries* to have their own unique grammar.

There is very small win here of “x foo y” over "x.foo(y)”?

And I completely agree that function/method syntax can easily suffice for
normal circumstances. Just trying to see how far Swift can be stretched.

Hi Jo,

The rationale is the same - the design of Swift really wants operators and
identifiers to be partitioned into different namespaces. Violating that
would make it impossible to parse a swift file without parsing all of its
imports. This is a mistake that C made (you have to parse all the headers
a file uses to reliably parse the file) that we don’t want to replicate in
Swift.

-Chris

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


(Jo Albright) #10

The rationale is the same - the design of Swift really wants operators and identifiers to be partitioned into different namespaces. Violating that would make it impossible to parse a swift file without parsing all of its imports. This is a mistake that C made (you have to parse all the headers a file uses to reliably parse the file) that we don’t want to replicate in Swift.

Thanks Chris. I now understand the reasoning for separating the two groups. I don’t have a background in language creation, so whatever I can learn from these email lists is awesome. I have already gained a ton of knowledge following these conversations.

Alternative: Reserve one of the operator characters as an operator introducer. Everything from that character to the next whitespace is an operator name. This would allow non-operator characters in operator names while still preserving the strict operator/identifier separation.

   // • is the operator introducer character
   infix operator •times …
   infix operator •mod …
   x = a •times b •mod 8

Limitations:
You still can't use an unadorned word as an operator name.
You can't use such an operator without whitespace (unlike operators whose names use operator characters only).

Oooooo … that is a very cool alternative Greg. Honestly went into this proposal thinking there was no possibility, but now I have a glimmer of hope.

Using “•” (option + 8 on keyboard) would be great since it is accessible through key combo, but isn’t widely used in normal expressions.

What is needed to prove worth of such a feature to be added?

 Nerd . Designer . Developer
Jo Albright


(Robert Widmann) #11

I’d love to have this specific form of this proposal happen. [Were it not that backticks are for naming things after reserved words!]

···

On Jan 7, 2016, at 10:49 PM, Jacob Bandes-Storch via swift-evolution <swift-evolution@swift.org> wrote:

Some other languages provide special syntax to use a binary function as infix:

Haskell:
    foo a b -- is equivalent to
    a `foo` b

Mathematica:
    Foo[a, b] (*is equivalent to*)
    a~Foo~b

Jacob

On Thu, Jan 7, 2016 at 9:42 PM, Chris Lattner via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

On Jan 7, 2016, at 5:26 PM, Jo Albright <me@jo2.co <mailto:me@jo2.co>> wrote:

Chris - I really appreciate that you take the time to entertain & respond to proposals.

On Jan 7, 2016, at 7:24 PM, Chris Lattner <clattner@apple.com <mailto:clattner@apple.com>> wrote:

On Jan 7, 2016, at 1:31 AM, Jo Albright via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

As my obsession grows with custom operators. I have come across wanting to use small words or 1-2 alphabetical characters as custom operators. I noticed that “as” and “is” are character based operators and figured it wouldn’t hurt to propose the allowance of character based custom operators.

Here are my reasons for allowing them:

1. easier to read “within” vs “>*<“ or “|*|”

Check out Replace Logical Operators (&&, ||, etc) with words like "and" and “or":
https://github.com/apple/swift-evolution/blob/master/commonly_proposed.md

I completely agree with that proposal being rejected. I am not asking to replace existing language grammar. My desire is for the support of alphabetical characters for custom operators to allow third party libraries to have their own unique grammar.

There is very small win here of “x foo y” over "x.foo(y)”?

And I completely agree that function/method syntax can easily suffice for normal circumstances. Just trying to see how far Swift can be stretched.

Hi Jo,

The rationale is the same - the design of Swift really wants operators and identifiers to be partitioned into different namespaces. Violating that would make it impossible to parse a swift file without parsing all of its imports. This is a mistake that C made (you have to parse all the headers a file uses to reliably parse the file) that we don’t want to replicate in Swift.

-Chris

_______________________________________________
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
https://lists.swift.org/mailman/listinfo/swift-evolution


(Greg Parker) #12

Swift's features make that solution trickier: free functions versus methods; named parameters.

Alternative: Reserve one of the operator characters as an operator introducer. Everything from that character to the next whitespace is an operator name. This would allow non-operator characters in operator names while still preserving the strict operator/identifier separation.

    // • is the operator introducer character
    infix operator •times …
    infix operator •mod …
    x = a •times b •mod 8

Limitations:
You still can't use an unadorned word as an operator name.
You can't use such an operator without whitespace (unlike operators whose names use operator characters only).

···

On Jan 7, 2016, at 9:49 PM, Jacob Bandes-Storch via swift-evolution <swift-evolution@swift.org> wrote:

Some other languages provide special syntax to use a binary function as infix:

Haskell:
    foo a b -- is equivalent to
    a `foo` b

Mathematica:
    Foo[a, b] (*is equivalent to*)
    a~Foo~b

--
Greg Parker gparker@apple.com Runtime Wrangler


(Jacob Bandes-Storch) #13

I'd be hesitant to support something like this. • is a very natural choice
for a binary operator by itself, and restricting it to require the use of
spaces seems unfortunate.

Re: free functions vs. methods: why does this matter? Supposing `foo` were
the syntax (bad choice, because it already has another meaning, but bear
with me), then you could disambiguate "a `foo` b" vs "a `self.foo` b" just
as you can with regular function calls.

Re: named parameters: there are two clear choices:
- Restrict such a syntax to functions without named parameters (seems
acceptable to me).
- Ignore parameter names, allowing any binary function to be used
(challenges with disambiguation, which I believe has had some discussion in
the other thread about function names).

This might be a crazy idea, but is it possible to support "a myfunc b"
without any extra delimiters? As far as I can tell, there's currently no
way this could parse as a valid expression, so there's no ambiguity to
resolve, although I imagine it would be hard to make diagnostics work well.
I'm not sure how this would play with precedence, but that hasn't been
discussed for any of the other solutions either.

Jacob Bandes-Storch

···

On Fri, Jan 8, 2016 at 12:29 AM, Jo Albright via swift-evolution < swift-evolution@swift.org> wrote:

The rationale is the same - the design of Swift really wants operators and
identifiers to be partitioned into different namespaces. Violating that
would make it impossible to parse a swift file without parsing all of its
imports. This is a mistake that C made (you have to parse all the headers
a file uses to reliably parse the file) that we don’t want to replicate in
Swift.

Thanks Chris. I now understand the reasoning for separating the two
groups. I don’t have a background in language creation, so whatever I can
learn from these email lists is awesome. I have already gained a ton of
knowledge following these conversations.

Alternative: Reserve one of the operator characters as an operator
introducer. Everything from that character to the next whitespace is an
operator name. This would allow non-operator characters in operator names
while still preserving the strict operator/identifier separation.

   // • is the operator introducer character
   infix operator •times …
   infix operator •mod …
   x = a •times b •mod 8

Limitations:
You still can't use an unadorned word as an operator name.
You can't use such an operator without whitespace (unlike operators whose
names use operator characters only).

Oooooo … that is a very cool alternative Greg. Honestly went into this
proposal thinking there was no possibility, but now I have a glimmer of
hope.

Using “•” (option + 8 on keyboard) would be great since it is accessible
through key combo, but isn’t widely used in normal expressions.

What is needed to prove worth of such a feature to be added?

 Nerd . Designer . Developer
Jo Albright

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


(Chris Lattner) #14

Ok, then yes, introducing a magic syntax would be technically feasible (though not backticks, since they are used for something else).

This is still extremely unlikely to be accepted though. Additional language complexity needs to pay for itself, and the win here is so small that it doesn’t seem worth it.

-Chris

···

On Jan 7, 2016, at 9:49 PM, Jacob Bandes-Storch <jtbandes@gmail.com> wrote:

Some other languages provide special syntax to use a binary function as infix:

Haskell:
    foo a b -- is equivalent to
    a `foo` b

Mathematica:
    Foo[a, b] (*is equivalent to*)
    a~Foo~b


(Joe Groff) #15

Some other languages provide special syntax to use a binary function as infix:

Haskell:
    foo a b -- is equivalent to
    a `foo` b

Mathematica:
    Foo[a, b] (*is equivalent to*)
    a~Foo~b

You could implement the Mathematica one yourself:

operator infix ~ { associativity left }

struct Section<T, U, V> { var lhs: T, op: (T,U) -> V }

func ~<T, U, V>(lhs: T, op: (T, U) -> V) -> Section<T,U,V> {
  return Section(lhs: lhs, op: op)
}

func ~<T, U, V>(section: Section<T, U, V>, rhs: U) -> V {
  return section.op(section.lhs, rhs)
}

though I don't really see how x `foo` y is a real improvement over x.foo(y).

-Joe

···

On Jan 7, 2016, at 9:49 PM, Jacob Bandes-Storch via swift-evolution <swift-evolution@swift.org> wrote:

Jacob

On Thu, Jan 7, 2016 at 9:42 PM, Chris Lattner via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

On Jan 7, 2016, at 5:26 PM, Jo Albright <me@jo2.co <mailto:me@jo2.co>> wrote:

Chris - I really appreciate that you take the time to entertain & respond to proposals.

On Jan 7, 2016, at 7:24 PM, Chris Lattner <clattner@apple.com <mailto:clattner@apple.com>> wrote:

On Jan 7, 2016, at 1:31 AM, Jo Albright via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

As my obsession grows with custom operators. I have come across wanting to use small words or 1-2 alphabetical characters as custom operators. I noticed that “as” and “is” are character based operators and figured it wouldn’t hurt to propose the allowance of character based custom operators.

Here are my reasons for allowing them:

1. easier to read “within” vs “>*<“ or “|*|”

Check out Replace Logical Operators (&&, ||, etc) with words like "and" and “or":
https://github.com/apple/swift-evolution/blob/master/commonly_proposed.md

I completely agree with that proposal being rejected. I am not asking to replace existing language grammar. My desire is for the support of alphabetical characters for custom operators to allow third party libraries to have their own unique grammar.

There is very small win here of “x foo y” over "x.foo(y)”?

And I completely agree that function/method syntax can easily suffice for normal circumstances. Just trying to see how far Swift can be stretched.

Hi Jo,

The rationale is the same - the design of Swift really wants operators and identifiers to be partitioned into different namespaces. Violating that would make it impossible to parse a swift file without parsing all of its imports. This is a mistake that C made (you have to parse all the headers a file uses to reliably parse the file) that we don’t want to replicate in Swift.

-Chris

_______________________________________________
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


(Thorsten Seitz) #16

I'd be hesitant to support something like this. • is a very natural choice for a binary operator by itself, and restricting it to require the use of spaces seems unfortunate.

What about if • would have to begin and end an operator containing letters?

x = a •times• b •mod• 8

This looks more symmetrically (like Haskell’s backticks) and wouldn’t need the restriction to require spaces.

Or maybe

x = a ‹times› b ‹mod› 8

Also easily typeable on a Mac keyboard.

Re: free functions vs. methods: why does this matter? Supposing `foo` were the syntax (bad choice, because it already has another meaning, but bear with me), then you could disambiguate "a `foo` b" vs "a `self.foo` b" just as you can with regular function calls.

Indeed.

-Thorsten

···

Am 08.01.2016 um 09:38 schrieb Jacob Bandes-Storch via swift-evolution <swift-evolution@swift.org>:

Re: named parameters: there are two clear choices:
- Restrict such a syntax to functions without named parameters (seems acceptable to me).
- Ignore parameter names, allowing any binary function to be used (challenges with disambiguation, which I believe has had some discussion in the other thread about function names).

This might be a crazy idea, but is it possible to support "a myfunc b" without any extra delimiters? As far as I can tell, there's currently no way this could parse as a valid expression, so there's no ambiguity to resolve, although I imagine it would be hard to make diagnostics work well. I'm not sure how this would play with precedence, but that hasn't been discussed for any of the other solutions either.

Jacob Bandes-Storch

On Fri, Jan 8, 2016 at 12:29 AM, Jo Albright via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

The rationale is the same - the design of Swift really wants operators and identifiers to be partitioned into different namespaces. Violating that would make it impossible to parse a swift file without parsing all of its imports. This is a mistake that C made (you have to parse all the headers a file uses to reliably parse the file) that we don’t want to replicate in Swift.

Thanks Chris. I now understand the reasoning for separating the two groups. I don’t have a background in language creation, so whatever I can learn from these email lists is awesome. I have already gained a ton of knowledge following these conversations.

Alternative: Reserve one of the operator characters as an operator introducer. Everything from that character to the next whitespace is an operator name. This would allow non-operator characters in operator names while still preserving the strict operator/identifier separation.

   // • is the operator introducer character
   infix operator •times …
   infix operator •mod …
   x = a •times b •mod 8

Limitations:
You still can't use an unadorned word as an operator name.
You can't use such an operator without whitespace (unlike operators whose names use operator characters only).

Oooooo … that is a very cool alternative Greg. Honestly went into this proposal thinking there was no possibility, but now I have a glimmer of hope.

Using “•” (option + 8 on keyboard) would be great since it is accessible through key combo, but isn’t widely used in normal expressions.

What is needed to prove worth of such a feature to be added?

 Nerd . Designer . Developer
Jo Albright

_______________________________________________
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


(Jo Albright) #17

I promise, this is my last idea to be thrown at this. Instead of characters in operators...

Would the core team be open to having an operatoralias keyword that allows an operator to be masked by an identifier.

Learning & Teaching Example :

operatoralias plus = +

let apples = 5 + 5
let apples = 5 plus 5

With extension :

let apples = 5 . plus ( 5 )

···

---------------------------------------------------------------------------------

Learning & Teaching Example :

operatoralias incrementedBy = +=

updatedValue += 10
updatedValue incrementedBy 10

With extension :

updatedValue . incrementedBy ( 10 )

---------------------------------------------------------------------------------

Readability & Code Reduction Example :

typealias Point = (x: CGFloat,y: CGFloat)

infix operator >>>> { }

func >>>> (lhs: CGContextRef?, rhs: Point) -> CGContextRef? {
    
    CGContextMoveToPoint(lhs, rhs.x, rhs.y); return lhs
    
}

operatoralias moveTo = >>>> // operator alias for custom operator

let context = UIGraphicsGetCurrentContext()

context moveTo (10,10) addLineTo (20,20) strokeWith UIColor.redColor()

Or if SVG letters used (less readable, but also less footprint) :

context M (10,10) L (20,20) stroke UIColor.redColor()

I know this looks a lot like a chained method and very close to the same amount of code to be written… however it is slightly easier to read without all of the function punctuation in between :

context.moveTo(10,10)?.addLineTo(20,20)?.strokeWith.(UIColor.redColor())

I believe there is an opportunity here that won’t truly be appreciated until it is in use. But will not argue that it is very close to what is currently available and does not have a huge impact in the current vision of things.

Thanks for humoring my imagination. :slight_smile:

 Nerd . Designer . Developer
Jo Albright

On Jan 8, 2016, at 2:26 PM, Chris Lattner <clattner@apple.com> wrote:

On Jan 7, 2016, at 9:49 PM, Jacob Bandes-Storch <jtbandes@gmail.com> wrote:

Some other languages provide special syntax to use a binary function as infix:

Haskell:
   foo a b -- is equivalent to
   a `foo` b

Mathematica:
   Foo[a, b] (*is equivalent to*)
   a~Foo~b

Ok, then yes, introducing a magic syntax would be technically feasible (though not backticks, since they are used for something else).

This is still extremely unlikely to be accepted though. Additional language complexity needs to pay for itself, and the win here is so small that it doesn’t seem worth it.

-Chris


(David Sweeris) #18

• is the dot product operator.

···

Sent from my iPhone

On Mar 28, 2016, at 10:21, Thorsten Seitz via swift-evolution <swift-evolution@swift.org> wrote:

Am 08.01.2016 um 09:38 schrieb Jacob Bandes-Storch via swift-evolution <swift-evolution@swift.org>:

I'd be hesitant to support something like this. • is a very natural choice for a binary operator by itself, and restricting it to require the use of spaces seems unfortunate.

What about if • would have to begin and end an operator containing letters?

x = a •times• b •mod• 8

This looks more symmetrically (like Haskell’s backticks) and wouldn’t need the restriction to require spaces.

Or maybe

x = a ‹times› b ‹mod› 8

Also easily typeable on a Mac keyboard.

Re: free functions vs. methods: why does this matter? Supposing `foo` were the syntax (bad choice, because it already has another meaning, but bear with me), then you could disambiguate "a `foo` b" vs "a `self.foo` b" just as you can with regular function calls.

Indeed.

-Thorsten

Re: named parameters: there are two clear choices:
- Restrict such a syntax to functions without named parameters (seems acceptable to me).
- Ignore parameter names, allowing any binary function to be used (challenges with disambiguation, which I believe has had some discussion in the other thread about function names).

This might be a crazy idea, but is it possible to support "a myfunc b" without any extra delimiters? As far as I can tell, there's currently no way this could parse as a valid expression, so there's no ambiguity to resolve, although I imagine it would be hard to make diagnostics work well. I'm not sure how this would play with precedence, but that hasn't been discussed for any of the other solutions either.

Jacob Bandes-Storch

On Fri, Jan 8, 2016 at 12:29 AM, Jo Albright via swift-evolution <swift-evolution@swift.org> wrote:

The rationale is the same - the design of Swift really wants operators and identifiers to be partitioned into different namespaces. Violating that would make it impossible to parse a swift file without parsing all of its imports. This is a mistake that C made (you have to parse all the headers a file uses to reliably parse the file) that we don’t want to replicate in Swift.

Thanks Chris. I now understand the reasoning for separating the two groups. I don’t have a background in language creation, so whatever I can learn from these email lists is awesome. I have already gained a ton of knowledge following these conversations.

Alternative: Reserve one of the operator characters as an operator introducer. Everything from that character to the next whitespace is an operator name. This would allow non-operator characters in operator names while still preserving the strict operator/identifier separation.

   // • is the operator introducer character
   infix operator •times …
   infix operator •mod …
   x = a •times b •mod 8

Limitations:
You still can't use an unadorned word as an operator name.
You can't use such an operator without whitespace (unlike operators whose names use operator characters only).

Oooooo … that is a very cool alternative Greg. Honestly went into this proposal thinking there was no possibility, but now I have a glimmer of hope.

Using “•” (option + 8 on keyboard) would be great since it is accessible through key combo, but isn’t widely used in normal expressions.

What is needed to prove worth of such a feature to be added?

 Nerd . Designer . Developer
Jo Albright

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

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

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


(Erica Sadun) #19

It's been pointed out to me that while this is true in the US, it is not so true on other keyboard layouts.

-- E

···

On Mar 28, 2016, at 9:21 AM, Thorsten Seitz via swift-evolution <swift-evolution@swift.org> wrote:

Also easily typeable on a Mac keyboard.


(Haravikk) #20

Personally I prefer the requirement of spaces; if you require a method to have textual operators without spaces then IMO it’s probably not a good place to use a textual operator in the first place.

I like the space requirement as it essentially lets textual operators be custom keywords, for example the recent thread on striding for loops, we could do the following:

  for eachIndex in 1 ..< 10 by 2 { … }

With the “by” defined as a custom operator on Range, rather than defining a new keyword or for loop variant (since it’s still essentially a for in loop). It’s really just a nicer alternative to: (1 ..< 10).by(2).

···

On 28 Mar 2016, at 16:21, Thorsten Seitz via swift-evolution <swift-evolution@swift.org> wrote:

Am 08.01.2016 um 09:38 schrieb Jacob Bandes-Storch via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>>:

I'd be hesitant to support something like this. • is a very natural choice for a binary operator by itself, and restricting it to require the use of spaces seems unfortunate.

What about if • would have to begin and end an operator containing letters?

x = a •times• b •mod• 8

This looks more symmetrically (like Haskell’s backticks) and wouldn’t need the restriction to require spaces.

Or maybe

x = a ‹times› b ‹mod› 8

Also easily typeable on a Mac keyboard.

Re: free functions vs. methods: why does this matter? Supposing `foo` were the syntax (bad choice, because it already has another meaning, but bear with me), then you could disambiguate "a `foo` b" vs "a `self.foo` b" just as you can with regular function calls.

Indeed.

-Thorsten

Re: named parameters: there are two clear choices:
- Restrict such a syntax to functions without named parameters (seems acceptable to me).
- Ignore parameter names, allowing any binary function to be used (challenges with disambiguation, which I believe has had some discussion in the other thread about function names).

This might be a crazy idea, but is it possible to support "a myfunc b" without any extra delimiters? As far as I can tell, there's currently no way this could parse as a valid expression, so there's no ambiguity to resolve, although I imagine it would be hard to make diagnostics work well. I'm not sure how this would play with precedence, but that hasn't been discussed for any of the other solutions either.

Jacob Bandes-Storch

On Fri, Jan 8, 2016 at 12:29 AM, Jo Albright via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

The rationale is the same - the design of Swift really wants operators and identifiers to be partitioned into different namespaces. Violating that would make it impossible to parse a swift file without parsing all of its imports. This is a mistake that C made (you have to parse all the headers a file uses to reliably parse the file) that we don’t want to replicate in Swift.

Thanks Chris. I now understand the reasoning for separating the two groups. I don’t have a background in language creation, so whatever I can learn from these email lists is awesome. I have already gained a ton of knowledge following these conversations.

Alternative: Reserve one of the operator characters as an operator introducer. Everything from that character to the next whitespace is an operator name. This would allow non-operator characters in operator names while still preserving the strict operator/identifier separation.

   // • is the operator introducer character
   infix operator •times …
   infix operator •mod …
   x = a •times b •mod 8

Limitations:
You still can't use an unadorned word as an operator name.
You can't use such an operator without whitespace (unlike operators whose names use operator characters only).

Oooooo … that is a very cool alternative Greg. Honestly went into this proposal thinking there was no possibility, but now I have a glimmer of hope.

Using “•” (option + 8 on keyboard) would be great since it is accessible through key combo, but isn’t widely used in normal expressions.

What is needed to prove worth of such a feature to be added?

 Nerd . Designer . Developer
Jo Albright

_______________________________________________
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
https://lists.swift.org/mailman/listinfo/swift-evolution