Last active
August 18, 2016 16:49
-
-
Save paddor/cb5325517ff2e605828841f8a4b47f7c to your computer and use it in GitHub Desktop.
from Ruby to Crystal
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from Ruby to Crystal: | |
* compiled to one binary | |
* (optional) type restrictions | |
* there's a class Bool (values are true and false) | |
* Nil is the type of nil (not NilClass) | |
* very DRY: def initialize(@name) | |
* nice way to avoid alias_method_chain: previous_def | |
* @@var is valid only in that class and its instances, not subclasses | |
* file-global functions can be called from within a method (foo() or explicitly ::foo()) | |
* Strings are immutable and always UTF-8 | |
* "..." are string literals, but not '...' ('a' is a Char as in C/C++) | |
* multi-line, indented String-literal with escaped newlines automatically undents (all leading whitespaces are removed) | |
* fancy strings only with %(...), %[...], %{...}, and %<...> | |
* there is Tuple and NamedTuple which are fixed-size, immutable, and stack-allocated | |
* only one Hash syntax: { :bla => "bli", "foo" => "bar" } ({ bla: "bli"} is a NamedTuple) | |
* regular parameters can be given as named parameters in any order (def foo(a,b) ... end; foo a: 5, b: "baz") <3 | |
* internal/external argument names: def increment(value, by amount) value + amount end; increment(5, by: 3) | |
* method overloading, depending on number of positional parameters, their types, block given or not, and even named parameters <3 | |
* there is #finalize <3 | |
* Go-like channel (Channel) for communication between green threads (#spawn) <3 | |
* "with obj yield", e.g. "with self yield" will set a special object as default receiver for methods inside the block | |
* there's struct (a inherits from Struct < Value < Object, whose instances are stack-allocated and are passed by value) | |
* otherwise a class inherits from Reference < Object, whose instances are passed by reference) | |
* private/protected are prepended to def: private def foo(bar : Bar) | |
* there's no "public" keyword, since it's the default | |
* protected means: caller is either of same type or in same namespace | |
* private top-level methods are only visible in the current file | |
* Object is the hierarchy root | |
* explicit return type of method, if needed, at the end of the signature (not like in C/C++/Java) | |
* there's no String#to_sym, as all Symbol's of the program are known at compile-time, and each one will be a Int32 | |
* there is enum (abstract struct Enum) | |
* there is Pointer and Slice | |
* there are abstract classes and abstract methods | |
* lib, alias, ifdef, fun, ...: syntax for writing C bindings built-in | |
* no uppercase methods (??) => Channel(String) is generics syntax (a Channel for String objects) | |
* green-threads (Fiber's) only, so far | |
* #map &.name.upcase (more flexible than &:name in Ruby, it's chainable) | |
* $var are file-global (??) | |
* $var, @var, @@var have to be typed (or initial type-deducable value given) | |
* []/{} has to be typed (compiler can't infer type of nothing) | |
* there are marcros, and ifdef | |
* method API doc is copied from above if it's "ditto" | |
* record Entry??? | |
* LibC | |
* there are macros, and they're very powerful | |
* getter/setter/property (macros) instead of attr_reader, attr_writer, attr_accessor | |
* there are macro defs, which are methods defined in a superclass with something in their body be replaced by the actual subclass | |
* String#camelcase | |
* no "and" or "or", only && and || | |
* heredocs are always of form "<<-EOF", so closing delimiter can always be indented; automatically undents content as much as the closing delimiter is indented | |
* break (and return?) inside a block return from the method that yielded | |
* next inside a block just returns from the block | |
* break and return can't be used inside a captured block (Proc object) | |
* procs from method: instead of ->{ meth }, just ->meth, even on explicit receivers (if method takes args, types must be specified): p = ->str.count(Char); p.call('c') | |
* no while/until statement modifier | |
* no "do ... end while <condition>" (just do "loop do ...; break unless <condition>") | |
* mandatory parenthesis around arguments when defining a method to avoid ambiguity (e.g.: def foo(bar) : Bool) | |
* no aliases: no Enumerable#inject (only #reduce), no Enumerable#collect (only #map), not sure about #find/#detect and #select/#find_all | |
* no String#length, only #size, same for Array | |
* not only #[], but also #[]? which could return nil if index inexistent (#[] would raise) | |
* raise "msg" raises Exception | |
* syntax "raise Klass, msg" doesn't exist. it's just "raise Klass.new(msg)" | |
* there's no $! in the rescue block, just catch it like this: "rescue e : Exception" | |
* PCRE is used instead of Oniguruma | |
* fancy regex syntax: %r(...) or %r{...} or %r[...] or %r<...> | |
* there are 'inherited', 'included', 'extended', and 'method_missing' hooks (as macros) | |
* forward_missing_to macro | |
* there's only require, but it's intelligent: "foo" requires "foo" or "foo/foo.cr" from require path, "./foo" is like require_relative, and "foo/*" and "foo/**" work as expected |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment