Hi Marc,

> On Dec 11, 2015, at 3:06 AM, Marc Knaup via swift-dev <swift-dev@swift.org 
> <mailto:swift-dev@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?
> 
> enum ArithmeticExpression {
>     case Number(Int)
>     case Addition(indirect ArithmeticExpression, indirect 
> ArithmeticExpression)
>     case Multiplication(indirect ArithmeticExpression, indirect 
> ArithmeticExpression)
> }

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@swift.org <mailto:swift-dev@swift.org>
> https://lists.swift.org/mailman/listinfo/swift-dev

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

Reply via email to