Installing racket-cas

I finally got round to trying @soegaard 's racket-cas and on the whole it seems OK but I'm not sure I've installed it correctly, there are some minor issues and the docs seem unclear.

I downloaded the zip from github and ran drracket from its directory.
Is it supposed to be installed as a package under raco? I didn't do that, maybe I was supposed to.

To get it to run I then had to modify main.rkt a bit, and then loaded that up into my DrRacket IDE. Here's the file:

#lang racket
(require "racket-cas.rkt")
(require "repl.rkt")

(provide (all-from-out "racket-cas.rkt"))

When I run this, the greeting appears OK, and the basic commands see to work fine, eg

> (tex (expand '(expt (+ a b) 2)))
"$a^{2}+b^{2}+2\\cdot {a\\cdot b}$"

Typing plain x y or z also correctly reads them as 'x 'y or 'z

What does not happen is automatic simplification, which the docs say should happen. However if I explicitly request simplification, it seems OK.

> `(+ 3 a 2 x (* 4 x))
'(+ 3 a 2 x (* 4 x))
> (simplify `(+ 3 a 2 x (* 4 x)))
'(+ 5 a (* 5 x))

Any suggestions?
(Especially if this should be installed as a package? The suggestion to use the form
(require racket-cas/repl)
instead of how I did it makes me think so.)

Thanks!

Thanks for taking the time to test racket-cas.

You are right there is an issue with the quasiquote when required.
It's a scope issue (I believe) - maybe someone can spot the problem [see later].

However, you can open the file repl.rkt directly and run it.
Then quasiquote, `, will work in the repl:

Note however, that automatic simplification and simplify is two different things. The automatic simplifier only does "small stuff" (adds numbers, collect equal terms, sort the terms etc.).

The functions in racket-cas usually expect their inputs to be normalized.
If the inputs are normalized, the outputs are also normalized.
Therefore the automatic simplifier (aka normalize) must be used on inputs
before calling many of the functions.

In the repl it is more convenient to use quasiquote than it is to writenormalize` all the time.

But, back to the macro problem. The "make quasiquote do automatic simplification" macro is defined in [1].

The question is why it works when used in "repl.rkt" but not when required from the repl?

(module+ start
  (provide quote quasiquote)
  (require (submod ".."))
  (require (prefix-in old: (only-in racket/base quote quasiquote)))
  ; In the REPL it can be convenient to change the meaning of ' 
  ; to automatic normalization:
  (define-syntax (quote stx) 
    (syntax-case stx () [(_ . datum) #'(normalize (old:quote . datum))]))
  (define-syntax (quasiquote stx) 
    (syntax-case stx () [(_ . datum) #'(normalize (old:quasiquote . datum))])))

; (let () (define f '(* x x)) `(* x ,f))  

; This macro doesn't work as expected ... why?
(define-syntax (repl stx) 
  (syntax-case stx () 
    [_ (with-syntax ([req (datum->syntax stx 'require)])
         (syntax/loc stx (req (submod "." start))))]))

[1] racket-cas/racket-cas/racket-cas.rkt at master · soegaard/racket-cas · GitHub

Where you're doing (provide (all-from-out "racket-cas.rkt")), does it help to also provide all-from-out "repl.rkt"?

Thanks for all that, Axel!
Yes, indeed, opening repl.rkt instead of main.rkt fixes the normalization/auto-simplification issue
(@AlexKnauth , no, just adding all-from-out does not fix it, but it doesn't matter, since you can just launch off the repl.rkt file)

Looking forward to testing it and seeing how it's been implemented!

There is one more little thing I found, I think it may be due to an update in Racket since it was written, I'm guessing it was a keyword parameter change

> (render (expand '(expt (+ a b) 2)))
. . racket-cas.rkt:2065:23: application: required keyword argument not supplied
  procedure: latex->pict
  required keyword: #:preamble
  arguments...:

Any ideas? - it would be nice to have a renderer that can be shown off...

Where are you trying to use the repl macro? It seems like the "." in the submod would only work if it's already in the same module anyway.

I think, the problem that render used to be defined in racket-cas but was removed.
Now it calls a render from latex-pict, which is broken.
[I'll fix that.]

In the mean time, you can paste this definition into the repl to get a render.

    (begin (require latex-pict pict)
                 (define (render u)
                   (define (strip$ x) (substring x 1 (- (string-length x) 1)))
                   (pict->bitmap (scale (tex-math (strip$ (tex u))) 2))))

Erm, almost but not quite

> (begin (require latex-pict pict)
                 (define (render u)
                   (define (strip$ x) (substring x 1 (- (string-length x) 1)))
                   (pict->bitmap (scale (tex-math (strip$ (tex u))) 2))))
> (render (normalize '(+ x 2 a 3 (* 4 x))))
exec failed (No such file or directory; errno=2)
. . ../../usr/share/racket/collects/racket/private/kw.rkt:1386:57: open-input-file: cannot open input file
  path: /var/tmp/latex2pdf-6d322b6d01941cdd976b954807b0591c.log
  system error: No such file or directory; errno=2

You can see it flash momentarily as it tries to open a rendering window, but then it reports the above error about not being able to find some log file, no idea what that is, I'm afraid. Permissions?

Anyway it really is not a high priority for me, I'm more than happy to wait till it's fixed, but it certainly would be nice to have, once everything's going. Just thought I'd let you know.

The package latex-pict uses pdflatex and a couple of latex libraries.
Maybe something is configured differently on your computer?
If you are using a complete, newish TeXLive, I'd expect everything to work.
Marc had to install some extra packages to get everything to work though.

See

I expect pdflatex is in the path?

pdflatex was not on the path.

It is now, it's still failing, but with less error output :grin:

(render (normalize '(+ x 2 a 3 (* 4 x))))
. . ../../usr/share/racket/collects/racket/private/kw.rkt:1386:57: latex failed

I'll look into it later, I'm more involved with the math now.

====
PS. The offending line was:

                                ;; caller didn't lift expressions out
                                (let ([ids (generate-temporaries args)])
>1386....................>>>      #`(let #,(map list ids
                                          (map hide-binding-name args))
                                              #,(k ids)))

if that helps at all

Which editor are you using in your screenshot? Mine doesn't really look like that in DrRacket or Emacs, and I'm wondering if there's another editor you're using that I haven't tried.

@cadence

It's just Emacs.
I have over time stolen bits and pieces from Eli, Greg and Bogdan
and added keybindings that work more-or-less like DrRacket.

See:

1 Like