RFC: variable declaration syntax using `:=`

That’s completely understandable. While Crystal is pretty sweet as-is, need to be careful about not making the language too sweet :slightly_smiling_face:.

There are definitely higher priorities than this, just thought it would be useful to explore different ways of embedding developer intent into the source code, as it helps to stave off unexpected behavior and bugs.

Long soliloquy incoming, I apologise.

they can be quite burdensome for newcomers

As someone who started using crystal relatively extensively as a hobby coder last year, with very little prior coding experience, I think I’m uniquely qualified to chime in on this :DD

As you pointed out, having dozens of different notations, keywords etc is really challenging for people starting out, particularly with little coding experience, because it increases the complexity significantly.

With that being said, the Crystal team has done a phenomenal job with the language. At no point did I feel like syntax sugar was introduced just for the sake of “being cool”. There was always a clear intent and reasonable thought process behind it. The language has been a joy to learn and this intuitive syntax sugar is what makes it so fun for me.

In that same vein, := follows a very logical derivation of the underlying syntax.

# Define a variable with inferred, open Type
x = 5 # x is Int32, but can change.

# Define a variable with fixed, explicit Type
x : Int32 = 5 # x is Int32 and cannot change.

# Based on this, any of the following are logical,
# intuitive steps for the inferred, yet fix Type
x : _ = 5
x : = 5
x := 5

None of the above are are pulled out of thin air, and anyone starting out with the language can see how it’s derived with relative ease.

TL;DR: I think Crystal is the best language precisely because it has a lot of syntax sugar, but they’re all very intuitive, easy to learn and convenient to use.

7 Likes

:heart:

1 Like

That’s a really good point :ok_hand:

4 Likes

This syntax is interesting, and I think writing it myself would be enjoyable.

However, if a library used this syntax, I might not like the code very much.

In my opinion, managing types too strictly is not always helpful for library users or those who want to reuse the code. While specifying every type might reduce mistakes for developers, it can make the library less flexible and harder to use when small type differences occur.

For others reading the code, it’s easier to understand if types are written explicitly when they need to be specified.

This might just be my hesitation toward new things. I won’t know until I actually try using it…

Using a compiler-backed annotation is also possible. I don’t think a new syntax is necessary here.

Could you elaborate on that?

As RFC: variable declaration syntax using `:=` - #22 by Barney demonstrates, the proposal isn’t completely new syntax, but a derivate of existing syntax.
So I think the level of barrier is lower than for introducing a completely new syntactical concept.

While I don’t think this would be an issue for what you’re talking about with local, instance, and class vars (the first not being something you’ll interact with much in a library, and the latter only allowing type changes within the classes they’re defined), I do see how this could be a problem for parameters:

def to_s(io := STDIN)
  io << "hello world"
end

io would be inferred to be IO::FileDescriptor instead of the general IO class, and not allow any other types that would usually fit (like IO::Memory, etc). I think this is just part of the tradeoff / balance between duck typing and full typing, where duck typing can be nice and allows more flexibility, but full typing allows for better semantic errors and can make code easier to understand. I don’t think this is a dealbreaker though, just something library developers should keep in mind.

5 Likes

Making it harder to write code, like requiring types to be written explicitly, is a way to make everyone write readable and consistent code. This is more common in Python than in Ruby. In Ruby, Matz prefers to give users freedom and often says, “With great power comes great responsibility.”

I think this syntax is interesting, and I would probably use it a lot if it were added. But I wonder if this would really make the code easier for others to read or reuse. If the community develops good practices, it might not be a problem. If this syntax is introduced, the community will probably discuss how to use it in the best way.

1 Like

That’s completely fair. Using := in documentation may have things show up with typeof(...), which is definitely not as readable as listing the type explicitly.

Ameba 1.7.0 will have rules to enforce method parameter / return type restrictions and type restrictions for getter / setter / property calls (off by default), which should help the community push more towards explicitly typing things.

4 Likes

I dont think that should happen.

Granted, this is my hacky implementation that is just syntactic sugar for : typeof(...), but this is what happens currently on my branch:

class MyClass
  getter name := "George"
end

If by “should” you mean that the behavior of the docs generator should be that the typeof(...) is resolved to the actual type, fair enough, that should be possible / straightforward

Ah no I guess it won’t be straightforward because it would require semantic analysis for resolving the typeof. The doc generator doesn’t do that.

I really like this too!, if we add :=, i thought it can do far more than expected, need more discussion.

Want to mention cr-source-typer shards here, discuss:

And the efforts for try to add into Crystal, PR

It can add all types for method args and return value automatically, I really like it when write Crystal shard

2 Likes

Thanks for the shout out! Due to the holidays and life in general, that PR has been languishing lately, and I’m running out of improvements to do for it (also may be falling into that trap of infinite polish that devs sometimes do…). I’ll get that PR out of draft state and subject it to the masses officially :)

I’m really glad to hear that ameba will be adding some linting rules to help with this effort, too. A lot of benefits for explicitly typing everything for even mildly complex projects.

2 Likes