Allowing Characters for use as Custom Operators

Jo, maybe it's time to explore infix functions as a potential solution? I
don't see infix functions under the commonly proposed list.

···

On Fri, Jan 8, 2016, 4:28 PM Jo Albright via swift-evolution < swift-evolution@swift.org> wrote:

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. :)

 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

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

Scala allows a method with one argument to be used infix with spaces either
side, this would allow

for index in 1 ..< 10 by 2 { ... }

if Range had a by method.

This feature has proved popular in Scala.

  -- Howard.

···

On 29 March 2016 at 21:37, Haravikk via swift-evolution < swift-evolution@swift.org> wrote:

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>:

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

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

Jo, maybe it's time to explore infix functions as a potential solution? I don't see infix functions under the commonly proposed list.

I just added them. To repeat what has been said several times on this thread, the problem being solved here is not important enough to be worth complicating the language for.

-Chris

···

On Jan 8, 2016, at 2:43 PM, Dennis Lysenko <dennis.s.lysenko@gmail.com> wrote:

On Fri, Jan 8, 2016, 4:28 PM Jo Albright via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
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. :)

 Nerd . Designer . Developer
Jo Albright

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

On Jan 7, 2016, at 9:49 PM, Jacob Bandes-Storch <jtbandes@gmail.com <mailto: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

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

Chris, hmm... Can you really say that this is the only problem that would
warrant infix functions? To say what you just seemingly implies that you
believe the use cases outlined here are the only reason one would want
infix operators, and that the use cases outlined here don't warrant infix
functions.

I'm sure there are plenty more reasons for implementing infix functions and
I think it would be reactionary to effectively discourage their
consideration on the basis of one tangentially related email chain.

···

On Sat, Jan 9, 2016, 1:53 PM Chris Lattner <clattner@apple.com> wrote:

On Jan 8, 2016, at 2:43 PM, Dennis Lysenko <dennis.s.lysenko@gmail.com> > wrote:

Jo, maybe it's time to explore infix functions as a potential solution? I
don't see infix functions under the commonly proposed list.

I just added them. To repeat what has been said several times on this
thread, the problem being solved here is not important enough to be worth
complicating the language for.

-Chris

On Fri, Jan 8, 2016, 4:28 PM Jo Albright via swift-evolution < > swift-evolution@swift.org> wrote:

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. :)

 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

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

I’m saying that I cannot personally imagine a use-case compelling enough to make the language more complicated for (including the ones listed on the thread). If you can, please share them and we can discuss it.

-Chris

···

On Jan 9, 2016, at 11:56 AM, Dennis Lysenko <dennis.s.lysenko@gmail.com> wrote:
Chris, hmm... Can you really say that this is the only problem that would warrant infix functions? To say what you just seemingly implies that you believe the use cases outlined here are the only reason one would want infix operators, and that the use cases outlined here don't warrant infix functions.

I'm sure there are plenty more reasons for implementing infix functions and I think it would be reactionary to effectively discourage their consideration on the basis of one tangentially related email chain.

Maybe this wan't the original idea but I have a proposition that is both parseable and useful

Imagine you have this struct
struct Person {
    let name: String
    let age: Int
}

and you want to use an operator to compare their fields because you do that often.
Typically you would do something along those lines:

func <(lhs: Person, rhs: Person) -> Bool {
    return lhs.age < rhs.age
}

func <<(lhs: Person, rhs: Person) -> Bool {
    return lhs.name < rhs.name
}

and then use it like so

let john = Person(name: "John", age: 12)
let steve = Person(name: "Steve", age: 14)

john < steve
john << steve

The point isn't that "<" and "<<" are bad operators for this purpose but that operators quickly become confusing when abused.
I think one great solution would be to allow alphanumeric character after the operator head like so:

func <age(lhs: Person, rhs: Person) -> Bool {…}

func <name(lhs: Person, rhs: Person) -> Bool {…}

john <age steve
john <name steve

and the grammar would need to be changed to:

operator -> operator-head operator-characters
operator-characters -> operator-characters operator-tail
operator-tail -> operator-characters
operator-tail -> alphanumeric alphanumeric?

or something similar

Extra:
If we extend this idea further we could even imagine nice operators like

john <⎮age⎮ steve
john >⎮name⎮ steve

And I will argue that this is more both readable and desirable than john.compareAge(steve) or john.lessThanAge(steve) even though that's what it years of Obj-C and OOP tells us to do.

···

On 10 Jan 2016, at 02:23, Chris Lattner via swift-evolution <swift-evolution@swift.org> wrote:

On Jan 9, 2016, at 11:56 AM, Dennis Lysenko <dennis.s.lysenko@gmail.com <mailto:dennis.s.lysenko@gmail.com>> wrote:
Chris, hmm... Can you really say that this is the only problem that would warrant infix functions? To say what you just seemingly implies that you believe the use cases outlined here are the only reason one would want infix operators, and that the use cases outlined here don't warrant infix functions.

I'm sure there are plenty more reasons for implementing infix functions and I think it would be reactionary to effectively discourage their consideration on the basis of one tangentially related email chain.

I’m saying that I cannot personally imagine a use-case compelling enough to make the language more complicated for (including the ones listed on the thread). If you can, please share them and we can discuss it.

-Chris

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

Chris, perhaps there is a disconnect in our perceptions of the commonly
proposed list. Based on the way you and others have referenced the commonly
proposed list, it comes off as a blacklist of sorts. That is, "it's on the
commonly proposed list" seems to be seen as an argument against a proposal.
I only worry that the mere presence of something on the commonly proposed
list will serve as a deterrent to legitimate proposals involving it in the
future.

If you have taken that into consideration when deciding to place infix
functions on the commonly proposed list then fair enough. I just feel that
infix functions have not been discussed nearly as much as, say,
"indentation over brace syntax" or "getting rid of ternary", and it's a bit
preemptive to put such a dent in potential future discussion because you
personally cannot imagine a use case warranting the language change.

Out of curiosity, has there even been a top-level proposal for infix
functions that generated significant discussion?

···

On Sat, Jan 9, 2016 at 5:23 PM Chris Lattner <clattner@apple.com> wrote:

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

Chris, hmm... Can you really say that this is the only problem that would
warrant infix functions? To say what you just seemingly implies that you
believe the use cases outlined here are the only reason one would want
infix operators, and that the use cases outlined here don't warrant infix
functions.

I'm sure there are plenty more reasons for implementing infix functions
and I think it would be reactionary to effectively discourage their
consideration on the basis of one tangentially related email chain.

I’m saying that I cannot personally imagine a use-case compelling enough
to make the language more complicated for (including the ones listed on the
thread). If you can, please share them and we can discuss it.

-Chris

Chris, perhaps there is a disconnect in our perceptions of the commonly proposed list. Based on the way you and others have referenced the commonly proposed list, it comes off as a blacklist of sorts. That is, "it's on the commonly proposed list" seems to be seen as an argument against a proposal. I only worry that the mere presence of something on the commonly proposed list will serve as a deterrent to legitimate proposals involving it in the future.

Hi Dennis,

I’m sorry for the confusion on this. The very first paragraph of that page says:

… If you're interested in pursuing something in this space, please familiarize yourself with the discussions that we have already had. In order to bring one of these topics up, you'll be expected to add new information to the discussion, not just say "I really want this" or "This exists in some other language and I liked it there".

The intention is to avoid re-treading old ground, not to say that something is impossible.

If you have taken that into consideration when deciding to place infix functions on the commonly proposed list then fair enough. I just feel that infix functions have not been discussed nearly as much as, say, "indentation over brace syntax" or "getting rid of ternary", and it's a bit preemptive to put such a dent in potential future discussion because you personally cannot imagine a use case warranting the language change.

Out of curiosity, has there even been a top-level proposal for infix functions that generated significant discussion?

Yes, it has come up several times in different contexts. The advantage of “x foo bar” (potentially with sigils around foo) over “x.foo(bar)” has consistently been seen as not worth adding complexity for. Perhaps you are thinking of something else?

-Chris

···

On Jan 9, 2016, at 7:50 PM, Dennis Lysenko <dennis.s.lysenko@gmail.com> wrote:

Sorry Chris, seems as though I misinterpreted. I guess I was arguing the
principle more than the specific example here; apologies if I derailed the
thread a bit. At the risk of derailing the thread further, since I still
have your attention and am not sure where else to raise such a suggestion:
have you or other members of the Swift team considered talking to the team
behind Kotlin? Kotlin has been loosely touted as "Swift for the
JVM/android" and may share some motivation with Swift--modern functionality
and interoperability with a very well-known, older language. In spite of
how much the two languages differ in key areas, maybe the two teams could
share and discuss motivation behind previous language decisions. Not sure
if there is a precedent for that kind of interaction so feel free to
disregard.

···

On Sun, Jan 10, 2016, 12:30 AM Chris Lattner <clattner@apple.com> wrote:

On Jan 9, 2016, at 7:50 PM, Dennis Lysenko <dennis.s.lysenko@gmail.com> > wrote:

Chris, perhaps there is a disconnect in our perceptions of the commonly
proposed list. Based on the way you and others have referenced the commonly
proposed list, it comes off as a blacklist of sorts. That is, "it's on the
commonly proposed list" seems to be seen as an argument against a proposal.
I only worry that the mere presence of something on the commonly proposed
list will serve as a deterrent to legitimate proposals involving it in the
future.

Hi Dennis,

I’m sorry for the confusion on this. The very first paragraph of that
page says:

… If you're interested in pursuing something in this space, please
familiarize yourself with the discussions that we have already had. In
order to bring one of these topics up, you'll be expected to add new
information to the discussion, not just say "I really want this" or "This
exists in some other language and I liked it there".

The intention is to avoid re-treading old ground, not to say that
something is impossible.

If you have taken that into consideration when deciding to place infix
functions on the commonly proposed list then fair enough. I just feel that
infix functions have not been discussed nearly as much as, say,
"indentation over brace syntax" or "getting rid of ternary", and it's a bit
preemptive to put such a dent in potential future discussion because you
personally cannot imagine a use case warranting the language change.

Out of curiosity, has there even been a top-level proposal for infix
functions that generated significant discussion?

Yes, it has come up several times in different contexts. The advantage of
“x foo bar” (potentially with sigils around foo) over “x.foo(bar)” has
consistently been seen as not worth adding complexity for. Perhaps you are
thinking of something else?

-Chris