Skip to content
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

[Experimental] Platform dependent int #9617

Closed
wants to merge 26 commits into from

Conversation

asterite
Copy link
Member

For #8111

Why?

As our ongoing quest to find the optimal language with also avoiding a massive breaking change, we discussed trying out the experiment of introducing a platform-dependent Int type.

What's Int?

Here Int is a different type than any other int type, meaning you can't pass an Int64 where an Int is expected.

However, this is based on #9569 and since Int will be represented as Int32 or Int64 depending on the platform, any int type that fits inside Int32 can be automatically passed to Int. That means an Int32 variable can be passed to an Int restriction.

Given that most of the restrictions in the stdlib are Int, and because Int32 is the usual default int type used everything, changing this has a low chance of breaking everyone's code, assuming the std is fully migrated to this new approach.

How to implement this?

Implementing this is a bit tricky. One problem is that Int is currently the base type of all ints. Now we want another base type, namely IntBase to serve that purpose, and Int to be a subclass. This information is deeply embedded in the compiler so we must change that there. But we also need to change the stdlib code that assumes these things.

To accomplish that there's a new compile-time flag, platform_dependent_int that will be true when compiling the new compiler (so you don't need to pass it), but obviously it's false in the current state. With that flag we can control what the stdlib looks like.

To make things easier we introduce a couple of aliases:

  • IntBase: well, this is actually the base type if platform_dependent_int is true, and it's aliases to Int if it's false
  • DefaultInt: this is Int when platform_dependent_int is true, and Int32 when it's false

Also, the type of an integer literal like 1 or 123 is now Int in the new approach.

Next I tried compiling an empty program. That already didn't compile and so I started changing a lot of Int32 to DefaultInt. That means we aren't changing anything if platform_dependent_int is false, but we are making it be Int if the flag is on. Eventually I managed to compile an empty program (with the default prelude and runtime), so this already works fine:

[10, 20, 30].each_with_index do |x, i|
  puts "#{x}) #{i}"
  p! typeof(x), typeof(i)
end

Obvious output:

10) 0
typeof(x) # => Int
typeof(i) # => Int
20) 1
typeof(x) # => Int
typeof(i) # => Int
30) 2
typeof(x) # => Int
typeof(i) # => Int

Oh, a small note: for now Int is actually implemented a Int64 regardless of the platform, just to make things easier for me. Changing that to Int32 is very easy.

Another note: to_i now returns Int (or, well, DefaultInt), but to_i32 returns Int32, and these, again, are different types.

Next I started to try compiling and running the std specs. So far I got int_spec.cr and string_spec.cr down. But making things work is very easy! You just try compiling something and the compiler will guide you.

How to use it?

Run make clean crystal, then you can do bin/crystal spec spec/std/string_spec.cr and see it pass.

What's next?

I'll be continuing to make more and more code compile. I expect this will be a huge diff. Also, don't expect this to go out soon, or even, because it's just an experiment. And I'll do this slowly if I have time.

Rant

I wish we could push branches here. That way I could make a PR that targets that branch and the commits here will be cleaner. I see no reason why we have to restrict ourselves like that. /cc @waj @bcardiff

asterite and others added 26 commits July 3, 2020 19:13
Co-authored-by: Sijawusz Pur Rahnama <sija@sija.pl>
* Hide Channel internal implementation methods
* Add private/nodoc to more methods and types
* Remove deprecated Channel#select
* Array rotate optimization

Add special case for array rotate to optimize for small arrays.

* fix typo in docs

* rotate tmp array is now populated with filler

* fix if statement in array#rotate! to use else

* use uninitialized StaticArray for array#rotate! optimization

* run crystal formatter

* use case statment to optimize array#rotate!

* fix formatting issue

* update array#rotate docs

* make array#rotate docs easierto read

* add comment for ignore block

* add large array for array#rotate

* use if statment over case statment

* add tests for array#rotate!

* change array#rotate! to check for size - 1

* add comment for shifting in array#rotate!

* update docs

* remove comments
* HTTP::Params: `#[]=` replaces all values.

* Fix HTTP::Request specs
@asterite asterite changed the title Platform dependent int [Experimental] Platform dependent int Jul 18, 2020
@waj
Copy link
Member

waj commented Jul 18, 2020

@asterite feel free to push branches. I just suggested that we don't do it by default for every feature/fix branch we create for our PR's. But in specific circumstances like this one, where you might want to split the work differently or receive contributions to your branch, let's do whatever is more appropriate.

@asterite
Copy link
Member Author

Closed in favor of #9619

@asterite asterite closed this Jul 18, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants