Darmani


8 points by Darmani over 2 years ago | link | top
cached 6 days ago
Well, since I voted for the basic library with sin, cos, pi, gcd, etc, I felt obligated to implement a basic math library with sin, cos, pi, gcd, closely related fucntions, and everything I needed or thought I'd need to implement those.

Implementations guaranteed not to be optimally efficient:

Edit: Fixed a mistake in bringing out-of-period numbers into period in sin and cos

  (= pi 3.141592653589793238)
  (= 2*pi (* 2 pi))
  
  (def signum (n)
    (if (> n 0)
        1
      (< n 0)
        -1
        0))
  
  (def floor (x)
    (if (< x 0)
      (- (trunc x) 1)
      (trunc x)))
  
  (def ceil (x)
    (if (< x 0)
      (trunc x)
      (+ (trunc x) 1)))
  
  (defmemo fac (n)
    (if (is n 0)
      1
      (* n (fac (- n 1)))))
  
  ;Existing mod only accepts integers. Left intact as "modulo"
  ;This mod copies the behavior of Ruby's mod
  (def mod (dividend divisor)
    "Returns the remainder from dividing dividend by divisor.
    Adds divisor once more if they are of different signs so that the result is always of the same sign as divisor."
    (if (is divisor 0)
          (error "modulo undefined for 0")
        (isnt (signum dividend) (signum divisor))
          (+ divisor (- dividend (* divisor (trunc (/ dividend divisor)))))
          (- dividend (* divisor (trunc (/ dividend divisor))))))
  
  (def sin (x)
    "Returns the sine of x in radians."
      (let x (let red (mod x 2*pi)
                (if (> (abs red) pi)
                  (- red (* (signum red) 2*pi))
                   red))
         ;Taylor polynomial; 0.0 is to cast to float
         (- (+ 0.0 x (/ (expt x 5) (fac 5)) (/ (expt x 9) (fac 9)))
             (/ (expt x 3) (fac 3)) (/ (expt x 7) (fac 7)))))
              
  (def cos (x)
    "Returns the cosine of x in radians."
       (let x (let red (mod x 2*pi)
                 (if (> (abs red) pi)
                   (- red (* (signum red) 2*pi))
                   red))
         ;Taylor polynomial
         (- (+ 1.0 (/ (expt x 4) (fac 4)) (/ (expt x 8) (fac 8)))
             (/ (expt x 2) (fac 2)) (/ (expt x 6) (fac 6)))))
  
  (def tan (x)
    "Returns the tangent of x in radians."
    ;Lazy definition
    (/ (sin x) (cos x)))
  
  (def int? (x)
    "Returns whether x is an integer"
    (is (mod x 1.0) 0.0))
  
  (defmemo prime (n)
    "Returns the nth prime. 2 is the 0th prime."
    (if (< n 0)
          nil
        (is n 0)
          2
          (let prev-primes (map prime (range 0 (- n 1)))
              ((afn (i)
                  (if (no (breakable:each p prev-primes ;Each always returns nil, so a break returns t
                              (if (int? (/ i p))
                                (break t))))
                        i
                        (self (+ i 1))))
                (+ 1 (last prev-primes))))))
      
  
  (def prime-factorization (n)
    "Returns a list each prime up to the greatest prime in n paired with the power of that prime in n.
    E.g.: (prime-factorization 20) returns ((2 2) (3 0) (5 1)).
    Use (reduce * (map [apply expt _] ...)) to change a prime factorization into the number."
    (rev:accum keep
      (let p-ord 0
        (while (> n 1)
            (with (p (prime p-ord)
                    pow 0)
              (until (isnt (mod n p) 0)
                (++ pow)
                (zap [/ _ p] n))
              (keep (list p pow)))
            (++ p-ord)))))
  
  (def gcd (x y)
    "Returns the greatest common divisor of x and y."
      (reduce * (map [apply expt _]
          (map (fn (a b)
                    (list (car a) (min (cadr a) (cadr b))))
            (prime-factorization x) (prime-factorization y)))))
  
  (def lcm (x y)
    "Returns the least common multiple of x and y."
    (/ (* x y) (gcd x y)))

8 points by Darmani over 2 years ago | link
cached 3 days ago

7 points by Darmani over 2 years ago | link | top
cached 11 days ago

  (let olddef def
    (mac def (name args . body)
      (if (acons name)
        `(def= ,(cadr name) ,args ,@body)
        `(,olddef ,name ,args ,@body))))
Hope that fits what you're looking for.

(I also hope that works -- I'm not at home and can't test it.)


6 points by Darmani about 1 year ago | link | parent | top
cached 23 days ago
Actually, especially since Arc lacks a debugger, I find it very convenient to be able to just place a pr: or pr. in front of some symbol to get an expression printed out without the behavior changing.

5 points by Darmani over 2 years ago | link | top
cached 23 days ago
Arc implementation in JavaScript: http://halogen.note.amherst.edu/~jdtang/arclite/

5 points by Darmani about 1 year ago | link | parent | top
cached 12 days ago
Ironically, before that comment, I had been concerned on how this forum had been dead for 6 days...

5 points by Darmani over 2 years ago | link | parent | top
cached 7 days ago
I'm guessing this request was inspired by something similar to Ruby's method_missing method. method_missing is often used to implement behavior that involves the name of the message being passed to an object (the official example is a class that converts between Roman and Arabic numerals and uses method_missing to redirect messages such as "roman.III" to "roman.roman_to_arabic('III')"). Another usage is undefining all methods and then intercepting the calls, such as in RubyQuiz #95, where that approach was used to convert code blocks to S-expressions.

The former use isn't really that useful without an object system to restrict the scope of a single method_missing definition. And, of course, any object system could implement its own method_missing. And the second usage, in addition to being pathologically uncommon, could be implemented in Arc using macros, or, where function calls must be intercepted at runtime, by iterating through all values in the namespace (or even a closure as well) and overloading functions to add hooks that perform some other behavior if some boolean is set to true. (Of course, said boolean would probably need to be in a table keyed by the current thread.) Of course, that would require being able to retrieve a list of all values in a namespace or closure to iterate through (hmmm...now there's an idea).


4 points by Darmani about 1 year ago | link | top
cached 13 days ago
An easy way to get an overview of what libraries are available. The Anarki libraries are spread over half a dozen different folders, and for a few of them I don't know what they're meant for even after I read the source code. There needs to be something akin to "gem list".

4 points by Darmani over 2 years ago | link | parent | top
cached 13 days ago
A purity analyzer would need to be a little more complex than that - the "=" operator would be pure or impure depending on the scope of the location being set. The simple way to solve that would be to make locations created within any lexical context that is discarded with the completion of the function pure and those without impure, although they may be slightly complicated.

Of course, some situations, such as code that sets unset values in an outside hash table to the default value, may arguably be "pure" functional code, although dealing with such things is outside the domain of a "conservative" purity analyzer.


4 points by Darmani over 2 years ago | link | parent | top
cached 11 days ago
Unfortunately, that won't work because the form is being returned to a place outside the closure where olddef was defined; when eval is given the form containing olddef, it will not recognize it.

Here's a better definition:

  (let olddef def
    (mac def (name args . body)
      (if (acons name)
        `(def= ,(cadr name) ,args ,@body)
        (apply (rep olddef) (cons name (cons args body))))))