1

This discussion got me investigating Calc programming with elisp, especially at the bottom this code

(defmath myFact (n)
 (format-number (calcFunc-fact n)))

then

(calcFunc-myFact 33)

yields 8683317618811886495518194401280000000

...all of which works nicely from my *scratch*. However, I would like these functions to work, but they don't seem to. The docs say many confusing things, such as prepending calcFunc- and math-. Also I've tried (require 'calc-ext) and tried running (calc-extensions). All of attempts to use these vector functions return void function errors. What am I missing?

6
  • 1
    Here's some additional info: emacs.stackexchange.com/questions/13423/…, but to give you a better answer, could you give an example of what you tried to do? Some functions may make assumptions about the way they are called (say, having particular number of arguments on the stack etc.), maybe that's the problem? Also this: emacs.stackexchange.com/questions/8202/…
    – wvxvw
    Commented Dec 8, 2015 at 22:40
  • (math-concat [1, 2] [3, 4]) gives (vec [1 (\, 2)] [3 (\, 4)]) but (vec-length [1, 2, 3, 4]) and (build-vector 1 5] etc give void function errors.
    – 147pm
    Commented Dec 8, 2015 at 23:06
  • 1
    Well, this is not how you write a vector in ELisp, , has a special meaning in ELisp (evaluation of the following expression in the context of a quoted expression). Thus a vector would be spelled [1 2], not [1, 2].
    – wvxvw
    Commented Dec 8, 2015 at 23:10
  • Good, but I'm not getting past void function. As I said above, calcFunc-fact works, but vec-length doesn't. I can only assume I haven't loaded the proper library/package. As far as how to do a vector, I was just following the examples.
    – 147pm
    Commented Dec 9, 2015 at 0:29
  • This might be just a case of outdated documentation. There is a function calc-vlen.
    – politza
    Commented Dec 10, 2015 at 9:13

2 Answers 2

1

Apparently, the documentation is bad: this per the former maintainer of calc-vec.el, Jay Belanger. His advice (besides contacting [email protected]) was to simply go to the main Calc docs (e.g. this and this) and use those function names (usually the one in brackets) prefixed by calcFunc-. Another curiosity is you need to refer to a vector in its "internal" format, namely a list: (vec 1 2 3), which then can be seen as a normal Calc vector with calc-eval:

(setq myv1 '(vec 1 2 3))
  => (vec 1 2 3)
(calc-eval myv1)
  => "[1, 2, 3]"
(calcFunc-subvec myv1 1 3)
  => (vec 1 2)
(calcFunc-vlen myv1)
  => 3

but it can get ugly. . .

(setq myv2 '(vec 2 4 6 8))
(calcFunc-arrange myv2 1)
  => (vec (vec 2) (vec 4) (vec 6) (vec 8))

requiring calc-eval to make it pretty

(calc-eval (calcFunc-arrange myv2 1))
  =>"[[2], [4], [6], [8]]"

why calc-eval does this, I don't know.

But this is not always easy. Here's an example that seems only calc-eval-friendly:

(calc-eval "deg(37@ 26' 36.42\")")
  => "37.44345"

This is as close as I can get

(calcFunc-deg '(hms 37 26 36))
  => (float 374433333333 -10)

but it won't accept 36.42 for some reasons better minds than mine might understand from this calc-math.el code:

;;; Convert A from HMS or radians to degrees.
(defun calcFunc-deg (a)   ; [R R] [Public]
  (cond ((or (Math-numberp a)
         (eq (car a) 'intv))
     (math-with-extra-prec 2
       (math-div a (math-pi-over-180))))
    ((eq (car a) 'hms)
     (math-from-hms a 'deg))
    ((eq (car a) 'sdev)
     (math-make-sdev (calcFunc-deg (nth 1 a))
             (calcFunc-deg (nth 2 a))))
    (math-expand-formulas
     (math-div (math-mul 180 a) '(var pi var-pi)))
    ((math-infinitep a) a)
    (t (list 'calcFunc-deg a))))
(put 'calcFunc-deg 'math-expandable t)

. . . yes, the lengths some people go to stay in Emacs, i.e., I'm trying to follow a Coursera course that wants me to use Python, but I know a better way. . .

1
  • Can you please file a bug report to improve the documentation? Commented Jan 14, 2016 at 14:36
0

Calc accepts 37@ 26' 36.42" .

Here is the simple case of 37@ 26' 36".

(calc-eval "deg(37@ 26' 36\")")         ; => "37.4433333333"

You can call Calc functions from Emacs Lisp by calcFunc-deg

(calcFunc-deg '(hms 37 26 36))          ; => (float 374433333333 -10)
(math-format-number (calcFunc-deg '(hms 37 26 36))) ; => "37.4433333333" as a string
(string-to-number
 (math-format-number (calcFunc-deg '(hms 37 26 36)))) ; => 37.4433333333 as a number

Now the case for 37@ 26' 36.42" .

As 36.42 is not an integer, it is expressed as (float 3642 -2) in Emacs Lisp.

Your '(hms 37 26 36.42) should be '(hms 37 26 (float 3642 -2)) .

Voila!

(calc-eval "deg(37@ 26' 36.42\")")          ; => "37.44345"
(calcFunc-deg '(hms 37 26 (float 3642 -2))) ; => (float 3744345 -5)
(math-format-number (calcFunc-deg '(hms 37 26 (float 3642 -2)))) ; => "37.44345" as a string
(string-to-number
 (math-format-number (calcFunc-deg '(hms 37 26 (float 3642 -2))))) ; => 37.44345 as a number

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.