Crystal: Disallow question mark (?) and exclamation mark (!) at the end of the LHS in an assignment.

Created on 8 Sep 2018  路  11Comments  路  Source: crystal-lang/crystal

module M
  @@x? = nil # => Syntax error: unexpected token: =
end

class C
  def initialize
    @x? = nil # => Syntax error: unexpected token: =
  end
end
help-wanted bug topicparser

Most helpful comment

If voting is a thing, then I vote option 1 lol. x? = 1 feels like dipping pizza in mayo.

All 11 comments

@dawkot I'm pretty sure this is expected behavior. The question mark is used at the end of a method to notate that it returns a boolean value, or used in the case of returning nil as opposed to throwing an exception like in the case of an array x[0]? or active?. It doesn't really make sense with a variable since you're assigning the value and not questioning if the value will exist, or if it's returning a boolean.

This works at the top level, with e.g. x? = 1.
It can be a good to have for ivars/cvars too, specially for class macros like property enabled? = true.
The property?, getter?, setter? macros could be removed then.

Ok setter? doesn't exist.
Does the class macros ending with ? only adds a ? to the method, compared to the non question mark variant?!

This doesn't work and it's expected behaviour. The actual bug is that x? = 1 is allowed (it isn't allowed in Ruby). The ? and ! suffixes are exclusively for method calls, not for variables.

Did we make that valid for setter x? = 1or something perhaps?

I think it's a side-effect of how the parser works. We never designed it specifically, it just worked from the beginning.

There are two options:
1) Forbid names ending with ? for every type of variables
2) Allow it everywhere, thus reducing the need of having setter? var and property? var since we will be able to use setter var? and property var?

If voting is a thing, then I vote option 1 lol. x? = 1 feels like dipping pizza in mayo.

I personally liked the ? syntax:

x? = rand > 0.5 ? 1 : nil

if x = x?
  puts x
end

It was also useful for nilable arguments:

def foo(x x? : Int32? = nil)
  if x = x?
  end
end

It worked well in those cases when thinking of non-nil variable name variant is hard. For example, if user = user? is easier than if the_user = user or if non_nil_user = user.

@vladfaust You don't need separate variables in the first place:

x = rand > 0.5 ? 1 : nil

if x
  x + 1
end

Local variables are effectively restricted by if var. The pattern if var = ... is only required when the value comes from a non-local variable.

Can be closed now that #7582 is merged.

Was this page helpful?
0 / 5 - 0 ratings