Generic Alaises


(James Campbell) #1

This was inspired from the topic about moving where clauses out of
parameter lists.

Certain generics get very long winded, I was wondering if we could create
some sort of alias for generics.

func anyCommonElements <T: SequenceType, U: SequenceType where
T.Generator.Element: Equatable, T.Generator.Element == U.Generator.Element>
(lhs: T, _ rhs: U) -> Bool

could be shared across functions like so:

genericalias SequencesWithSameElements<T, U> = <T: SequenceType, U:
SequenceType where T.Generator.Element: Equatable, T.Generator.Element ==
U.Generator.Element>

func anyCommonElements <SequencesWithSameElements> (lhs: T, _ rhs: U) ->
Bool
func == <SequencesWithSameElements> (lhs: T, _ rhs: U) -> Bool

···

*___________________________________*

*James⎥*

*james@supmenow.com <james@supmenow.com>⎥supmenow.com <http://supmenow.com>*

*Sup*

*Runway East *

*10 Finsbury Square*

*London*

* EC2A 1AF *


(Milos Rankovic) #2

Chris Lattner has a proposal under review <https://github.com/apple/swift-evolution/blob/master/proposals/0048-generic-typealias.md> on this topic.

milos

···

On 6 Apr 2016, at 20:41, James Campbell via swift-evolution <swift-evolution@swift.org> wrote:

This was inspired from the topic about moving where clauses out of parameter lists.

Certain generics get very long winded, I was wondering if we could create some sort of alias for generics.

func anyCommonElements <T: SequenceType, U: SequenceType where T.Generator.Element: Equatable, T.Generator.Element == U.Generator.Element> (lhs: T, _ rhs: U) -> Bool

could be shared across functions like so:

genericalias SequencesWithSameElements<T, U> = <T: SequenceType, U: SequenceType where T.Generator.Element: Equatable, T.Generator.Element == U.Generator.Element>

func anyCommonElements <SequencesWithSameElements> (lhs: T, _ rhs: U) -> Bool
func == <SequencesWithSameElements> (lhs: T, _ rhs: U) -> Bool
___________________________________

James⎥

james@supmenow.com <mailto:james@supmenow.com>⎥supmenow.com <http://supmenow.com/>
Sup

Runway East >

10 Finsbury Square

London

> EC2A 1AF

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


(Ross O'Brien) #3

It's not the same topic. Let's take an example: suppose we have a data
structure for a graph of nodes and edges, where the nodes and edges are
indexed and both have values. So we have a Graph<NodeIndex : Hashable,
EdgeIndex : Hashable, NodeValue, EdgeValue>.
Now suppose we want a shortest path from one node to another, and we have a
data structure to represent that. Now we have a Path<NodeIndex : Hashable,
EdgeIndex : Hashable, NodeValue, EdgeValue>. They both have the same
'generic signature'. If you're navigating a Graph<String, Int, City,

, you're going to want a Path<String, Int, City, Motorway> as

output.

Right now you might write that as:
func shortestPath<NodeIndex, EdgeIndex, NodeValue,

(graph:Graph<NodeIndex, EdgeIndex, NodeValue, EdgeValue>,

startNode: NodeIndex, endNode: NodeIndex> -> Path<NodeIndex, EdgeIndex,
NodeValue, EdgeValue>

It might save a fair amount of typing if we had a generic equivalent to
both typealias and associatedtype.

associatedgenerics GraphElements = <NodeIndex : Hashable, EdgeIndex :
Hashable, NodeValue, EdgeValue>
func shortestPath<GraphElements>(graph: Graph<GraphElements>,
startNode<GraphElements.NodeIndex>, endNode<GraphElements.NodeIndex>) ->
Path<GraphElements>

genericalias NavigationGraphElements = GraphElements<String, Int, City,

typealias NavigationGraph = Graph<NavigationGraphElements>
// navigationGraph.shortestPath() now returns a
Path<NavigationGraphElements>
// this last part is closest to the proposal under review.

···

On Wed, Apr 6, 2016 at 9:05 PM, Milos Rankovic via swift-evolution < swift-evolution@swift.org> wrote:

Chris Lattner has a proposal under review
<https://github.com/apple/swift-evolution/blob/master/proposals/0048-generic-typealias.md> on
this topic.

milos

On 6 Apr 2016, at 20:41, James Campbell via swift-evolution < > swift-evolution@swift.org> wrote:

This was inspired from the topic about moving where clauses out of
parameter lists.

Certain generics get very long winded, I was wondering if we could create
some sort of alias for generics.

func anyCommonElements <T: SequenceType, U: SequenceType where
T.Generator.Element: Equatable, T.Generator.Element == U.Generator.Element>
(lhs: T, _ rhs: U) -> Bool

could be shared across functions like so:

genericalias SequencesWithSameElements<T, U> = <T: SequenceType, U:
SequenceType where T.Generator.Element: Equatable, T.Generator.Element ==
U.Generator.Element>

func anyCommonElements <SequencesWithSameElements> (lhs: T, _ rhs: U) ->
Bool
func == <SequencesWithSameElements> (lhs: T, _ rhs: U) -> Bool

*___________________________________*

*James⎥*

*james@supmenow.com <james@supmenow.com>⎥supmenow.com
<http://supmenow.com/>*

*Sup*

*Runway East *

*10 Finsbury Square*

*London*

* EC2A 1AF *
_______________________________________________
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


(James Campbell) #4

Ross put it better than I ever could :slight_smile: yes this is what I meant

···

Sent from Supmenow.com

On Wed, Apr 6, 2016 at 1:45 PM -0700, "Ross O'Brien" <narrativium+swift@gmail.com> wrote:

It's not the same topic. Let's take an example: suppose we have a data structure for a graph of nodes and edges, where the nodes and edges are indexed and both have values. So we have a Graph<NodeIndex : Hashable, EdgeIndex : Hashable, NodeValue, EdgeValue>.Now suppose we want a shortest path from one node to another, and we have a data structure to represent that. Now we have a Path<NodeIndex : Hashable, EdgeIndex : Hashable, NodeValue, EdgeValue>. They both have the same 'generic signature'. If you're navigating a Graph<String, Int, City, Motorway>, you're going to want a Path<String, Int, City, Motorway> as output.
Right now you might write that as:func shortestPath<NodeIndex, EdgeIndex, NodeValue, EdgeValue>(graph:Graph<NodeIndex, EdgeIndex, NodeValue, EdgeValue>, startNode: NodeIndex, endNode: NodeIndex> -> Path<NodeIndex, EdgeIndex, NodeValue, EdgeValue>
It might save a fair amount of typing if we had a generic equivalent to both typealias and associatedtype.
associatedgenerics GraphElements = <NodeIndex : Hashable, EdgeIndex : Hashable, NodeValue, EdgeValue>func shortestPath<GraphElements>(graph: Graph<GraphElements>, startNode<GraphElements.NodeIndex>, endNode<GraphElements.NodeIndex>) -> Path<GraphElements>
genericalias NavigationGraphElements = GraphElements<String, Int, City, Motorway>
typealias NavigationGraph = Graph<NavigationGraphElements>// navigationGraph.shortestPath() now returns a Path<NavigationGraphElements>// this last part is closest to the proposal under review.

On Wed, Apr 6, 2016 at 9:05 PM, Milos Rankovic via swift-evolution <swift-evolution@swift.org> wrote:
Chris Lattner has a proposal under review on this topic.
milos

On 6 Apr 2016, at 20:41, James Campbell via swift-evolution <swift-evolution@swift.org> wrote:
This was inspired from the topic about moving where clauses out of parameter lists.
Certain generics get very long winded, I was wondering if we could create some sort of alias for generics.
func anyCommonElements <T: SequenceType, U: SequenceType where T.Generator.Element: Equatable, T.Generator.Element == U.Generator.Element> (lhs: T, _ rhs: U) -> Bool

could be shared across functions like so:
genericalias SequencesWithSameElements<T, U> = <T: SequenceType, U: SequenceType where T.Generator.Element: Equatable, T.Generator.Element == U.Generator.Element>
func anyCommonElements <SequencesWithSameElements> (lhs: T, _ rhs: U) -> Bool
func == <SequencesWithSameElements> (lhs: T, _ rhs: U) -> Bool

___________________________________

James⎥

james@supmenow.com⎥supmenow.com

Sup

Runway East

10 Finsbury Square

London

EC2A 1AF

_______________________________________________
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


(Milos Rankovic) #5

Hi Ross,

That was a hell of an example! However, even with the types as they are now, the code needn’t look so dreadful. With following protocols in place:

protocol Indexed {
  associatedtype Index : Hashable
  var index: Index { get }
}

protocol NodeType : Indexed { }
protocol EdgeType: Indexed { }

protocol GraphType {
  associatedtype Node : NodeType
  associatedtype Edge : EdgeType
  
  var nodes: [Node] { get }
  var edges: [Edge] { get }
}

We can define `Graph` and `Path` as:

struct Graph<Node:NodeType, Edge:EdgeType> : GraphType {
  let nodes: [Node] = [] // todo
  let edges: [Edge] = [] // todo
}

struct Path<Node:NodeType, Edge:EdgeType> {}

So the function with the endless signature you’ve got would become:

extension Graph {
  func shortestPath(from from: Node, to: Node) -> Path<Node, Edge> {
    fatalError("todo")
  }
}

As for my link to Chris’s proposal, all I meant is to point out that there is a proposal under review with an identical name as this thread. I certainly did not mean to discourage discussion James started!

milos

···

On 6 Apr 2016, at 21:45, Ross O'Brien <narrativium+swift@gmail.com> wrote:

It's not the same topic. Let's take an example: suppose we have a data structure for a graph of nodes and edges, where the nodes and edges are indexed and both have values. So we have a Graph<NodeIndex : Hashable, EdgeIndex : Hashable, NodeValue, EdgeValue>.
Now suppose we want a shortest path from one node to another, and we have a data structure to represent that. Now we have a Path<NodeIndex : Hashable, EdgeIndex : Hashable, NodeValue, EdgeValue>. They both have the same 'generic signature'. If you're navigating a Graph<String, Int, City, Motorway>, you're going to want a Path<String, Int, City, Motorway> as output.

Right now you might write that as:
func shortestPath<NodeIndex, EdgeIndex, NodeValue, EdgeValue>(graph:Graph<NodeIndex, EdgeIndex, NodeValue, EdgeValue>, startNode: NodeIndex, endNode: NodeIndex> -> Path<NodeIndex, EdgeIndex, NodeValue, EdgeValue>

It might save a fair amount of typing if we had a generic equivalent to both typealias and associatedtype.

associatedgenerics GraphElements = <NodeIndex : Hashable, EdgeIndex : Hashable, NodeValue, EdgeValue>
func shortestPath<GraphElements>(graph: Graph<GraphElements>, startNode<GraphElements.NodeIndex>, endNode<GraphElements.NodeIndex>) -> Path<GraphElements>

genericalias NavigationGraphElements = GraphElements<String, Int, City, Motorway>

typealias NavigationGraph = Graph<NavigationGraphElements>
// navigationGraph.shortestPath() now returns a Path<NavigationGraphElements>
// this last part is closest to the proposal under review.

On Wed, Apr 6, 2016 at 9:05 PM, Milos Rankovic via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
Chris Lattner has a proposal under review <https://github.com/apple/swift-evolution/blob/master/proposals/0048-generic-typealias.md> on this topic.

milos

On 6 Apr 2016, at 20:41, James Campbell via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

This was inspired from the topic about moving where clauses out of parameter lists.

Certain generics get very long winded, I was wondering if we could create some sort of alias for generics.

func anyCommonElements <T: SequenceType, U: SequenceType where T.Generator.Element: Equatable, T.Generator.Element == U.Generator.Element> (lhs: T, _ rhs: U) -> Bool

could be shared across functions like so:

genericalias SequencesWithSameElements<T, U> = <T: SequenceType, U: SequenceType where T.Generator.Element: Equatable, T.Generator.Element == U.Generator.Element>

func anyCommonElements <SequencesWithSameElements> (lhs: T, _ rhs: U) -> Bool
func == <SequencesWithSameElements> (lhs: T, _ rhs: U) -> Bool
___________________________________

James⎥

james@supmenow.com <mailto:james@supmenow.com>⎥supmenow.com <http://supmenow.com/>
Sup

Runway East >>

10 Finsbury Square

London

>> EC2A 1AF

_______________________________________________
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