5API
8.18
top
← prev up next →

helpful: providing suggestions on unbound identifier error.πŸ”— i

Sorawee Porncharoenwase <sorawee.pwase@gmail.com>

(require helpful ) package: helpful

This package provides suggestions on unbound identifier error. It requires Racket 8.7 at minimum.

1How to use it?πŸ”— i

There are two ways to activate the suggestions.

  • Using raco helpful as a replacement of racket

  • Adding (require helpful) in a module that you want to get suggestions and running racket normally

2SuggestionsπŸ”— i

Currently, the package provides two kinds of suggestions.

One suggestion is hinting a “closest” identifier name, which could be helpful when the error is caused by a typo mistake. The definition of “closest” is according to the Levenshtein distance. It breaks a tie by the alphabetical order, with module and lexical bindings being prioritized over imported identifiers.

Another suggestion is hinting modules that could be imported to make the identifier bound, which could be helpful when you forgot to import the desired module. This feature consults Scribble and the Racket documentation index and thus is only available if they are installed.

3ExamplesπŸ”— i

;Suggestion for a module binding
> (module testracket
(require helpful)
(define (factx)
(cond
[(zero? x)1]
[else (* x(fac(sub1 x)))])))

eval:1:0: fac: unbound identifier

in: fac

suggestion: do you mean `fact'?

;Suggestion for a local binding
> (module testracket
(require helpful)
(define (factx)
(cond
[(zero? x)1]
[else (* x(fact(sub1 y)))])))

eval:2:0: y: unbound identifier

in: y

suggestion: do you mean `x'?

;Suggestion for an imported identifier
> (module testracket
(require helpful)
(defun(fact)1))

eval:3:0: defun: unbound identifier

in: defun

suggestion: do you mean `define'?

;Suggestion for a module to import
;(only when Scribble and the Racket documentation index are installed)
> (module testracket/base
(require helpful)
->)

eval:4:0: ->: unbound identifier

in: ->

suggestion: do you mean `-'?

alternative suggestion: do you want to import one of the

following modules, which provides the identifier?

`lang/htdp-intermediate-lambda'

`lang/htdp-intermediate'

`ffi/unsafe'

`lang/htdp-beginner-abbr'

`mzlib/contract'

`lang/htdp-advanced'

`deinprogramm/sdp/beginner'

`lang/htdp-beginner'

`racket/contract/base' or `racket/contract' or `racket'

`typed/racket/base' or `typed/racket'

4LimitationsπŸ”— i

The feature only affects code in a module or a #lang. Because top level is hopeless, the feature is disabled for the REPL.

The feature only works reliably for code at phase level 0.

5APIπŸ”— i

syntax

( #%top . x)

A replacement of Racket’s #%top that provides suggestions. A #lang that wishes to provide the suggestions by default can simply reprovide #%top .

5.1InternalsπŸ”— i

procedure

( suggest x
[ #:closest?closest?
#:import?import?])none/c
closest?:any/c =#t
import?:any/c =#t
Given an unbound identifier x, this function raises the unbound id error with the suggestions. If closest? is #f, the closest identifier suggestion will be excluded. If import? is #f, the import suggestion will be excluded.

6More examplesπŸ”— i

;No suggestion outside a module or #lang
> (require helpful)
> (let ([x1])y)

y: undefined;

cannot reference an identifier before its definition

in module: top-level

;No suggestion for use-before-definition errors
> (module testracket
(require helpful)
an-id
(define an-id#f))
> (require 'test)

an-id: undefined;

cannot reference an identifier before its definition

in module: 'test

;Prioritization of module/lexical bindings
> (module testracket
(require helpful)
(define add2#f)
(define add3#f)
add4)

eval:5:0: add4: unbound identifier

in: add4

suggestion: do you mean `add2'?

;Alphabetical order
> (module testracket
(require helpful)
(define add3#f)
(define add2#f)
add4)

eval:6:0: add4: unbound identifier

in: add4

suggestion: do you mean `add2'?

;Consistent with Racket
> (module testracket
(require helpful)
add2
())

eval:7:0: #%app: missing procedure expression;

probably originally (), which is an illegal empty

application

in: (#%app)

;Also consistent with Racket
> (module testracket
(require helpful)
add2
(let ()()))

eval:8:0: add2: unbound identifier

in: add2

suggestion: do you mean `add1'?

;Another module recommendation
> (module testracket
(require helpful)
format-id)

eval:9:0: format-id: unbound identifier

in: format-id

suggestion: do you mean `format'?

alternative suggestion: do you want to import

`racket/syntax', which provides the identifier?

top
← prev up next →

AltStyle γ«γ‚ˆγ£γ¦ε€‰ζ›γ•γ‚ŒγŸγƒšγƒΌγ‚Έ (->γ‚ͺγƒͺγ‚ΈγƒŠγƒ«) /