Crystal 0.34.0 has been released!

Can you please provide code with wrapping operators that works with 0.34.0 (and sooner w/o -Ddisable_overflow)? There’s no point in compiling code against 0.34.0 that doesn’t work in the correct way.

The above code examples 1) and 2) compile with 0.34 without -Ddisable_overflow as I stated, as well as 2) with 0.33.

@jzakiya I think what everyone is trying to say here is that the overflow checks are expected to be slower than not doing overflow checks. If you were compiling your code in 0.33.0 with -Ddisable_overflow and you want the same behavior for 0.34.0 then your only option is to stop using +, -, etc. everywhere and use &+, &-, etc.

1 Like

Doing testing on a more “quiet” system (limited background threads use) the time differences between 0.33 and 0.34 disappear, and are sameish. So that won’t make any difference, since overflow was occurring at only one place.

Plus if that really matters, then the default behavior should be to internally use the & wrappers for all the arithmetic symbols. If it’s always more accurate and faster to use &+ versus + why make users populate their code with the longer versions, in order to get more accurate/faster results?

But, the stripped binaries for 0.34 are always at least 20KB greater.

To test this, I compiled puts "Hello World!'', and the stripped binaries were: 0.33 - 393528 bytes and 0.34 - 397640, 4KB greater.

So, 0.34 inherently comes with more baggage vs 0.33, thus overall, offers no tangible benefits for running this specific code.

Not a criticism, just an observation for this one specific use case.

As you add more overall features/capabilities I would expect this to occur in a pre 1.0 development release. As long as there’s no significant performance or accuracy impediments I’m good with it. Rust binaries were “hugemongous” initially, until lately, so it’s par for the course.

It doesn’t matter where the overflow was happening. Whenever you use + or -, the runtime will check for overflow under the hood. So in your code, overflow checking is done everywhere except where you now use &-.

It’s not always more accurate. If you have a counter and it overflows, that’s usually an error. Say you are counting number of beds in a hospital with Int32. You really don’t want to end up with -2147483648 beds. That’s why + will raise by default, to prevent you from getting to that state.

In fact, it’s very unusual to want to have wrapping operators by default. Only in very specific bitwise or math situations you want that. Which might be your use case, but I’m not sure.

We never case about binary size because disk space is not a limited resource, much less 20KB (I know, I know, embedded systems, but that’s not our target).

Oh thit, I thought it was the other way around. Now what you said makes sense. That wasn’t clear from reading the docs/blog on this. Let me go back and change things to see the effect it will have.

I understand for desktops/laptops binary sizes aren’t a big issue, however they are if you’d like Crystal to be used in embedded systems where memory is a premium. That’s why Matz (with funding from the Japanese government) created MRuby, specifically for those environments.

Can’t reproduce this building on Ubuntu using Crystal’s default dockerfiles. What OS are you on and which test setup did you use?

$ echo 'puts "Hello World"' > test.cr
$ docker run --rm -it -v $(pwd):/app -w /app crystallang/crystal:0.34.0 crystal build test.cr -o test.34 --release --no-debug
$ docker run --rm -it -v $(pwd):/app -w /app crystallang/crystal:0.33.0 crystal build test.cr -o test.33 --release --no-debug
$ ls -l test.3*
-rwxr-xr-x 1 root    root    473696 Apr  9 00:25 test.33
-rwxr-xr-x 1 root    root    474016 Apr  9 00:25 test.34
$ strip test.33
$ strip test.34
$ ls -l test.3*
-rwxr-xr-x 1 root    root    392592 Apr  9 00:26 test.33
-rwxr-xr-x 1 root    root    392584 Apr  9 00:26 test.34
1 Like

Here’s the system and environment that produced the posted results.

➜  ~ inxi -MSC 
System:    Host: localhost.localdomain Kernel: 5.5.10-pclos1 x86_64 bits: 64 Desktop: KDE Plasma 5.18.4 Distro: PCLinuxOS 2020 
Machine:   Type: Laptop System: System76 product: Gazelle v: gaze10 serial: <superuser/root required> 
           Mobo: System76 model: Gazelle v: gaze10 serial: <superuser/root required> UEFI [Legacy]: American Megatrends 
           v: 1.05.08 date: 03/31/2016
CPU:       Topology: Quad Core model: Intel Core i7-6700HQ bits: 64 type: MT MCP L2 cache: 6144 KiB 
           Speed: 3100 MHz min/max: 800/3500 MHz Core speeds (MHz): 1: 3100 2: 3100 3: 3100 4: 3100 5: 3100 6: 3100 7: 3100 
           8: 3100 

hello_world.cr => puts "Hello World!"

For both 0.33 and 0.34

$ crystal  build hello_world.cr --release
$ strip hello_world

20KB for an executable that can’t accidentally overflow its arithmetic might be considered worth it…Do you want your math to accidentally be able to wrap, by default? This isn’t like in Ruby, where if it overflows it gets auto promoted…though come to think of it that would be an interesting class to have “AutoPromotableInt” or something, that moves to BigInt if it overflows. Or maybe BigInt is already efficient enough under the covers for that type of use and we could just use that :)

Here’s my size results in Ubuntu 19.04

hello_world 0.33 755040
hello_world 0.34 773248
hello_world 0.33 stripped 392544
hello_world 0.34 stripped 400736

It increased by a few percentage.

On OS X

hello_world 0.33 417656
hello_world 0.34 418328
hello_world 0.33 stripped 332264
hello_world 0.34 stripped 332264
hello_world.dwarf 0.33 418129
hello_world.dwarf 0.34 423462

So small percent increase again.
Doesn’t seem too extraordinary… :| Though overall still seems a bit large, would be a fun endeavor to try and figure out how to get it smaller, but I’m not too worried about it ATM. :)

Why the push toward 1.0?

This is from 2016, about the quest for the smallest Rust binary (Rust is inherently smaller now).

https://lifthrasiir.github.io/rustlog/why-is-a-rust-executable-large.html

Also FYI: mruby - about

1 Like

The huge portions of those binaries are really just stdlib baggage you don’t actually need for such a tiny program printing hello world. You can easily shrink it by not including stdlib but rolling your own.

1 Like

See Towards Crystal 1.0 - The Crystal Programming Language

2 Likes

Seems this was never posted on the forum, and perhaps very few people have seen it at all.

1 Like

Well, according to the comments at least 11 people outside the core team. And it was also posted on reddit with 80+ upvotes, so word should have made it around. :man_shrugging:

1 Like

From ysbaddaden:

I’m not fond of where this is all going. The nice & fun of Crystal is slowly eroding away :disappointed:

Well, that hurt to read.

What’s this issue with Exhaustive pattern matching for case stuff? Context.

If the developer doesn’t have the right type to match, that’s their problem. That’s not a issue of the language. Especially considering Crystal is statically typed… wait a minute… unions: hold my beer!

This is one of the downsides of open source. People want features that other developers don’t think are necessary. This cycle repeats itself too and is never-ending. There is nothing wrong with a language having core values that are set in stone, and having developers adapt.

What’s that supposed to mean? Unions are completely statically typed.

Also, it is quite normal for any project, whether it’s open source or not, that there are different opinions on the way to go forward. If we all shared the same opinion, it would be a sign there’s something very wrong!

Where can I find that remark from ysbabadden?

1 Like

Unions are not statically typed.

The type of a variable or expression can consist of multiple types.

Source

You just brought up another negative of open source. Assuming change is good…

@ganymedes here: https://github.com/crystal-lang/crystal/pull/8424#issuecomment-610808655

What does this mean?