# Var &= .method

**URL:** <https://forum.crystal-lang.org/t/var-method/301>\
**Category:** Crystal Contrib\
**Created:** [January 17, 2019, 10:29am UTC](https://forum.crystal-lang.org/t/var-method/301 "2019-01-17T10:29:12Z")\
**Posts on this page:** 12\
**Page:** 1

<div class="post-metadata">

**Author:** ![vladfaust](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/vladfaust/32/48_2.png) [@vladfaust](https://forum.crystal-lang.org/u/vladfaust)\
**Post date:** [January 17, 2019, 10:29am UTC](https://forum.crystal-lang.org/t/var-method/301/1 "2019-01-17T10:29:12Z")

</div>

There are some situations when this code would be great to work:

```crystal
foo = "foo"
foo &= .upcase if rand > 0.5
pp foo

```

It works for String and Number concatenation, however, `+` and `-` are just methods as well, so why not letting the syntax be more sweet with `&=`?

Just to be clear, the code above should expand to

```crystal
foo = foo.upcase if rand > 0.5

```

---

<div class="post-metadata">

**Author:** ![vladfaust](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/vladfaust/32/48_2.png) [@vladfaust](https://forum.crystal-lang.org/u/vladfaust)\
**Post date:** [January 19, 2019, 12:57pm UTC](https://forum.crystal-lang.org/t/var-method/301/2 "2019-01-19T12:57:53Z")

</div>

WDYT, Crystallers?

---

<div class="post-metadata">

**Author:** ![vlazar](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/vlazar/32/31_2.png) [@vlazar](https://forum.crystal-lang.org/u/vlazar)\
**Post date:** [January 19, 2019, 4:18pm UTC](https://forum.crystal-lang.org/t/var-method/301/3 "2019-01-19T16:18:36Z")

</div>

Wouldn’t it make code harder to parse at least for humans?

Compare this straightforward to expand example (you don’t need to think about `right` side here, the `&=` defines the expansion):

```auto
left &= right
left = left & right

```

This is confusing however (the `&` and `.` come from different sides, and if there is `.` at the right side it expands differently now, and what’s worse the end result is not related to `&` operator at all):

```auto
left &= .right
left = left.right

```

Just from “looks good” standpoint it feels like your idea to shorten the code can be written as:

```auto
left .= right
left = left.right

```

However the `.` is not even an operator to begin with.

Using `left &.= right` probably looks even weirder.

---

<div class="post-metadata">

**Author:** ![bew](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/bew/32/113_2.png) [@bew](https://forum.crystal-lang.org/u/bew)\
**Post date:** [January 26, 2019, 3:38am UTC](https://forum.crystal-lang.org/t/var-method/301/4 "2019-01-26T03:38:06Z")

</div>

I’m not a fan of `foo &= .something` as `&=` is already an operator:

```auto
foo &= expr
foo = foo & expr # expanded

```

It would be confusing to have the same operator for 2 entirely different things… (AND binary operator, and short method calling)

* * *

Also `left &= .right` and @vlazar 's `left &.= right` looks like a call to left: `left(&.=(right))`, with the former being a weird typo…

@vlazar `left .= right` doesn’t look ‘right’, we can’t see the relationship between `left` & `right`…

* * *

Another idea idea would be a `=` pseudo operator/method that takes a block:

```auto
foo = &.upcase
foo = foo.upcase # expanded

```

I like this syntax because it looks like crystal!! And I think it’s quite easy to guess what it does.

---

<div class="post-metadata">

**Author:** ![vlazar](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/vlazar/32/31_2.png) [@vlazar](https://forum.crystal-lang.org/u/vlazar)\
**Post date:** [January 26, 2019, 6:47am UTC](https://forum.crystal-lang.org/t/var-method/301/5 "2019-01-26T06:47:18Z")

</div>

> [@bew](#):
>
> @vlazar `left .= right` doesn’t look ‘right’, we can’t see the relationship between `left` & `right` …

@bew Not sure what you mean by “we can’t see relationship”. Visually it’s exactly the same rules as for `left += right` or any other operator, just ignore the spaces. Well also ignore that `.` is not an operator:

```auto
left += right
left = left + right # expanded

left .= right
left = left.right # expanded (plus spaces removed)

```

That being said I’m not sure this is a good idea as removing spaces and ignoring the “not operator” part doesn’t feel very consistent.

For your example with `foo = &.upcase` it’s easy to guess what it does, but `&.` now has quite clear semantic for blocks and overloading it with expansion syntax for assignment might not be a good idea as well.

Side note: I never made any language or part of it, I would guess there are tons of ways the introduction of some syntax might look very appealing on the surface but complicate language implementation exponentially.

It would be much more interesting to hear opinion on this matter from someone who has expertise on this. Maybe @asterite can chime in here and tell the kids why this is a terrible idea? 😉

---

<div class="post-metadata">

**Author:** ![asterite](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/asterite/32/60_2.png) [@asterite](https://forum.crystal-lang.org/u/asterite)\
**Post date:** [January 26, 2019, 11:37am UTC](https://forum.crystal-lang.org/t/var-method/301/6 "2019-01-26T11:37:49Z")

</div>

I think `left .= right` expanding to `left = left.right` is the most intuitive syntax.

That said, I’m not sure this is that common or useful. And with this I mean “implementing it might be easy, but without carefully thinking about it it might interact badly with other features or even prevent us from using that syntax or that operator for something else in the future”.

---

<div class="post-metadata">

**Author:** ![bew](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/bew/32/113_2.png) [@bew](https://forum.crystal-lang.org/u/bew)\
**Post date:** [January 26, 2019, 12:18pm UTC](https://forum.crystal-lang.org/t/var-method/301/7 "2019-01-26T12:18:40Z")

</div>

I disagree for `left .= right`, what I mean by not seeing relationships is that it looks like a call to a **top level** `right` method and even worse imo it looks like a call to `=`: `left.=(right)`, which doesn’t make sense.

I agree `.=` would be kinda consistent with `+=` expension logic, but to me it’ll do much more bad than good because it’s inconsistent / conflicts with the current call syntax

---

<div class="post-metadata">

**Author:** ![vlazar](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/vlazar/32/31_2.png) [@vlazar](https://forum.crystal-lang.org/u/vlazar)\
**Post date:** [January 27, 2019, 5:44pm UTC](https://forum.crystal-lang.org/t/var-method/301/8 "2019-01-27T17:44:12Z")

</div>

Yeah. Syntax is very important, that’s why we love Crystal. But it’s also very hard and requires careful thinking.

---

<div class="post-metadata">

**Author:** ![mavu](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/mavu/32/213_2.png) [@mavu](https://forum.crystal-lang.org/u/mavu)\
**Post date:** [January 27, 2019, 7:07pm UTC](https://forum.crystal-lang.org/t/var-method/301/9 "2019-01-27T19:07:08Z")

</div>

Just to throw that out there:

Ruby has method + ! as a sytax for I will modify my caller.  
This could be interpreted without too much of a stretch as such:

```auto
a = a.split 
a.split!

```

Theoretically this would remove the ! from being a legal character in method names.  
Also, major disclaimer, I have no idea of language design, I have not thought this through at all, and I’m not even sure I like it all that much, Just though to mention it as a option.

---

<div class="post-metadata">

**Author:** ![girng](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/girng/32/127_2.png) [@girng](https://forum.crystal-lang.org/u/girng)\
**Post date:** [January 27, 2019, 7:28pm UTC](https://forum.crystal-lang.org/t/var-method/301/10 "2019-01-27T19:28:01Z")

</div>

`&` reminds me of the bitwise operator in an if statement. then when I see the **foo &= .upcase** part, it makes my head explode ![](https://yyz2.discourse-cdn.com/flex036/uploads/crystal_lang/original/1X/2e216665936c2d671cb233332b3caade0e355cf6.gif)

I really like

> foo = foo.upcase if rand \> 0.5

it’s just so simple and easier to read (IMO)

---

<div class="post-metadata">

**Author:** ![jhass](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/jhass/32/1779_2.png) [@jhass](https://forum.crystal-lang.org/u/jhass)\
**Post date:** [January 28, 2019, 10:39am UTC](https://forum.crystal-lang.org/t/var-method/301/11 "2019-01-28T10:39:11Z")

</div>

IMO this is a non-issue, not worth to solve it. The expanded version is easy to follow, doesn’t require to learn any new concepts and thanks to the postfix-if already short and fast enough to write.

---

<div class="post-metadata">

**Author:** ![RX14](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/rx14/32/633_2.png) [@RX14](https://forum.crystal-lang.org/u/RX14)\
**Post date:** [January 28, 2019, 12:20pm UTC](https://forum.crystal-lang.org/t/var-method/301/12 "2019-01-28T12:20:00Z")

</div>

I ditto this statement, I’d need a _lot_ of convincing to include this sugar in crystal, regardless of the syntax.
