-
Notifications
You must be signed in to change notification settings - Fork 23
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
alias syntax to make every symbol 1st class #232
Comments
Note: Sorry for the deletions but it seemed the best way so that the RFC's author remains Timotheecour. |
I think as a next step you should outline the wording we have to add to the manual. |
@Araq done => nim-lang/Nim#14747 |
We already have |
What is |
There is considerable overlap with my unwritten RFC "nullary non-overloaded templates should be resolved early and allow for aliasing of the template body". Can we unify aliases and nullary templates? |
I'd like to rename tyAlias to tyAliasType and tyAliasSym to tyAlias in future work though, but it's low priority.
hard to comment on something that hasn't been written, please point me to a draft, but from your description I don't see how these could be unified. Nullary templates don't help with passing symbols to routines, in particular wouldn't help with most of the test suite I added in the PR (eg, lambdas @B3liever
there is no way to pass symbols to routines before this PR. alias declarations ( |
I would prefer to reuse the template mechanism as a means to alias symbols, so looking forwards to Araqs RFC there. proc a(p: proc) =
discard p[int]()
proc p[T]() =
echo "hey"
a(p) which would enable us to pass uninstantiated generics to other generics (I faintly remember an RFC/issue about this, but can't find it, searching for "lazy generics"). proc a(p: proc[T](arg: T)) = ... Regarding templates I think making |
Would this change semantics such that nullary templates could not be used in places that non-nullary would work (or exhibit different behavior)? Or to phrase it another way, would nullary templates become a semantic superset of non-nullary templates, or would they diverge in shared behaviors? |
Ok, let me phrase it differently: Everything your |
I don't see how nullary templates as a replacement for I've gone through the trouble to write the implementation for the proposed If you still think nullary templates is a viable and preferable alternative, please write an RFC with sufficient details otherwise it's impossible to comment on this alternative. I'm not even sure what syntax you're suggesting since there's no RFC; is it:
Here are just some of the problems with nullary templates: nullary templates are already very commoneg around 220 definitions just in nim repo itself; any change of meaning would have an large impact. major breaking change: nullary templates are not resolved earlya lot of code would break under this proposal, eg:
template checkIfInitialized() =
when compiles(defaultInitialSize): (if t.dataLen == 0: initImpl(t, defaultInitialSize)) it'd conflate 2 unrelated conceptsdespite appearances, the 2 concepts are unrelated. templates is a substitution mechanism that operates on AST (PNode); alias operates on symbols (PSym). this introduces a weird special case for templatesall those rules would be violated, introducing weird special cases and bugs:
|
has any decision been made regarding this yet? this looks like a good addition, a PR is already there, and the nullary templates rfc is nowhere to be seen... |
Plenty of Nim developers think that there is considerable overlap with |
nim-lang/Nim#11992 has the +1's amongst all PR's to date, and I haven't seen any explanation of how it would overlap.
as was already mentioned, You've proposed |
I personally don't think there is much overlap with templates. Just because templates can be used as a "workaround" for alias, does not mean we should go around adding more stuff on top of templates just to increase support for that use case. I mean I can use macros to do whatever templates do, but I don't do I? So, why should I be using templates to define alias, when there could be a better alternative that is easy to use, is less likely to cause confusion (esp. to newcomers) and most importantly, conveys its intentions well (the keyword 'alias' describes 'creating an alias for a symbol' much better than the keyword 'template'). If there are downsides/annoyances to using templates that are fixed by nullary templates, I am all for it as well. However, I am against complicating templates just because some people want to avoid having a new keyword 'alias'. In any case, I am not against comparing alias with template to figure out the downsides and upsides, I just don't want this feature to be merged with templates if it increases its complexity. |
This is rather meaningless, C# still lacks it and nobody complained. In fact, the programming language theory knows no such |
As overly simple as it sounds, the limitations of nullary templates outlined above could be cleared up with an explicit |
Symbol aliases
Abstract
This RFC proposes to add more aliasing capabilties to Nim. Every symbol (template, module, const, iterator etc: anything in
TSymKind
) becomes a 1st class entity, which can be passed to routines (procs, templates, iterators, etc: anything inroutineKinds
), or used as generic paramter in types. This works even if the symbol is overloaded, or if it's a template/macro (even if all parameters are optional).In particular, this allows defining 0-cost lambdas and aliases.
See nim-lang/Nim#11992 for the corresponding PR.
Motivation 1: symbol aliasing
template foo2(args: varargs[untyped]): untyped = foo(args)
falls short in many cases; egcase1
case2
case3
Motivation 2: passing symbols to routines
Motivation 3: speed benefit
Passing functors via closures is not free, because closure prevents inlining. Instead this RFC allows passing templates directly which is a zero-cost abstraction. eg: see
case4
.Motivation 3: lambdas
sugar.=>
, and don't incur overhead, seetests/magics/tlambda.nim
; eg:case5
Motivation 4: composable iterators
composable iterators, which allows define lazy functional programming primitives (eager
toSeq
and lazymap/filter/join
etc; which can have speed benefit compared tosequtils
); the resulting code is quite nice and compact, seetlambda_iterators.nim
which uses librarylambdaIter
that builds on top oflambda
; it allows defining primitives that work regardless we're passing a value (@[1,2,3]
) or a lazy iterate (egiota(3)
)Motivation 5: this fixes or closes a lot of issues
see a sample here: nim-lang/Nim#11992
alias syntax:
alias foo2 = expr
passing alias to a routine / generic parameter
alias
parameter makes a routine implicitly genericalias
parameter matches a generic parameter:alias parameters are resolved early
symbol constraints (not implemented)
note: this can be achieved without
alias[T]
via{.enableif.}
(nim-lang/Nim#12048)which is also more flexible:
symbol parameters typed as a symbol type alias parameter (not implemented)
Description: lambda
library solution on top of
alias
Differences with nim-lang/Nim#11992
currently:
const foo2 = alias2 foo
is used instead ofalias foo2 = foo
fn(alias2 echo)
is used instead offn(alias2 echo)
a: aliassym
is used instead ofa: alias
complexity
this introduces a new
tyAliasSym
type, which has to be dealt with.Examples
tests/magics/tlambda.nim
tests/magics/tlambda_iterators.nim
Backward incompatibility
No backward incompatibility is introduced.
In particular, the parser accepts this even if
nimHasAliassym
is not defined.snippets referenced in this RFC
The text was updated successfully, but these errors were encountered: