64 lines
2.3 KiB
Markdown
64 lines
2.3 KiB
Markdown
|
# C# Language Design Notes for September 5, 2018
|
||
|
|
||
|
## Agenda
|
||
|
|
||
|
1. Index operator: is it a unary operator?
|
||
|
1. Compiler intrinsics
|
||
|
|
||
|
# Discussion
|
||
|
|
||
|
## Index operator
|
||
|
|
||
|
There are multiple questions here:
|
||
|
|
||
|
1. Is the operator syntactically a unary operator?
|
||
|
1. Is it a user-definable operator?
|
||
|
1. Does it have the same precedence as other unary operators?
|
||
|
1. Do members which do not exist implicitly exist anyway as an intrinsic?
|
||
|
1. Does it have overloads? Is `^^1` allowed? That would imply that there's an
|
||
|
overload which takes an index.
|
||
|
|
||
|
Follow-up: is `..` a binary operator?
|
||
|
|
||
|
**Conclusion**
|
||
|
|
||
|
Agreed that it's syntactically a unary operator. Also agreed that it is a
|
||
|
semantically treated as a unary operator that it is not user-definable. Right
|
||
|
now, we don't see a great need to add a second overload. There is a single
|
||
|
overload for `int`.
|
||
|
|
||
|
We're not strictly defining `..` as a binary operator right now. It has its
|
||
|
own syntactic form.
|
||
|
|
||
|
Also, we're renaming '^' to the "hat" operator.
|
||
|
|
||
|
## Compiler intrinsics
|
||
|
|
||
|
Proposal: https://github.com/dotnet/csharplang/blob/master/proposals/intrinsics.md
|
||
|
|
||
|
There is contention between using `void*` and some stronger typing, either a
|
||
|
delegate or some kind of function pointer syntax. The benefit of using a
|
||
|
pointer type is that it is always unsafe, which this feature requires if
|
||
|
there are no allocations (because an appdomain could unload and cause the
|
||
|
invocation to point to arbitrary memory).
|
||
|
|
||
|
For `calli`, there's a worry about moving the typing from the point of
|
||
|
retrieving a function pointer to the declaration of the target and calling
|
||
|
convention. The `extern` declaration, specifically, is disliked.
|
||
|
|
||
|
Does this only work for managed code or also for native code? Do we have to
|
||
|
care about the calling convention?
|
||
|
|
||
|
**Conclusion**
|
||
|
|
||
|
We'd probably be willing to accept this in some form. We think the current
|
||
|
proposal needs some work.
|
||
|
|
||
|
Some thoughts/suggestions:
|
||
|
|
||
|
1. Don't allow instance `&receiver.M` form -- only types for instance methods
|
||
|
e.g., `&TypeName.M`.
|
||
|
1. Drop the separate declaration for the `calli` invocation. A special calling
|
||
|
form like `_calli_stdcall(args, f)` is suggested. We don't like signature
|
||
|
being declared somewhere other than the method definition or at the call site.
|
||
|
1. Would like the calling convention, if used, present at the call site.
|