February 17, 2013
On 2/17/13 6:29 AM, Denis Shelomovskij wrote:
> I'd like to specify function attributes explicitly because I do want to
> get a compilation error when I e.g. use non-safe stuff in safe function
> instead of a just compiler silently changing the function (and all
> functions which use it) to unsafe.=

It's something I didn't have time to write in that wiki page, but you can restrict the types of a function.

def foo(x : Int)
  1
end

foo "Hello" # Gives a compile-time error

This is similar to what you can do with D templates. You can also restrict an overload an use another one unrestricted and it will choose the correct one:

def foo(x : Int)
  1
end

def foo(x)
  2
end

foo "Hello" # Chooses the second one

So theoretically you can type everything you want. We might also support typing a variable in order to disallow it to change to another type (I think this is what is done in the Julia language).

>
> Now about argument types. I do not understand the purpose of dynamic
> typing at all and consider such languages too dangerous to use in real
> projects.

In the place I work we've written several web applications and programs in Ruby and they work just fine. We writes lots of test units to make sure everything works (you don't have another option, really, with dynamic languages).

> Sorry for such cruel comment, I it is just my opinion.

It's not cruel at all. I really appreciate your comments.


February 17, 2013
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!

February 17, 2013
> Have you looked into Ruby Motion or Mirah as well?

Ruby Motion is not open source, so we couldn't (or didn't want) to take a look at that.

Mirah compiles for the JVM, and we want to compile to native code. We try to escape from virtual machines...
February 17, 2013
Am 17.02.2013 17:41, schrieb Ary Borenszweig:
>> Have you looked into Ruby Motion or Mirah as well?
>
> Ruby Motion is not open source, so we couldn't (or didn't want) to take
> a look at that.
>

I know, the question was more in the value proposal kind of way.

> Mirah compiles for the JVM, and we want to compile to native code. We
> try to escape from virtual machines...

Currently yes, but there have been discussions to get it to compile to native code via LLVM.
February 17, 2013
On 2013-02-17 17:34, Ary Borenszweig wrote:

> 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

Yeah, I saw there's explicit static typing.

> 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

So in that case "self" would evaluate, at compile time, to whatever Comparable is mixed in to?

> 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.

That code will be executed as soon as the file has been loaded using "require"?

> 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
> ---

Yeah, I saw that.

> 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)

This looks cool.

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

You don't need them in Ruby because it's dynamically typed.

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

But it does support explicit static typing. It doesn't look easy to restrict a method for a given type for something like an interface. So what will happen is one use duck typing and it will basically be the same as templates without constrains.

> 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.

I see.

-- 
/Jacob Carlborg
February 17, 2013
On Sunday, 17 February 2013 at 12:14:40 UTC, Jacob Carlborg wrote:
>
> Except from what others already have mentioned someone created a language with a Python like syntax written in D. But I think that had explicit types.
>
http://delight.sourceforge.net/
February 17, 2013
On 2/17/13 4:09 PM, Jacob Carlborg wrote:
> On 2013-02-17 17:34, Ary Borenszweig wrote:
>
>> 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
>
> Yeah, I saw there's explicit static typing.
>
>> 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
>
> So in that case "self" would evaluate, at compile time, to whatever
> Comparable is mixed in to?

Yes.

>
>> 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.
>
> That code will be executed as soon as the file has been loaded using
> "require"?

Since it's not yet implemented, it could be like that, or it can be that it is evaluated when you execute the program (but not at compile time).
February 17, 2013
On 2013-02-17 21:22, Ary Borenszweig wrote:

> Since it's not yet implemented, it could be like that, or it can be that
> it is evaluated when you execute the program (but not at compile time).

But if I just but code that the top level of a file, when at runtime is that executed?

-- 
/Jacob Carlborg
February 17, 2013
On 2013-02-17 20:50, JN wrote:

> http://delight.sourceforge.net/

There we go, thanks.

-- 
/Jacob Carlborg
February 18, 2013
On 2/17/13 5:46 PM, Jacob Carlborg wrote:
> On 2013-02-17 21:22, Ary Borenszweig wrote:
>
>> Since it's not yet implemented, it could be like that, or it can be that
>> it is evaluated when you execute the program (but not at compile time).
>
> But if I just but code that the top level of a file, when at runtime is
> that executed?

In the order it was analyzed. Same as in Ruby.