Wilfred / suggest.el

discover elisp functions that do what you want
367 stars 14 forks source link

Why can't programmers tell the difference between Christmas and Halloween? #34

Closed nickdrozd closed 6 years ago

nickdrozd commented 6 years ago

Because DEC 25 is OCT 31.

suggest doesn't suffer from this problem though:

  ;; Inputs (one per line):
  25

  ;; Desired output:
  "31"

  ;; Suggestions:
  ;; No matches found.

What I'd like to get back is something like

  (format "%o" 25)

Stringifying a number is no problem, so I take it the issue is just the radix conversion.

  ;; Inputs (one per line):
  25

  ;; Desired output:
  "25"

  ;; Suggestions:
  (number-to-string 25) ;=> "25"
  (apply #'number-to-string (list 25)) ;=> "25"
  (apply #'number-to-string (cons 25 nil)) ;=> "25"
  (apply #'number-to-string (make-list 1 25)) ;=> "25"
  (number-to-string (car (-cons* 25 2))) ;=> "25"

It turns out that suggest doesn't "know about" format; that is, format isn't included in suggest-functions. I add it.

  (push #'format suggest-functions)

I still don't get the result I want, so I try adding a more specialized function:

  (defun octalize (n)
    (format "%o" n))

  (push #'octalize suggest-functions)

This time I get what I want:

  ;; Inputs (one per line):
  25

  ;; Desired output:
  "31"

  ;; Suggestions:
  (octalize 25) ;=> "31"
  (apply #'octalize (list 25)) ;=> "31"
  (octalize (float 25)) ;=> "31"
  (octalize (ffloor 25)) ;=> "31"
  (octalize (fceiling 25)) ;=> "31"

If I run it again, however, I get slightly worse results:

  ;; Inputs (one per line):
  25

  ;; Desired output:
  "31"

  ;; Suggestions:
  (apply #'octalize (list 25)) ;=> "31"
  (octalize (float 25)) ;=> "31"
  (octalize (ffloor 25)) ;=> "31"
  (octalize (fceiling 25)) ;=> "31"

In fact, if I run some other query, then run [25] => "31" again (is there a better notation for this?), then run it again, I get the same results: (octalize 25) is included the first run, but not in subsequent runs.

I guess this issue really has two issues.

1) I think radix conversion is common, simple, and "discoverable" enough to warrant inclusion in suggest-functions. I don't know exactly what the right function to use is; I've tried using functions from calc, but to no avail. There must be an appropriate library somewhere.

2) Different results from one run to the next. I've seen this behavior with other functions (e.g. [100] => 10), so I don't think it has anything to do with octalize being a "user-defined" function.

Wilfred commented 6 years ago

Great bug report, thank you. I love the bug title.

There is string-to-number for handling number literals with different bases, so "31" 8 => 25 works. I couldn't find any way to go 25 8 => 31 though (apart from the silly (apply #'logior (number-sequence 8 25))). However, I only managed to come up with this example after looking at the functions, where suggest.el is supposed to help you find functions you can't remember!

Format doesn't currently help you because suggest.el doesn't know to try "%s" as an extra argument. We can definitely fix that.

Your second issue is #3.

Wilfred commented 6 years ago

OK, we can now do 25 => 31 and 25 => "31". :)

nickdrozd commented 6 years ago

Quick turnaround! The solution is almost correct. Now when I run the query, I get

;; Inputs (one per line):
25

;; Desired output:
"31"

;; Suggestions:
(format %o 25) ;=> "31"

But evaluating (format %o 25) will raise error: (void-variable %o). The output should be (format "%o" 25). The same is true for the others:

;; Inputs (one per line):
25

;; Desired output:
"19"

;; Suggestions:
(format %x 25) ;=> "19"
Wilfred commented 6 years ago

That should now be fixed.