Where can I find the definition of eq? procedure

I am referring to the eq? procedure that is built into racket link to racket docs

Things I have already tried

  1. The solution suggested here does not appear to work in my case. On right clicking eq? identifier the context menu item "Open defining file" does not appear.

  2. I downloaded the latest racket source code and used silver searcher but could not find a helpful definition for eq?
    2.1 ag -A 10 "define (eq?" returned no results
    2.2 ag -A 10 "define eq?" did not return a helpful result

Thank you
Any help is appreciated

1 Like

The eq? operation is handled specially by the compiler, when it occurs in operator position and is applied to exactly two arguments. The definition you found wraps that operation as a function, which handles the other cases, like maybe (apply eq? some-list).

The compiler's handling of eq? is partly in racket/src/ChezScheme/s/cpprim.ss:

    (define-inline 2 eq?
      [(e1 e2)
       (or (eqvop-null-fptr e1 e2)
           (relop-length RELOP= e1 e2)
           (%inline eq? ,e1 ,e2))])

The first two cases are optimizations for certain patterns of eq? comparisons. The first seems related to foreign function pointer comparisons. The second one seems to be optimizing expressions like (> (length lst) 1) to avoid the call to length. If neither optimization applies, the third case is used: (%inline eq? _ _).

I think (but I'm not sure) that %inline cooperates with define-instruction, so this would use the implementation of eq? defined for the specific architecture being used. For example, in racket/src/ChezScheme/s/x86_64.ss there is

  (define-instruction pred (eq? u< < > <= >=)
    ....)

which emits machine code for comparisons depending on whether the arguments are immediates or in registers or memory.

5 Likes

You found the actual definition of the eq? function:

(define eq?
  (lambda (x y)
    (eq? x y)))

What happens is that, first the compiler learns how to generate machine code for expressions such as (eq? x y), this is processor specific and for X86-64 it happens here: racket/x86_64.ss at e028f252da859759100f9248230bdc4e203a6684 · racket/racket · GitHub

Next, the procedure eq? is defined having the expression (eq? x y) as its body, but the compiler already knows what code to generate for that expression.

Alex.

3 Likes

I tried to grok the definition of define-instruction at ChezScheme/x86_64.ss at 0d5ec1da706fc4e08acca748284963fd286eed59 · cisco/ChezScheme · GitHub
However, it appears to be a very complex and long definition. Is the definition of define-instruction hand written or computer generated?
Are there tests or documentation for define-instruction that will help me understand what it does? I could not find anything at Index

@alexh and @ryanc I don't know enough about compilers and CPUs to understand your respective answers. I don't know which answer to mark as a solution, maybe the forum moderators can select one.

I can't help but wonder what your goal here is, just to make sure we haven't missed something obvious. Are you trying to figure out the low-level details of how something like eq? is implemented, or are you trying to figure out how to use it?

If you're interested in low level details, it sounds like you might want to take a look at Jeremy Siek's book, Essentials of Compilation:

This book dives into the nanopass architecture that is the foundation for Chez Scheme.

But ... i have the feeling that this is an x-y problem, and there's something else that might be more helpful to you.

3 Likes