# Operator (re)definition and order of operations

**URL:** <https://racket.discourse.group/t/operator-re-definition-and-order-of-operations/368>\
**Category:** Questions & Answers\
**Created:** [December 7, 2021, 1:36am UTC](https://racket.discourse.group/t/operator-re-definition-and-order-of-operations/368 "2021-12-07T01:36:09Z")\
**Posts on this page:** 15\
**Page:** 1

<div class="post-metadata">

**Author:** ![decuser](https://avatars.discourse-cdn.com/v4/letter/d/5e9695/32.png) [@decuser](https://racket.discourse.group/u/decuser)\
**Post date:** [December 7, 2021, 1:36am UTC](https://racket.discourse.group/t/operator-re-definition-and-order-of-operations/368/1 "2021-12-07T01:36:09Z")

</div>

Given:

```scheme
#lang racket

(* (+ 2 (* 4 6))
   (+ 3 5 7))

(define + (* 2 3))

+

```

Why does dr racket complain about the combination starting at line 2, that:

```scheme
+: undefined;
 cannot reference an identifier before its definition

```

---

<div class="post-metadata">

**Author:** ![EmEf](https://avatars.discourse-cdn.com/v4/letter/e/53a042/32.png) [@EmEf](https://racket.discourse.group/u/EmEf)\
**Post date:** [December 7, 2021, 1:47am UTC](https://racket.discourse.group/t/operator-re-definition-and-order-of-operations/368/2 "2021-12-07T01:47:08Z")

</div>

Would it help if the error message ended in “is evaluated”?

---

<div class="post-metadata">

**Author:** ![decuser](https://avatars.discourse-cdn.com/v4/letter/d/5e9695/32.png) [@decuser](https://racket.discourse.group/u/decuser)\
**Post date:** [December 7, 2021, 2:02am UTC](https://racket.discourse.group/t/operator-re-definition-and-order-of-operations/368/3 "2021-12-07T02:02:05Z")

</div>

Not really. I'm a racket (sicp dialect) newb. But ...

If I put:

```scheme
(define + 6)
(+ 2 2)

```

it correctly states that application: not a procedure; given 6

but

```scheme
(+ 2 2)
(define + 6)

```

gives the aforementioned: +: undefined;  
cannot reference an identifier before its definition

which doesn't make sense because + is the addition operator, provided by the language, or at least it should be... until the (re) define.

That is, if I just put

```scheme
(+ 2 2)

```

and don't bother using define at all it correctly evaluates to 4.

---

<div class="post-metadata">

**Author:** ![dannypsnl](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/dannypsnl/32/917_2.png) [@dannypsnl](https://racket.discourse.group/u/dannypsnl)\
**Post date:** [December 7, 2021, 2:21am UTC](https://racket.discourse.group/t/operator-re-definition-and-order-of-operations/368/4 "2021-12-07T02:21:08Z")

</div>

I think this is two problems:

1. you think defined `+` shadow origin `+`
2. we cannot use a variable before you define it

To check the second problem, we can have the following code:

```scheme
(c 2 3)
(define (c a b) `(,a ,b))

```

you will get `c: undefined;`. With the following code:

```scheme
a
(define a 1)

```

you will get `a: undefined;`.

So the part that confuses you is, should `+` reference to origin language provided `+`? The answer is no, because the top-level mapping of id is linked with the compiled definition! Thus, in your code, there is actually only has one `+` definition and you use it before you define it.

---

<div class="post-metadata">

**Author:** ![decuser](https://avatars.discourse-cdn.com/v4/letter/d/5e9695/32.png) [@decuser](https://racket.discourse.group/u/decuser)\
**Post date:** [December 7, 2021, 2:27am UTC](https://racket.discourse.group/t/operator-re-definition-and-order-of-operations/368/5 "2021-12-07T02:27:10Z")

</div>

OK. I think I'm tracking with you. Are you suggesting that racket is compiled? At least, when run in the definitions window?

---

<div class="post-metadata">

**Author:** ![jbclements](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/jbclements/32/11_2.png) [@jbclements](https://racket.discourse.group/u/jbclements)\
**Post date:** [December 7, 2021, 3:09am UTC](https://racket.discourse.group/t/operator-re-definition-and-order-of-operations/368/6 "2021-12-07T03:09:49Z")

</div>

Well... Racket _is_ compiled, but that's not relevant in this question. Your question has to do with scope: what is the scope of the top-level definition of plus?

In Racket, the scope of a top-level definition is the whole file.

---

<div class="post-metadata">

**Author:** ![dannypsnl](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/dannypsnl/32/917_2.png) [@dannypsnl](https://racket.discourse.group/u/dannypsnl)\
**Post date:** [December 7, 2021, 3:11am UTC](https://racket.discourse.group/t/operator-re-definition-and-order-of-operations/368/7 "2021-12-07T03:11:12Z")

</div>

All interpret language seems like interpret who wants performance, do compile actually, but this is not the point. The point is anyway, once you write down `(define id expression)`, all `id` refers to this one in this module/namespace/compiled component.

---

<div class="post-metadata">

**Author:** ![benknoble](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/benknoble/32/16_2.png) [@benknoble](https://racket.discourse.group/u/benknoble)\
**Post date:** [December 7, 2021, 1:38pm UTC](https://racket.discourse.group/t/operator-re-definition-and-order-of-operations/368/8 "2021-12-07T13:38:03Z")

</div>

(Someone jump in and correct me; I'm sure I got some details wrong, but the general idea seems reasonable.)

I think of the top-level of a module a bit like a big `letrec` context combined with the printing of non-define expressions. This is necessary to allow mutual recursion (_e.g._, try to define `even?` and `odd?` such that `(even? n)` is true iff `n` is 0 or `(odd? (sub1 n))` and `(odd? n)` iff `n` is 1 or `(even? (sub1 n))`; without forward references, this would be difficult) because forward references are allowed. Essentially, the identifiers to be bound are not created in sequence. In a module with

```scheme
(define (x) …)

```

`x` will refer to this top-level binding except where it is shadowed.

However, there _is_ a sequence for when identifiers get their binding! The _placeholders_ (identifiers, like `x`) may be grouped up front (like a `letrec` does so that they may all reference each other), but the _bindings_ are not installed until the binding expressions (like `define`) are evaluated. @dannypsnl has a great example of this.

The error message isn't that `a` isn't `unbound identifier` which you get when `a` has no definition; it's that `a` is undefined. It will be bound, but you can't use it until it has been bound.

* * *

This all explains why racket complains about `+` in your example: By the time you get to the `(* …)` expression, `+` is marked as to-be-bound in this module. But it hasn't been bound yet.

---

<div class="post-metadata">

**Author:** ![dannypsnl](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/dannypsnl/32/917_2.png) [@dannypsnl](https://racket.discourse.group/u/dannypsnl)\
**Post date:** [December 7, 2021, 1:58pm UTC](https://racket.discourse.group/t/operator-re-definition-and-order-of-operations/368/9 "2021-12-07T13:58:01Z")

</div>

And an interesting part is `(define (id ...) ...)`, we can treat `(define (id ...) ...)` as `(define id (lambda (...) ...))`, so we get the following example:

```scheme
(is-even? 1) ; error: is-even?: undefined

(define (is-even? n)
  (or (zero? n)
      (is-odd? (sub1 n))))

(is-even? 1) ; error: is-odd?: undefined

(define (is-odd? n)
  (or (zero? n)
      (is-even? (sub1 n))))

```

---

<div class="post-metadata">

**Author:** ![decuser](https://avatars.discourse-cdn.com/v4/letter/d/5e9695/32.png) [@decuser](https://racket.discourse.group/u/decuser)\
**Post date:** [December 7, 2021, 2:11pm UTC](https://racket.discourse.group/t/operator-re-definition-and-order-of-operations/368/11 "2021-12-07T14:11:22Z")

</div>

It seems like + is defined by scheme. Once a file includes a (define + whatever) ANYWHERE, scheme marks + as needing a binding expression before it can be referenced ANYWHERE. With x, it is not defined by scheme, therefore it requires a binding expression, naturally. Is this a reasonable understanding?

---

<div class="post-metadata">

**Author:** ![decuser](https://avatars.discourse-cdn.com/v4/letter/d/5e9695/32.png) [@decuser](https://racket.discourse.group/u/decuser)\
**Post date:** [December 7, 2021, 2:18pm UTC](https://racket.discourse.group/t/operator-re-definition-and-order-of-operations/368/12 "2021-12-07T14:18:01Z")

</div>

Here's my confusion, stated after the clarifications. In the repl, I can evaluate:

```scheme
(+ 1 2 3 4)

```

with 10 as the result. Telling me that + is bound to the addition operation. Then if I:

```scheme
(define + 6)

```

and try:

```scheme
(+ 1 2 3 4)

```

I get the expected, can't apply 6, error.

This is rational and makes sense. + is bound to addition, I bind it to a number, a number can't be applied to anything. It's orderly and ordered.

Put all of the code above into a script and run it:

```scheme
(+ 1 2 3 4)
(define + 6)
(+ 1 2 3 4)

```

and it seems like the code is first parsed and the parser detects that + is in need of binding and the + undefined message is generated before any other code is executed (as described in the thread, above). This seems inconsistent, but I'm positive, it's my lack of understanding. I appreciate y'alls clarifying comments and explanations.

---

<div class="post-metadata">

**Author:** ![dominik.pantucek](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/dominik.pantucek/32/144_2.png) [@dominik.pantucek](https://racket.discourse.group/u/dominik.pantucek)\
**Post date:** [December 7, 2021, 2:31pm UTC](https://racket.discourse.group/t/operator-re-definition-and-order-of-operations/368/13 "2021-12-07T14:31:50Z")

</div>

I think you're just seeing the symptoms of "top level is hopeless":

> <https://gist.github.com/samth/3083053>

---

<div class="post-metadata">

**Author:** ![benknoble](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/benknoble/32/16_2.png) [@benknoble](https://racket.discourse.group/u/benknoble)\
**Post date:** [December 7, 2021, 3:14pm UTC](https://racket.discourse.group/t/operator-re-definition-and-order-of-operations/368/14 "2021-12-07T15:14:14Z")

</div>

Yes, the delayed evaluation from `lambda` is key here.

---

<div class="post-metadata">

**Author:** ![jbclements](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/jbclements/32/11_2.png) [@jbclements](https://racket.discourse.group/u/jbclements)\
**Post date:** [December 8, 2021, 3:03am UTC](https://racket.discourse.group/t/operator-re-definition-and-order-of-operations/368/15 "2021-12-08T03:03:13Z")

</div>

Did you specifically mean to mention "scheme" here as opposed to "racket"? Scheme has a sequence of language definitions which will answer this question, but the answers there won't necessarily be the same as those for Racket. To some degree, you can explore this using

```scheme
#lang r5rs

```

and comparing it to

```scheme
#lang racket

```

If you don't specifically care about Scheme as opposed to Racket, feel free to ignore this.

---

<div class="post-metadata">

**Author:** ![decuser](https://avatars.discourse-cdn.com/v4/letter/d/5e9695/32.png) [@decuser](https://racket.discourse.group/u/decuser)\
**Post date:** [December 8, 2021, 4:10am UTC](https://racket.discourse.group/t/operator-re-definition-and-order-of-operations/368/16 "2021-12-08T04:10:30Z")

</div>

Good point. I use Dr. Racket to explore SICP, which is basically a book that uses Scheme, probably r4rs. But, I should have said Racket, which I tested for the behavior before posting here.
