Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Racket match semantics with null

My question is why the following pattern returns 'match even though (make-tree 0 null null) is clearly not null?

#lang racket
(define-struct tree (val left right))
(match (make-tree 1 (make-tree 0 null null) null)
  [(tree 1 null _) 'match]
  [_ 'no-match])

I noticed changing the null to '() in the first pattern yields the correct(?) value. Why does this occur? Aren't null and '() equivalent? Thanks in advance.

like image 495
Anthony Calandra Avatar asked Dec 15 '22 09:12

Anthony Calandra


2 Answers

According to https://docs.racket-lang.org/reference/match.html, identifiers in patterns has the following rule:

id or (var id) — matches anything, and binds id to the matching values.

In your case, null is not evaluated to a value. Instead, it is recognized as an identifier shadowed by the value matched at that position, which is (make-tree 0 null null)

like image 200
Sorawee Porncharoenwase Avatar answered Dec 26 '22 12:12

Sorawee Porncharoenwase


As already mentioned, a bare identifier will match anything because the purpose of an identifier in a match pattern is to create a new binding as a result of the match. Of course, null is not a keyword in Racket, it’s just a binding exported by racket/base, so it just gets bound as usual. In contrast, '() is a quoted list literal, which can obviously be detected by match and handled accordingly.

It is sometimes useful, though, to be able to compare values dynamically, in which case those values will be bound to identifiers. In this case, you can use the == match expander, which will compare the match to the value of an arbitrary expression. This would allow you to use null if you wished:

#lang racket
(define-struct tree (val left right))
(match (make-tree 1 (make-tree 0 null null) null)
  [(tree 1 (== null) _) 'match]
  [_ 'no-match])
; => 'no-match

Of course, using '() is probably clearer in this case.

like image 31
Alexis King Avatar answered Dec 26 '22 12:12

Alexis King