-
-
Notifications
You must be signed in to change notification settings - Fork 1.5k
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
deprecates newSeqUninitialized
replaced by unsafeseqs.newSeqUninit
#22586
Conversation
Should not be too complicated to make |
lib/system.nim
Outdated
assert len(s) == 10 | ||
assert s[0] == "abc" | ||
|
||
result = newSeqOfCap[T](len) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
missing type constraint for T
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nope, it's intended. There is an example in the runnableExample to demonstrate how to use it with types having destructors (credits to @Araq).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"be cautious" is kind of .. unsettling though - ie it feels like a sentence saying that it randomly might or might not work depending on the whims of the compiler, the complexity of the object graph or the mood of the developer
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
also, nodestroy
on the whole proc
like that would likely lead to other bugs - ie if you (accidentally) create some temporaries during construction - sounds like a good way to mess up the compiler - not sure it's good to recommend that kind of footgun
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's a sharp tool but it fits newSeqUninit
which is a very sharp tool too. However, we can move these to a new module unsafeseqs
and then distinguish between newSeqUninit
which has the constraint supportsCopyMem(T)
and newSeqUnsafe
which lacks the constraint.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
well, that's reasonable along with a better name - this version is not sharp at all beyond its name for plain types ("uninitialised" vs "broken GC with lots of gotchas")
for the gc case, one would almost need to have a template newSeqInitIt(size, body): {.nodestroy.}: let it = ...; body
to make it .. reasonable. nodestroy
is a bit of a shotgun.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we can move these to a new module unsafeseqs and then distinguish between newSeqUninit which has the constraint supportsCopyMem(T) and newSeqUnsafe which lacks the constraint.
done
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
newSeqUninit
is safe why is it in unsafeseqs
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Probably"unsafeseqs" is not a descriptive name for both of functions. I added both of them there instead of system lest they would break important packages. We can also move newStringUninit
to std/strbasics
and call this "seqbasics" or something. Or a new module called initutils for all of these initializations.
There are two packages(arraymancer, neo) are using |
lib/system.nim
Outdated
assert len(s) == 10 | ||
assert s[0] == "abc" | ||
|
||
result = newSeqOfCap[T](len) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
well, that's reasonable along with a better name - this version is not sharp at all beyond its name for plain types ("uninitialised" vs "broken GC with lots of gotchas")
for the gc case, one would almost need to have a template newSeqInitIt(size, body): {.nodestroy.}: let it = ...; body
to make it .. reasonable. nodestroy
is a bit of a shotgun.
uh, oops, wrong button - the approve was meant to be a comment saying that it would be nice with more protection against silly cases. in particular, it's very hard to know if some |
for threads and many other use cases, it would actually be nice to have a way of saying |
Can supportsCopyMem be a concept constraint? |
Arraymancer's newSeqUninit is a custom one because |
Yep, but also with
Libraries could define it with a |
Arraymancer will be compatible: mratsim/Arraymancer#589 |
newSeqUninitialized
replaced by newSeqUninit
newSeqUninitialized
replaced by unsafeseqs.newSeqUninit
Co-authored-by: Amjad Ben Hedhili <amjadhedhili@outlook.com>
Yes, but as I understand it there should be a |
Why put this in a module? It's a single function. |
this is often not enough - ie anything that relies on magic that the compiler generates behind your back (memory allocations like closures, destrutors etc) are usually a no-no for building core infrastructure supporting threads and other advanced use cases - for this, precise primitives are needed in the language along with guarantees about how they will evolve in the future so that one can describe functions that are safe for what in C would have been termed POD - C++ is a good journey to study where pod was later refined to https://en.cppreference.com/w/cpp/language/classes#Trivial_class in order to be able to generate optimal code for each kind of layout.
|
## After the creation of the sequence you should assign | ||
## entries to the sequence instead of adding them. | ||
runnableExamples: | ||
# newSeqUnsafe can be safely used for types, which don't contain |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is not a primary use case - I think the documentation should generally recommend newSeqUninit
and only fall back to newSeqUnsafe
for cases that involve complex types - I also think it's prudent to clearly establish the meaning of "unsafe" in this context, otherwise it's just a vacuous word for unknown bounds which makes it difficult to reason about in usage. ie "how is this unsafe?" for example, it is not unsafe in the same way addr
is unsafe.
Actually, it's not supposed to be a sledgehammer, it is the beginning of a classification system with crystal clear naming and C++ could learn something here too. ;-) But this all feels rather misguided when we could optimize |
In measuring performance, the zeroing is often dominant even for disk reads when the data is in cache, but it truly stands out in dumb low-level memory copies from a to b. |
I'd tend to prefer names that explain the primitives rather than complex combinations thereof - ie |
This should not be in its own module. If keeping it out of |
Succeeded by #22739 |
ref #19727