On 2/17/13 9:14 AM, Jacob Carlborg wrote:
I find it very interesting. But actually I'm going to agree with Denis,
mostly. If I was going to use Crystal I would probably use a lot more
static typing than it's probably made for.

I quite often miss static typing in Ruby. Often there are functions that
are supposed to only work with a given type, I don't see why I shouldn't
explicitly write that type out then.

As I replied to Denis, you can specify type restrictions in functions and methods.

def foo(x : Int)
  1
end

foo "Hello" # Gives a compile error

It works similar to overloaded templates: you don't specify the type of the function, but which types you can give to it. In the case of Int, of course it will always just accept an Int. But you can specify for example

def foo(x : Enumerable)
end

And there's a special restriction, self, that will only match for the owner of the method. This is used for example in the Comparable module:

https://github.com/manastech/crystal/blob/master/std/comparable.cr


A couple of questions:

* Executable code at class level, is that supported? If that's the case,
when is it run? Example:

class Foo
   puts "asd"
end

I thought it was supported but it's not. It would be very easy to support it, but it would execute at run time, as if you had put it before the class declaration.

However, there's another thing I didn't mention in that wiki page and that is macros. You can write;

---
macro define_something
  "def something; 1; end"
end

define_something() # This defines the "something" method

something() # And this invokes it
---

Again, this is different from Ruby.

Macros are executed at compile time. You can pass arguments to them, and their type will be the AST node of the expression you give them. They must return a String (for now), and it will be mixed in the program (later we'll support returning AST nodes directly).

We use macros for attr_accessor and the like:

https://github.com/manastech/crystal/blob/master/std/object.cr

Just note that this is an experimental feature, and for now only variables, strings and symbols are allowed for macros.

Macros can execute arbitrary code and have access to what you defined in your program. That means they can open a file, read/write a database and so on. I believe this can be very powerful for metaprogramming.

(this is inspired mainly from Lisp)


* With a statically typed languages you quite soon get the need for
interfaces, abstract classes and similar. How is this handled?

If you don't need them in Ruby I don't see why would you need them in Crystal.

The only use of interfaces is to satisfy the compiler. But since Crystal is mostly duck-typed interfaces have no use.

Another use is probably performance, and we are still considering how to fit everything together. We are writing code in Crystal and see where it's slow, and think of the most little change that's not a burden for the programmer that can help speed up compilation times.


* Is Ruby code supposed to be able to run of out the box in Crystal?
That is can I take arbitrary Ruby code and compile it with Crystal and
expect it to work. If that's the case, what's currently supported and
what's not supported?

You probably won't have eval, define_method and so on. You will be able to do some of those things with macros, but it's not the same.

Most Ruby code should run out of the box, unless something is missing from the standard library.

For example I tried running this code:

https://gist.github.com/havenwood/4724778

(removing the Time.now lines, because we don't have that yet)

and it just worked. And it was much faster than all of the other languages.

Our idea was to make a language as similar as Ruby, not with the intention of compiling Ruby. But accidentally (or not :-P) it is happening, slowly.

Thanks for your comments and questions!

Reply via email to