[Pitch] Object aliases


(Daryle Walker) #1

I started a thread earlier this week about strong type-aliases and object aliases. Here’s a fuller proposal on object aliases.

Feature name
Proposal: SE-NNNN <file:///Users/daryle/NNNN-local-object-aliases.md>
Authors: Daryle Walker <https://github.com/CTMacUser>, Author 2 <https://github.com/swiftdev>
Review Manager: TBD
Status: Awaiting review
During the review process, add the following fields as needed:

Decision Notes: Rationale <https://lists.swift.org/pipermail/swift-evolution/>, Additional Commentary <https://lists.swift.org/pipermail/swift-evolution/>
Bugs: SR-NNNN <https://bugs.swift.org/browse/SR-NNNN>, SR-MMMM <https://bugs.swift.org/browse/SR-MMMM>
Previous Revision: 1 <https://github.com/apple/swift-evolution/blob/...commit-ID.../proposals/NNNN-filename.md>
Previous Proposal: SE-XXXX <file:///Users/daryle/XXXX-filename.md>
Introduction
This is a proposal to define aliases to objects.

Swift-evolution thread: 1 <https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20170619/037631.html>
Motivation
Aliasing allows a named object to actually refer to another object instead of newly-allocated storage. Referring to an object with a simple name isn't very useful, but referring to an object needing a complex expression to point to it can help with reducing typing.

However, aliasing has a cost. Compilers have to make certain assumptions if objects can have multiple names referring to them, and these assumptions reduce what kinds of optimizations can be made.

Language design can make a difference in how code can be optimized. Languages like C and C++ assume aliasing is allowed by default, limiting how many optimizations can be done. More recent versions of C have a keyword ("restrict") to ban certain objects from aliasing. Other languages go the other way; you need to take extra measures to alias objects, since object handling bars aliasing by default.

Swift is currently an alias-adverse language. The model for the equivalent of pointers is supposed to be for short-term use, and not persisted. Other constructs that would use references: read-write properties, read-write subscripts, and inout function parameters, can all be implemented by copy-in-then-copy-out, presumably to avoid alias dynamics and its anti-optimizations. So the scope of aliases here will be limited to local-scale renaming of object locations that the compiler can connect statically.

Yes, the use case is currently weak, but it is a stepping stone for stronger cases, like changing the interface of an object with (currently not in the language) strong type-aliases without copies.

Proposed solution
The solution is to introduce a new kind of object declaration. It uses a new keyword pose in the same place as let or var. It must be initialized with an expression that specifies an object, and be typed with a layout-compatible type (like the unsafeBitCast function).

struct Sample {
    var test1 = (1, 2, 3, "apple")
    //...
    func trial1() {
        pose firstTestNumber = test1.0
        print(firstTestNumber) // prints "1"
        //...
        firstTestNumber = 4
        print(test1.0) // prints "4"
    }
}
When an object is used, the compiler associates the object with some sort of location ID. An alias just reuses its original's ID instead of having one of its own.

Here, the substitution is simple, but longer chains are imaginable. With a local-scope limitation, aliases work kind-of like macro constants in C.

Detailed design
Add to the "Grammar of a Declaration":

declaration → alias-declaration
Add a new section "Grammar of an Alias Declaration":

alias-declaration → attributes_opt declaration-modifiers_optpose pattern-initializer-list
An alias declaration can only be in the local scope of a function. Expressions that describe source objects must be:

a named object, including function parameters
a member of a qualifying tuple object
a stored property of a qualifying struct (or class?) object
A source object must have a lifetime at least as long as any aliases to it. A source object cannot have willSet and/or didSetobservers. The alias poses as an object of its type annotation, defaulting to the source object's type if omitted. An annotation must be of the source object's type or a layout-compatible type. An alias has the same mutability status as its source object.

An alias has the same operations as its annotated type, using the storage of the source object. An alias used as an inout function argument is banned if it and at least one other inout argument share memory (in whole or in part).

Since source objects are restricted to have their storage established statically, the compiler can reuse a source object's location ID when an alias to that source is referenced. Since an alias doesn't escape its containing function (any returns or inout action would copy to/from the source object), additional global aliasing checks are avoided.

Source compatibility
Besides the new keyword pose, which should be conditional if possible, the changes are additive. I don't think it is legal to currently use an identifier pose in its planned syntax, so there should be no code to migrate.

Effect on ABI stability
The effects of aliases happen only during translation, reusing locations of either named objects or a sub-objects of named objects. Since they shouldn't escape the function containing them (and can't be sub-objects of another type), the ABI should be unaffected.

Effect on API resilience
Since aliases shouldn't leak out from being a function implementation aid, there should be no effect on the API.

Alternatives considered
The alternative is to do nothing. This would currently make reuse of a sub-object for read-write a bit more wordy. But this facility may be more useful if making interface-wise different but layout-compatible types (like strong type-aliases) is added.

···


Daryle Walker
Mac, Internet, and Video Game Junkie
darylew AT mac DOT com


#2

This sounds similar to lenses. Have you looked at previous lens discussions
on-list?

Nevin

···

On Fri, Jun 23, 2017 at 3:28 AM, Daryle Walker via swift-evolution < swift-evolution@swift.org> wrote:

I started a thread earlier this week about strong type-aliases and object
aliases. Here’s a fuller proposal on object aliases.

Feature name

   - Proposal: SE-NNNN
   - Authors: Daryle Walker <https://github.com/CTMacUser>, Author 2
   <https://github.com/swiftdev>
   - Review Manager: TBD
   - Status: *Awaiting review*

*During the review process, add the following fields as needed:*

   - Decision Notes: Rationale
   <https://lists.swift.org/pipermail/swift-evolution/>, Additional
   Commentary <https://lists.swift.org/pipermail/swift-evolution/>
   - Bugs: SR-NNNN <https://bugs.swift.org/browse/SR-NNNN>, SR-MMMM
   <https://bugs.swift.org/browse/SR-MMMM>
   - Previous Revision: 1
   <https://github.com/apple/swift-evolution/blob/...commit-ID.../proposals/NNNN-filename.md>
   - Previous Proposal: SE-XXXX

Introduction

This is a proposal to define aliases to objects.

Swift-evolution thread: 1
<https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20170619/037631.html>
Motivation

Aliasing allows a named object to actually refer to another object instead
of newly-allocated storage. Referring to an object with a simple name isn't
very useful, but referring to an object needing a complex expression to
point to it can help with reducing typing.

However, aliasing has a cost. Compilers have to make certain assumptions
if objects can have multiple names referring to them, and these assumptions
reduce what kinds of optimizations can be made.

Language design can make a difference in how code can be optimized.
Languages like C and C++ assume aliasing is allowed by default, limiting
how many optimizations can be done. More recent versions of C have a
keyword ("restrict") to ban certain objects from aliasing. Other
languages go the other way; you need to take extra measures to alias
objects, since object handling bars aliasing by default.

Swift is currently an alias-adverse language. The model for the equivalent
of pointers is supposed to be for short-term use, and not persisted. Other
constructs that would use references: read-write properties, read-write
subscripts, and inout function parameters, can all be implemented by
copy-in-then-copy-out, presumably to avoid alias dynamics and its
anti-optimizations. So the scope of aliases here will be limited to
local-scale renaming of object locations that the compiler can connect
statically.

Yes, the use case is currently weak, but it is a stepping stone for
stronger cases, like changing the interface of an object with (currently
not in the language) strong type-aliases without copies.
Proposed solution

The solution is to introduce a new kind of object declaration. It uses a
new keyword pose in the same place as let or var. It must be initialized
with an expression that specifies an object, and be typed with a
layout-compatible type (like the unsafeBitCast function).

struct Sample {
    var test1 = (1, 2, 3, "apple")
    //...
    func trial1() {
        pose firstTestNumber = test1.0
        print(firstTestNumber) // prints "1"
        //...
        firstTestNumber = 4
        print(test1.0) // prints "4"
    }
}

When an object is used, the compiler associates the object with some sort
of location ID. An alias just reuses its original's ID instead of having
one of its own.

Here, the substitution is simple, but longer chains are imaginable. With a
local-scope limitation, aliases work kind-of like macro constants in C.
Detailed design

Add to the "Grammar of a Declaration":

*declaration* → *alias-declaration*

Add a new section "Grammar of an Alias Declaration":

*alias-declaration* → *attributes_opt* *declaration-modifiers_opt**pose*
*pattern-initializer-list*

An alias declaration can only be in the local scope of a function.
Expressions that describe source objects must be:

   - a named object, including function parameters
   - a member of a qualifying tuple object
   - a stored property of a qualifying struct (or class?) object

A source object must have a lifetime at least as long as any aliases to
it. A source object cannot have willSet and/or didSetobservers. The alias
poses as an object of its type annotation, defaulting to the source
object's type if omitted. An annotation must be of the source object's type
or a layout-compatible type. An alias has the same mutability status as its
source object.

An alias has the same operations as its annotated type, using the storage
of the source object. An alias used as an inout function argument is
banned if it and at least one other inout argument share memory (in whole
or in part).

Since source objects are restricted to have their storage established
statically, the compiler can reuse a source object's location ID when an
alias to that source is referenced. Since an alias doesn't escape its
containing function (any returns or inout action would copy to/from the
source object), additional global aliasing checks are avoided.
Source compatibility

Besides the new keyword pose, which should be conditional if possible,
the changes are additive. I don't think it is legal to currently use an
identifier pose in its planned syntax, so there should be no code to
migrate.
Effect on ABI stability

The effects of aliases happen only during translation, reusing locations
of either named objects or a sub-objects of named objects. Since they
shouldn't escape the function containing them (and can't be sub-objects of
another type), the ABI should be unaffected.
Effect on API resilience

Since aliases shouldn't leak out from being a function implementation aid,
there should be no effect on the API.
Alternatives considered

The alternative is to do nothing. This would currently make reuse of a
sub-object for read-write a bit more wordy. But this facility may be more
useful if making interface-wise different but layout-compatible types (like
strong type-aliases) is added.


Daryle Walker
Mac, Internet, and Video Game Junkie
darylew AT mac DOT com

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


(Daryle Walker) #3

I put this proposal, with an addendum about lenses, at <https://gist.github.com/CTMacUser/464998bada4d567e4b3ff2626ec59c27>.

···


Daryle Walker
Mac, Internet, and Video Game Junkie
darylew AT mac DOT com


(Beta) #4

So, what’s the difference between this and teaching Key Paths to look through tuple indices - that was the only part of your example I couldn’t directly express.

~Robert Widmann

···

On Jun 23, 2017, at 12:28 AM, Daryle Walker via swift-evolution <swift-evolution@swift.org> wrote:

I started a thread earlier this week about strong type-aliases and object aliases. Here’s a fuller proposal on object aliases.

Feature name
Proposal: SE-NNNN <file:///Users/daryle/NNNN-local-object-aliases.md>
Authors: Daryle Walker <https://github.com/CTMacUser>, Author 2 <https://github.com/swiftdev>
Review Manager: TBD
Status: Awaiting review
During the review process, add the following fields as needed:

Decision Notes: Rationale <https://lists.swift.org/pipermail/swift-evolution/>, Additional Commentary <https://lists.swift.org/pipermail/swift-evolution/>
Bugs: SR-NNNN <https://bugs.swift.org/browse/SR-NNNN>, SR-MMMM <https://bugs.swift.org/browse/SR-MMMM>
Previous Revision: 1 <https://github.com/apple/swift-evolution/blob/...commit-ID.../proposals/NNNN-filename.md>
Previous Proposal: SE-XXXX <file:///Users/daryle/XXXX-filename.md>
Introduction
This is a proposal to define aliases to objects.

Swift-evolution thread: 1 <https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20170619/037631.html>
Motivation
Aliasing allows a named object to actually refer to another object instead of newly-allocated storage. Referring to an object with a simple name isn't very useful, but referring to an object needing a complex expression to point to it can help with reducing typing.

However, aliasing has a cost. Compilers have to make certain assumptions if objects can have multiple names referring to them, and these assumptions reduce what kinds of optimizations can be made.

Language design can make a difference in how code can be optimized. Languages like C and C++ assume aliasing is allowed by default, limiting how many optimizations can be done. More recent versions of C have a keyword ("restrict") to ban certain objects from aliasing. Other languages go the other way; you need to take extra measures to alias objects, since object handling bars aliasing by default.

Swift is currently an alias-adverse language. The model for the equivalent of pointers is supposed to be for short-term use, and not persisted. Other constructs that would use references: read-write properties, read-write subscripts, and inout function parameters, can all be implemented by copy-in-then-copy-out, presumably to avoid alias dynamics and its anti-optimizations. So the scope of aliases here will be limited to local-scale renaming of object locations that the compiler can connect statically.

Yes, the use case is currently weak, but it is a stepping stone for stronger cases, like changing the interface of an object with (currently not in the language) strong type-aliases without copies.

Proposed solution
The solution is to introduce a new kind of object declaration. It uses a new keyword pose in the same place as let or var. It must be initialized with an expression that specifies an object, and be typed with a layout-compatible type (like the unsafeBitCast function).

struct Sample {
    var test1 = (1, 2, 3, "apple")
    //...
    func trial1() {
        pose firstTestNumber = test1.0
        print(firstTestNumber) // prints "1"
        //...
        firstTestNumber = 4
        print(test1.0) // prints "4"
    }
}
When an object is used, the compiler associates the object with some sort of location ID. An alias just reuses its original's ID instead of having one of its own.

Here, the substitution is simple, but longer chains are imaginable. With a local-scope limitation, aliases work kind-of like macro constants in C.

Detailed design
Add to the "Grammar of a Declaration":

declaration → alias-declaration
Add a new section "Grammar of an Alias Declaration":

alias-declaration → attributes_opt declaration-modifiers_optpose pattern-initializer-list
An alias declaration can only be in the local scope of a function. Expressions that describe source objects must be:

a named object, including function parameters
a member of a qualifying tuple object
a stored property of a qualifying struct (or class?) object
A source object must have a lifetime at least as long as any aliases to it. A source object cannot have willSet and/or didSetobservers. The alias poses as an object of its type annotation, defaulting to the source object's type if omitted. An annotation must be of the source object's type or a layout-compatible type. An alias has the same mutability status as its source object.

An alias has the same operations as its annotated type, using the storage of the source object. An alias used as an inout function argument is banned if it and at least one other inout argument share memory (in whole or in part).

Since source objects are restricted to have their storage established statically, the compiler can reuse a source object's location ID when an alias to that source is referenced. Since an alias doesn't escape its containing function (any returns or inout action would copy to/from the source object), additional global aliasing checks are avoided.

Source compatibility
Besides the new keyword pose, which should be conditional if possible, the changes are additive. I don't think it is legal to currently use an identifier pose in its planned syntax, so there should be no code to migrate.

Effect on ABI stability
The effects of aliases happen only during translation, reusing locations of either named objects or a sub-objects of named objects. Since they shouldn't escape the function containing them (and can't be sub-objects of another type), the ABI should be unaffected.

Effect on API resilience
Since aliases shouldn't leak out from being a function implementation aid, there should be no effect on the API.

Alternatives considered
The alternative is to do nothing. This would currently make reuse of a sub-object for read-write a bit more wordy. But this facility may be more useful if making interface-wise different but layout-compatible types (like strong type-aliases) is added.


Daryle Walker
Mac, Internet, and Video Game Junkie
darylew AT mac DOT com

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


(John McCall) #5

I started a thread earlier this week about strong type-aliases and object aliases. Here’s a fuller proposal on object aliases.

Feature name
Proposal: SE-NNNN <file:///Users/daryle/NNNN-local-object-aliases.md>
Authors: Daryle Walker <https://github.com/CTMacUser>, Author 2 <https://github.com/swiftdev>
Review Manager: TBD
Status: Awaiting review
During the review process, add the following fields as needed:

Decision Notes: Rationale <https://lists.swift.org/pipermail/swift-evolution/>, Additional Commentary <https://lists.swift.org/pipermail/swift-evolution/>
Bugs: SR-NNNN <https://bugs.swift.org/browse/SR-NNNN>, SR-MMMM <https://bugs.swift.org/browse/SR-MMMM>
Previous Revision: 1 <https://github.com/apple/swift-evolution/blob/...commit-ID.../proposals/NNNN-filename.md>
Previous Proposal: SE-XXXX <file:///Users/daryle/XXXX-filename.md>
Introduction
This is a proposal to define aliases to objects.

Swift-evolution thread: 1 <https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20170619/037631.html>
Motivation
Aliasing allows a named object to actually refer to another object instead of newly-allocated storage. Referring to an object with a simple name isn't very useful, but referring to an object needing a complex expression to point to it can help with reducing typing.

However, aliasing has a cost. Compilers have to make certain assumptions if objects can have multiple names referring to them, and these assumptions reduce what kinds of optimizations can be made.

Language design can make a difference in how code can be optimized. Languages like C and C++ assume aliasing is allowed by default, limiting how many optimizations can be done. More recent versions of C have a keyword ("restrict") to ban certain objects from aliasing. Other languages go the other way; you need to take extra measures to alias objects, since object handling bars aliasing by default.

Swift is currently an alias-adverse language. The model for the equivalent of pointers is supposed to be for short-term use, and not persisted. Other constructs that would use references: read-write properties, read-write subscripts, and inout function parameters, can all be implemented by copy-in-then-copy-out, presumably to avoid alias dynamics and its anti-optimizations. So the scope of aliases here will be limited to local-scale renaming of object locations that the compiler can connect statically.

Yes, the use case is currently weak, but it is a stepping stone for stronger cases, like changing the interface of an object with (currently not in the language) strong type-aliases without copies.

We usually expect language features to stand on their own. Certainly something as core as a new kind of declaration would be expected to.

Anyway, this feature is rather similar to what I called a "local ephemeral binding" in the ownership proposal, except that your alias does not access the referenced storage until it itself is accessed. Unfortunately, this actually makes it *more* complex, rather than less, as it creates a new way to abstract over storage, including local storage.

John.

···

On Jun 23, 2017, at 3:28 AM, Daryle Walker via swift-evolution <swift-evolution@swift.org> wrote:
Proposed solution
The solution is to introduce a new kind of object declaration. It uses a new keyword pose in the same place as let or var. It must be initialized with an expression that specifies an object, and be typed with a layout-compatible type (like the unsafeBitCast function).

struct Sample {
    var test1 = (1, 2, 3, "apple")
    //...
    func trial1() {
        pose firstTestNumber = test1.0
        print(firstTestNumber) // prints "1"
        //...
        firstTestNumber = 4
        print(test1.0) // prints "4"
    }
}
When an object is used, the compiler associates the object with some sort of location ID. An alias just reuses its original's ID instead of having one of its own.

Here, the substitution is simple, but longer chains are imaginable. With a local-scope limitation, aliases work kind-of like macro constants in C.

Detailed design
Add to the "Grammar of a Declaration":

declaration → alias-declaration
Add a new section "Grammar of an Alias Declaration":

alias-declaration → attributes_opt declaration-modifiers_optpose pattern-initializer-list
An alias declaration can only be in the local scope of a function. Expressions that describe source objects must be:

a named object, including function parameters
a member of a qualifying tuple object
a stored property of a qualifying struct (or class?) object
A source object must have a lifetime at least as long as any aliases to it. A source object cannot have willSet and/or didSetobservers. The alias poses as an object of its type annotation, defaulting to the source object's type if omitted. An annotation must be of the source object's type or a layout-compatible type. An alias has the same mutability status as its source object.

An alias has the same operations as its annotated type, using the storage of the source object. An alias used as an inout function argument is banned if it and at least one other inout argument share memory (in whole or in part).

Since source objects are restricted to have their storage established statically, the compiler can reuse a source object's location ID when an alias to that source is referenced. Since an alias doesn't escape its containing function (any returns or inout action would copy to/from the source object), additional global aliasing checks are avoided.

Source compatibility
Besides the new keyword pose, which should be conditional if possible, the changes are additive. I don't think it is legal to currently use an identifier pose in its planned syntax, so there should be no code to migrate.

Effect on ABI stability
The effects of aliases happen only during translation, reusing locations of either named objects or a sub-objects of named objects. Since they shouldn't escape the function containing them (and can't be sub-objects of another type), the ABI should be unaffected.

Effect on API resilience
Since aliases shouldn't leak out from being a function implementation aid, there should be no effect on the API.

Alternatives considered
The alternative is to do nothing. This would currently make reuse of a sub-object for read-write a bit more wordy. But this facility may be more useful if making interface-wise different but layout-compatible types (like strong type-aliases) is added.


Daryle Walker
Mac, Internet, and Video Game Junkie
darylew AT mac DOT com

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


(Daryle Walker) #6

I had no idea what a lens is. Nor was is easy to figure out since I can’t read Scala, JavaScript, or Haskell. From what I can grok from those papers, I’m guessing it’s like C++’s pointer-to-member, but it’s more like a group of them forming an access chain from a source object to a (possibly nested) sub-object. It seems like a functional programming thing.

From a high-level view, a poser is a kind of a lens. But the low-level details are completely different.

* A lens is a first-class type, probably part of a Standard Library. Posers are symbolic substitution; they’re deliberately not first-class types.
* As a first-class type, lenses have data, indicating the path from source to sub-object. There is no data for a poser, since the concept is realized during translation.
* A lens, a far as I understand, targets a sub-object. A poser can target the entirety of a named object.
* A poser can cover substituting an object of one type for a layout-compatible type (including future strong type-aliases). Lenses don’t cover this use case.
* A poser’s purpose is to defeat copy-in/out semantics with reference semantics. How lenses work on copy-in/out vs. reference is unspecified.

Swift tries to avoid direct reference semantics, and does two-way object passing as (or as-if) copy-in & copy-out. This avoids having to do the pessimizations needed for safety when one object reference may alias another. Posers are limited to minimize these anti-optimizations. Posers can only be implementation aids for functions; they cannot be globals nor a property/associated-value (not the case for lenses since they’re first-class types). Posers can only alias a (sub-)block of statically determined memory (not the case for lenses either). Posers are not passed a function arguments or returns; the original object is instead.

Something I like about the poser syntax is that we could extend it to actual lenses someday (when we can make pointer-to-member expressions).

Oh, some previous discussions are:

https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20160111/006663.html
https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20160523/019138.html
https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20160104/005236.html
https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20160307/012541.html
https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20160627/022479.html
https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20151221/004555.html
https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20160801/025882.html
https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20160111/006262.html
https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20161212/029531.html

The “Lenses in Swift” video is actually at <https://www.youtube.com/watch?v=ofjehH9f-CU <https://www.youtube.com/watch?v=ofjehH9f-CU>>.

···

On Jun 23, 2017, at 9:29 AM, Nevin Brackett-Rozinsky <nevin.brackettrozinsky@gmail.com> wrote:

This sounds similar to lenses. Have you looked at previous lens discussions on-list?


Daryle Walker
Mac, Internet, and Video Game Junkie
darylew AT mac DOT com


(TJ Usiyan) #7

This video is a nice introduction to why lenses are. It is in Haskell, yes,
but I believe that you can infer everything that you need from the context
provided.
A Brief Introduction of the Haskell Lens Library
<https://www.youtube.com/watch?v=7fbziKgQjnw>

···

On Wed, Jun 28, 2017 at 1:42 PM, Daryle Walker via swift-evolution < swift-evolution@swift.org> wrote:

I put this proposal, with an addendum about lenses, at <
https://gist.github.com/CTMacUser/464998bada4d567e4b3ff2626ec59c27>.


Daryle Walker
Mac, Internet, and Video Game Junkie
darylew AT mac DOT com

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


(Daryle Walker) #8

You’re talking about Apple’s Cocoa’s KVC/KVO, right? The key-path method is like the lenses idea bouncing around this thread, except KVO/KVC doesn’t take Swift-specific stuff (like tuples) into account. Key-path and lenses are resolved at run-time, while the posing-aliases here should be resolved at compile-time (or whenever the memory locations of globals and named locals are resolved).

···

On Jun 29, 2017, at 6:45 PM, Beta <rwidmann@apple.com> wrote:

So, what’s the difference between this and teaching Key Paths to look through tuple indices - that was the only part of your example I couldn’t directly express.


Daryle Walker
Mac, Internet, and Video Game Junkie
darylew AT mac DOT com


(Daryle Walker) #9

I was thinking posing aliases would be like symbolic substitution; we could replace the alias with the text defining its source expression everywhere and there should be no efficiency change. But I would want any evaluation of the (sub-)object’s location to be computed once; is that where complexity could come in? I was hoping that object location determination could be done at compile-time; that’s the reason for restricting what kinds of objects can be a source object.

···

On Jun 30, 2017, at 1:11 AM, John McCall <rjmccall@apple.com> wrote:

On Jun 23, 2017, at 3:28 AM, Daryle Walker via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

Swift is currently an alias-adverse language. The model for the equivalent of pointers is supposed to be for short-term use, and not persisted. Other constructs that would use references: read-write properties, read-write subscripts, and inout function parameters, can all be implemented by copy-in-then-copy-out, presumably to avoid alias dynamics and its anti-optimizations. So the scope of aliases here will be limited to local-scale renaming of object locations that the compiler can connect statically.
Yes, the use case is currently weak, but it is a stepping stone for stronger cases, like changing the interface of an object with (currently not in the language) strong type-aliases without copies.

We usually expect language features to stand on their own. Certainly something as core as a new kind of declaration would be expected to.

Anyway, this feature is rather similar to what I called a "local ephemeral binding" in the ownership proposal, except that your alias does not access the referenced storage until it itself is accessed. Unfortunately, this actually makes it *more* complex, rather than less, as it creates a new way to abstract over storage, including local storage.


Daryle Walker
Mac, Internet, and Video Game Junkie
darylew AT mac DOT com


(John McCall) #10

I'm always wary of features that require a ton of restrictions because they can only be implemented using a sort of preprocessing. Among other things, it suggests that they cannot possibly be made resilient.

I think a better way of thinking of your feature is as sugar on top of the generalized accessors feature from ownership — that is, a concise way to declare a var/subscript with accessors that automatically forward to some other entity, e.g.:

  var values: [Value]
  alias var count: Int = values.count
  alias subscript(i: Int) -> Value = values[i]

John.

···

On Jun 30, 2017, at 4:55 AM, Daryle Walker <darylew@mac.com> wrote:

On Jun 30, 2017, at 1:11 AM, John McCall <rjmccall@apple.com <mailto:rjmccall@apple.com>> wrote:

On Jun 23, 2017, at 3:28 AM, Daryle Walker via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

Swift is currently an alias-adverse language. The model for the equivalent of pointers is supposed to be for short-term use, and not persisted. Other constructs that would use references: read-write properties, read-write subscripts, and inout function parameters, can all be implemented by copy-in-then-copy-out, presumably to avoid alias dynamics and its anti-optimizations. So the scope of aliases here will be limited to local-scale renaming of object locations that the compiler can connect statically.
Yes, the use case is currently weak, but it is a stepping stone for stronger cases, like changing the interface of an object with (currently not in the language) strong type-aliases without copies.

We usually expect language features to stand on their own. Certainly something as core as a new kind of declaration would be expected to.

Anyway, this feature is rather similar to what I called a "local ephemeral binding" in the ownership proposal, except that your alias does not access the referenced storage until it itself is accessed. Unfortunately, this actually makes it *more* complex, rather than less, as it creates a new way to abstract over storage, including local storage.

I was thinking posing aliases would be like symbolic substitution; we could replace the alias with the text defining its source expression everywhere and there should be no efficiency change. But I would want any evaluation of the (sub-)object’s location to be computed once; is that where complexity could come in? I was hoping that object location determination could be done at compile-time; that’s the reason for restricting what kinds of objects can be a source object.


(Martin Waitz) #11

Hello,

···

Am 30.06.2017 um 10:55 schrieb Daryle Walker via swift-evolution <swift-evolution@swift.org>:

I was thinking posing aliases would be like symbolic substitution; we could replace the alias with the text defining its source expression everywhere and there should be no efficiency change. But I would want any evaluation of the (sub-)object’s location to be computed once; is that where complexity could come in? I was hoping that object location determination could be done at compile-time; that’s the reason for restricting what kinds of objects can be a source object.

Have you had a look at local `inout` bindings as proposed in the Ownership Manifesto[1]?
Do they solve your problem?

— Martin

[1]: https://github.com/apple/swift/blob/master/docs/OwnershipManifesto.md#local-ephemeral-bindings
<https://github.com/apple/swift/blob/master/docs/OwnershipManifesto.md#local-ephemeral-bindings> <https://github.com/apple/swift/blob/master/docs/OwnershipManifesto.md#local-ephemeral-bindings>


(Martin Waitz) #12

Hi again,

Hello,

I was thinking posing aliases would be like symbolic substitution; we could replace the alias with the text defining its source expression everywhere and there should be no efficiency change. But I would want any evaluation of the (sub-)object’s location to be computed once; is that where complexity could come in? I was hoping that object location determination could be done at compile-time; that’s the reason for restricting what kinds of objects can be a source object.

Have you had a look at local `inout` bindings as proposed in the Ownership Manifesto[1]?

yes of course you have, because you already replied to John :wink:
sorry for not reading the complete thread :-/

And yes, these local bindings would effectively just be a new binding for the same memory location.
This way it really would be a compile-time alias.

— Martin

···

Am 30.06.2017 um 10:55 schrieb Daryle Walker via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>>: