New crystal release: 0.15.0
- (breaking change) ! has now its meaning hardcoded in the language. If you defined it for a type it won't be invoked as a method anymore.
- (breaking change) nil? has now its meaning hardcoded in the language. If you defined it for a type it won't be invoked as a method anymore.
- (breaking change) typeof is now disallowed in alias declarations
- Added crystal tool format --check to check that source code is properly formatted
- crystal play (playground) added workbooks support, as well as improvements and stabilizations
- Added Tempfile.dirname (thanks @DougEverly)
- Added Path#resolve method in macros
- {{...}} arguments to a macro call are now expanded before macro invocation (#2392)
- Special variables ($~ and $?) are now accessible after being defined in blocks (#2194)
- Some bugs and regressions fixed
What this means for the language:
Hard coding ! and nil? allows the language to be more flexible and more ruby like. Not to mention is fixes some trivial compile errors that some people may often overlook.
For instance say we want to find the occurrence of a sub-string inside another string, or print "Not found" if not found.
Code
# `String#index` returns an Int32 if the index is found, or Nil if not
index = "some_word".index(ARGV[0])
if index
puts "Found at character number #{index + 1}"
else
puts "Not found"
end
The way the compiler interpreters this code is that if index is a truthful value (not nil, false, or null pointer) then the value of index inside the "then" branch can only be of type Int32, so the operation "index + 1" compiles fine.
Code
index = "some_word".index(ARGV[0])
if !index
puts "Not found"
else
puts "Found at character number #{index + 1}"
end
In this segment of code, which does the exact same thing has a flaw though due to the ! (and also the .nil? method) which is that they were able to be user definable. Compiling this code would result in:
Code
Error in ./file.cr:14: undefined method '+' for Nil (compile-time type is Int32?)
puts "Found at character number #{index + 1}"
Logically in the "else" branch to us, there is no way index can be nil due to the ! operator however because ! was able to be user redefined the compiler could not make that guarantee that ! actually meant what ! used to be. For instance, if someone redefined ! for what ever reason to be a double not (!nil is true, !!nil is false) then it was possible to fool the branch logic into executing the "else" branch which would in turn cause all kinds of problems when a nil value had the addition applied to it.
So to fix this, they hard coded the behavior of ! and .nil? so that they can not be user redefined and this allows constructing logical statements easier since now you don't have to work around compiler quirks to get your code to compile.
This post was edited by AbDuCt on Apr 3 2016 10:00am