Comments (7)
This makes the code much, much easier to write|read, and explicitly expresses to anyone reading it what's happening.
This is doubtful. If a single operator (e.g. +
) can have different meanings depending on context, you always need to be aware of the context in order to understand what's actually happening. You may not be able to easily spot a no overflow check
directive when looking at a specific piece of code. This introduces ambiguity.
Inverting the meaning of &+
to signify a non-wrapping operation makes this even weirder.
I relate to the sentiment that operators with &
prefix are harder to read. But I'm pretty sure it's better that way than following this proposal which hinders semantic readability because you have to resolve the ambiguity of operator mechanics.
from crystal.
Having implemented a bunch of PRNG, I understand the appeal.
That being said, this is just a few &
to explicit that we want wrapping math. It could be a lot more awful (look at wrapping_x
of Rust). This is on the same level as calling #to_unsafe
to skip bound checks, but we won't introduce a "no bounds check".
from crystal.
This is doubtful. If a single operator (e.g. +) can have different meanings depending on context, you always need to be aware of the context in order to understand what's actually happening. You may not be able to easily spot a no overflow check directive when looking at a specific piece of code. This introduces ambiguity.
No, no, that is not what I meant. I misspoke if you took it that way. I'm not proposing dual meanings of the &x
operators.
I am not proposing any change to the handling of overflow|boundary
checking. Crystal already allows users the ability to turn it off on individual operations using the &x
operators. That would not change. Crystal also already allows turning off address boundary checking: memory.to_unsafe[x] = y
So philosophically and operationally nothing that already exists changes.
All I'm requesting is a stylistic
way to make turning checks off easier and more appealing, similarly as provided in Rust, et al.
This will improve the writing|reading of code, and aide in code testing too. Again, nothing proposed here changes the thinking and responsibilities of users to write good
code. In fact it enhances it, because it eliminates missing hidden&x
operators stuffed somewhere when reading code, or places they could be inserted when writing it.
I think it's undeniable, to a code writer and reader, that something like this is more desirable:
def collatz(seed : UInt64)
unsafe do
steps = 0_u64
while seed > 1
tz_count = seed.trailing_zeros_count
steps += tz_count
seed >>= tz_count
if seed > 1
steps += 1
seed = seed * 3 + 1
end
end
steps
end
end
than this:
def collatz(seed : UInt64)
steps = 0_u64
while seed > 1
tz_count = seed.trailing_zeros_count
steps &+= tz_count
seed >>= tz_count
if seed > 1
steps &+= 1
seed = seed &* 3 &+ 1
end
end
steps
end
Two simple lines of code to add, versus changes to 4 individual operators (and this is a very simple real example).
So please focus the discussion|understanding of this proposal on how it will make users happy
, while also making code easier to read, modify, and maintain, as in Rust, et al.
from crystal.
In Rust you can do this:
fn nextp_init(.....)
unsafe {
........
........
}
}
to achieve turning off bounds checking. Again, I'm not concerned with the semantics, I want the same affect. I'm not aware that Rust even has the equivalent of individual &x
operators, and if so I don't use them in my Rust code, I just use unsafe
.
So if that would be semantically more appealing I would be all for it.
from crystal.
I didn't know Rust disabled checks inside unsafe
(that sounds just as bad as disabling checks in release mode). Anyway, we already rejected the unchecked block notation when designing the feature.
from crystal.
Could you clarify this phrase from the OP then?
If you then need to do overflow checking on some operation(s) for correctness, you can do it on just them by using the
&x
operators inside the code.
I read that as inside a block of code annotated as no overflow check
where +
means wrapping addition, &+
would mean non-wrapping addition.
Apparently I misunderstood.
(this aspect is only a minor detail of course, so no need to elaborate extensively until there's a consensus on the general proposal)
from crystal.
I read that as inside a block of code annotated as no overflow check where + means wrapping addition, &+ would mean non-wrapping addition.
Apparently I misunderstood.
I was thinking faster than I could write.
If an overflow occurs within an unsafe
code block, in the original code you test operation-by-operations using &x
until you find the one(s) that cause it. Once you know that, you can put the surrounding code in unsafe
blocks if you can't make the overflowing math not overflow (change numeric types, change algorithm to no allow it, etc).
From personal experience, most algorithms work over well defined number spaces (like modulo arithmetic) and have predefined min|max data ranges|types. You don't start out using unsafe
code anyway. You only use it when you need|want max speed from you existing code|hardware.
This is how I write my Rust code, when I want to be as fast as possible within a code base. Most stuff occurs once, or infrequently, and won't affect (measurable) performance anyway, so you don't worry about it. But stuff occurring inside loops (like the collatz
method example) become prime candidates for doing as fast as possible, for greatest overall speed.
As math in most realworld algorithms perform dozen of &x
type operations, it just becomes tedious to change multiple operations, over multiple lines of code, to do this type of testing.
I wasn't around to follow the discussions in Rust around this, but the Rust devs are some of the most annal people around in making their standard code base be safe
. But ultimately they accepted that there are times people need to do stuff their coding paradigm considers unsafe
, and they have to be responsible for it. But they created a standard|fast way to do it, that shows (and tells the compiler) it's obviously being done when you read|write Rust code. In fact their compiler is so good, it tells you when you have unnecessary unsafe
blocks within routines, if you already have an unsafe
block at a higher level that uses that code.
Since Rust and Crystal both use LLVM
, I imagine it shouldn't be that hard to implement, as a technical matter.
from crystal.
Related Issues (20)
- Iterate slice by reference (not by value)
- Unexpected behavior of the match method with position HOT 7
- Third-party library repositories on Windows CI HOT 3
- 1.13.0 - a big problem with UTF strings after `JSON.parse` when some special symbols present; broken encoding HOT 3
- IO::FileDescriptor & Socket finalizers do far too much
- sudo dnf install crystal results in error HOT 13
- Support double splatting on NamedTuple union. HOT 2
- Failed to update crystal with package managers on Windows HOT 8
- Don't require linking to libraries in order to generate documentation HOT 1
- Streamlining the `WaitGroup` API HOT 4
- Fully qualified name must be used inside a block when assigning to an ivar. HOT 1
- crystal i crashes in HAR shard HOT 4
- LLVM 18 breaks 128-bit integers in the interpreter HOT 5
- [CI] Darwin test job fails with `macos-14` HOT 2
- Process.on_terminate proc cannot be executed? HOT 9
- crystallography
- Option to launch processes as children
- LLVM 19 support
- Add `has_key?` to `NamedTupleLiteral` and `HashLiteral` HOT 3
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from crystal.