[swift-dev] Location of "indirect" declaration modifier

Marc Knaup marc at knaup.koeln
Fri Dec 11 10:01:08 CST 2015

Thank you for your thorough answer.

So when direct and indirect cases already look the same for the type system
then why is there the indirect modifier in the first place?
Couldn't the compiler just automatically box variables which would cause a
recursion? For structs, enums and probably tuples.

>From what I understand in indirected enum cases the compiler will basically
just box either

   - the case value as a whole or
   - just the associative values which cause the recursion.

What is boxed?

I do not intend to propose to make indirect part of the type itself. I'm
checking whether the modifier can be moved closer to the declaration of the
variables which cause the indirections.
What I need for my proposal is indeed indirection on structs and for that
I'd like to understand how indirections work under the hood and what their
limitations are.
Your answer already gives a lot of insight there.

Actually I once needed to design a recursive struct
<https://gist.github.com/fluidsonic/6a8f1c1def2a92416519> and did so by
just wrapping the recursive variable in an indirect enum case. Works fine
in Swift 2.1
I could have done it differently - e.g. by storing an array of parents
instead of using recursion - but the approach worked.

How can a recursive struct using indirection be an infinite type? Since the
indirect variables are just boxes which have a fixed size (just a pointer?)
independent of the struct's size the type is no longer infinite.


On Fri, Dec 11, 2015 at 4:03 PM, Slava Pestov <spestov at apple.com> wrote:

> Hi Marc,
> On Dec 11, 2015, at 3:06 AM, Marc Knaup via swift-dev <swift-dev at swift.org>
> wrote:
> Hey guys,
> I'm working on a proposal and the question arose why the declaration
> modifier indirect can only be specified for the whole enum case and the
> whole enum but not for the actual parameter which is indirect.
> I.e. is there any technical reason which would prevent something like the
> following?
>    1. enum ArithmeticExpression {
>    2. case Number(Int)
>    3. case Addition(indirect ArithmeticExpression, indirect
>    ArithmeticExpression)
>    4. case Multiplication(indirect ArithmeticExpression, indirect
>    ArithmeticExpression)
>    5. }
> Right now, notice that direct and indirect cases look the same from the
> perspective of the type system.
> With your proposal, the fact that the entire tuple payload can be matched
> by a pattern implies that ‘indirect’ has to become a formal type in the
> language, since you will now be able to write down a value of type
> '(indirect ArithmeticExpression, Int)’, for example. It also raises the
> issue of how these indirect values are wrapped and unwrapped, since now the
> ‘indirect ArithmeticExpression’ is itself a value.
> An alternative is to make ‘indirect’ a non-materializable type, like
> ‘inout’. ‘inout’ can appear inside tuple types, but is not a first class
> value. This creates lots of special cases for ‘inout’ and you can imagine
> it will be equally difficult for ‘indirect’.
> If you want an ‘indirect’ that can be nested inside a tuple type, you
> could just define ‘class Box<T> { let payload: T }’ and tolerate a bit of
> verbosity when wrapping and unwrapping values. As long as the payload is
> immutable, you will still have value semantics using this trick.
> Also is there any technical reason which would prevent indirect from
> being used for structs?
> Like an ‘indirect’ modifier for stored properties on structs? Yes, this
> should be possible, however note that right now enum payloads are not
> themselves lvalues, which means that assignment of indirect enum cases only
> has to update the reference count of the box to maintain value semantics,
> since the contents of the box will never change. Presumably for structs you
> would need to be able to define an ‘indirect var’ with a mutable payload —
> immutable-only indirect stored properties don’t seem very useful.
> Making the indirect payload mutable will require either copying the box
> upon assignment, or alternatively, a copy-on-write scheme could be used.
> The SIL @box type that implements indirect cases isn’t set up to support
> either of those right now. Also, unlike enums, indirect fields of structs
> won’t give you any new generality that was not possible before — its just a
> performance change. A value type that contains a cycle through an
> ‘indirect’ struct field is still invalid, for example, because the
> resulting type is still infinite.
> Slava
> Thanks,
>   Marc
> _______________________________________________
> swift-dev mailing list
> swift-dev at swift.org
> https://lists.swift.org/mailman/listinfo/swift-dev
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-dev/attachments/20151211/e8fb18a3/attachment.html>

More information about the swift-dev mailing list