Are ``then`` and ``of`` deprecated in crystal?

there are no use cases for then and of in the newest versions of crystal are they deprecated ?

Hashes can still be created like this using of:

foo = {} of String => Int32
foo["neat"] = 42

And then is still used with case statements when you just have a single line after the when/in.

case someVar
when 9 then doSomething
when 13 then doSomethingElse
else puts "Not 9 or 13"
end

case someEnum
in .foo? then puts "Foo!"
in .bar? then puts "Bar!"
end

case other
when 69
  puts "Not a single line on the same line after the 'when'"
  puts "So no 'then'"
end
4 Likes

No they definitely aren’t deprecated. What gave you that idea?

4 Likes

I find it interesting that then is only ever used in case and select statements, it would be nice if we replaced the current ternary operator with if..then..else, and it would make more sense since we can already use if statements as expressions.

1 Like

if a then b else c would be quite confusing as ternary expression compared to a regular conditional expression if a; b else c end considering the final end keyword. And it’s not even shorter, so really there’s no point in that. Just use the regular if.

2 Likes

I don’t see how it would be confusing, I often have trouble reading code like this: foo = bar? ? baz : qux which would be much more readable as foo = if bar? then baz else qux. Using a regular if statement forces extra whitespace by the formatter even when trying to use the semicolon form:

foo = if bar?
        baz
      else
        qux
      end

Also, you could make the same argument about inline[1] rescue expressions which (as far as I’m aware) aren’t even documented properly. Why not just use begin..rescue..end?


  1. I’m not actually sure what this form of rescue syntax is called, but it is “inline” with the current expression so that made sense to me. ↩︎

foo = bar? && baz || qux would also do the trick :S

EDIT: Kinda meant this as a joke, but if you find this syntax better than bar? ? baz : qux then :+1:.

4 Likes

Sure, then could be allowed as separator between condition and then branch.

But if you think about the general case, I think it is often a good solution to split this into multiple lines.
In your example you’re using very short identifiers. In most real use cases, they are likely much longer. Maybe calls with a receiver and arguments. At that point the additional overhead of writing out the keywords will make a poor fit for an inline expression. The ternary operator is concise, which makes it more useful. You don’t have to use it, of course. But I think the best alternative is most commonly a multi-line expression, rather than an inline condition with keywords.

1 Like

In the absence of ‘then,’ if statements lack a sense of ceremony, and it is hoped that ‘then’ remains an optional element

Ritual is more important than simplicity

Why did I choose Ruby over Python? It’s because Python, in its pursuit of simplicity, omitted ‘end,’ and it lost the ceremonial aspect of programming.

OK, haven’t heard that one before. I gather that you don’t use and editor that automatically adds an end when typing do?

@Xen
The sense of ceremony is not only in writing, but also in reading

If the conditional part spans multiple lines, I think it would be easier to read if there was then. Without
then, the conditional part may be enclosed in parentheses.

Someone who think then is redundant/unnecessary would also think that elsif is unnecessary because

if condition1
block1
elsif condition2
block2
else
block3
end

could be replaced with

if condition1 {
block1
} condition2 {
block2
} else {
block3
}

I think this type of simplification leads to lisp-like syntax. I believe that then and elsif is necessary for readability. (Because of the same reason, I believe that for i in a do block end is necessary.)

1 Like

Oh, indeed… Python kinda feels like it’s constantly stopping mid-sentence, doesn’t it?

But then feels archaic to me. I wouldn’t say “if they have eggs, then buy 2”, but rather “if they have eggs, buy 2”. In a one line context, using a semicolon works for me. And I think I’d rather write when 7; puts "seven" than when 7 then puts "seven".

But isn’t it a bit inconsistent that if a; b else c end doesn’t require a semicolon before else? And, well, technically end too?

I practice, I use the ternary operator in one-line conditions, or the if/unless suffixes.

2 Likes

I think it depends on background/context. In the UK you would use if ... then in a formal context and omit it in informal contexts (which would be the equivalent of if ...;).

It’s also worth pointing out that if a then b else c is not the same thing as if a; b else c end so this wouldn’t be the removal of the latter syntax because they are two separate expressions. case statements similarly support this: you don’t have to use when a then b, you can also do when a; b or the more popular newline format.

2 Likes

if...then feels like Pascal to me, a bit too verbose with extra unneeded keywords, and also complete with the possibility of a dangling else because you forgot a begin and end.

if var1 <> var2 then begin
  func1
  func2
end else if var1 = 69 then
  func3SingeLineOnlySoNoBegin
else
  func4AlsoSingleLineOnly;
// No end needed because it's a single line

For a single line, either a ternary operator with some parenthesis for visual separation, or a suffixed if/unless looks perfectly readable to me.

To reiterate what I said earlier:

so your code example would be equivalent of this in Crystal:

var1 == var2 ? begin
  func1
  func2
end : var1 == 69 ? func3SingleLineOnlySoNoBegin : func4AlsoSingleLineOnly

You wouldn’t write code like this in Crystal, you would use an if statement. They cover different use-cases, and for a language that is meant to be read like English, I think it makes more sense to have if..then..else which has better visual representation compared to my initial example.

It is acceptable for me if condition then block1 else block2 end is replaced with if condition do block1 else block2 end. We could include the syntax without adding the keyword then

(DELETE: I did not read the beginning of this thread carefully.)

(DELETE: This paragraph was a bit of a detour, so I’ll write it again.)

Although if condition; block1 else block2 end is acceptable in Crystal/Ruby/Einglish, I feel something beautiful/comfortable/consistent in the expression if condition then/do block1 else block2 end. I never use the ternary operator because it is not Crystal/Ruby-like.

This seems similar to this previous discussion

except in the opposite direction (the inclusion of keywords vs their removal).

I think anyone coming to any language (human or software) has to be willing to learn it to become convsersant in it to other people using it. There are many ways to express ideas in a language. Some give you more options than others to say essentially the same thing. Sometimes this is good, but it may be abused when clarity isn’t the real goal.

“There is no greater impediment to the advancement of knowledge than the ambiguity of words.” - Thomas Reid

Here I feel, as someone who came from Ruby, the syntax feels familiar and consistent with past experience. What I had to learn unique to Crystal was mostly based on idioms necessary to program in a compiled language paradigm. But that wasn’t a big deal because I knew a little C, C++, etc, so these concepts weren’t new to learn.

Here the developers of Crystal made certain decisions, based on their preferences, which you wish to extend to meet your preferences. I guess the things they have to determine are 1) does it make the language easier to write, 2) does it make it easier to read, 3) does it make it perform better.

I don’t see this proposal affecting 3).

So it seems it’s just a matter of satisfying 1) and 2) to them.

I don’t think the devs are going to (need to) go through the effort to change the language to accommodate these changes, with the finite amount of time, energy, and resources needed to do other things.

Sometimes you just have to say to yourself, is the language useful (and nice to use) the way it is, warts and all, or do I wait for it to meet my concept of perfection (or even just much better) until I use it?

I would just say, don’t let perfection be an opponent of utility.

6 Likes

unless has a special place in my heart. It’s superfluous, longer than if ! and even if not, but it comes with the message “I’m going to spend a few extra keystrokes just to make this ever minutely easier to read for you”. Which is a lovely sentiment in a sea of languages that insists that there should only be one form of conditional.

I kinda dig @Devonte’s argument, if a then b else c does look nice, but I’m also very wary about adding new syntax, as it is changing the language.

2 Likes

(My previous post was a bit of a detour, so I am writing it again.)

I think that ease of writing and reading depends on a person and a situation. The language could be flexible to satisfy many users and situations.

We can have the flexibility by using a powerful macro as introduced in lisp. Users can define a new syntax by themselves to satisfy their request. However, the powerful macro might be dangerous because it diverges the language.

Because then/do has already been a keyword, I think that the addition of optional if then/do syntax does not get in the way of others.

Personally (I mean that it is unnecessary for the developers to accept my opinion), I expect Crystal/Ruby to be also a pseudo code language. To be a pseudo code language, algorithms should be written formally, where verbosity is preferred over brevity. Of course, lisp is an alternative (opposite side) pseudo code language. I respect both languages.

1 Like