Re: Recursively inline kl source

88 views
Skip to first unread message

Mark Tarver

unread,
Jun 12, 2013, 6:52:32 PM6/12/13
to Qilang

> Lastly, does anyone know the appropriate way to tell if something is a
> function? I wrote my own `function?` logic here, but I feel like
> this should be built-in.

(define function?
  X -> (not (= (arity X) -1)))

is the closest. It will work on system functions and anything defined
in Shen except functions internal to the Shen package. It will not
work on /., lambda or let.

Mark

Mark Tarver

unread,
Jun 12, 2013, 7:32:49 PM6/12/13
to Qilang
(12+) (define function?
{A --> boolean}
       X -> (not (= (arity X) -1)))
function? : (A --> boolean)

with types.

Mark

Martial B

unread,
Jun 14, 2013, 6:12:51 AM6/14/13
to qil...@googlegroups.com
Hi,

On Wednesday, 12 June 2013 23:33:23 UTC+2, jpd wrote:
(...)

If you want to prevent the infinite recursion one idea is to keep track of which functions you already visited and refuse to visit them
again within walk-src.
 
I did a quick hack of your code to avoid this case (Note: I remove take and introduced zip; it's a personal choice, nothing better or worse):

(define zip
  X Y -> [] where (or (empty? X) (empty? Y))
  X Y -> (zip-help X Y []))

(define zip-help
  X Y Acc -> (reverse Acc) where (or (empty? X) (empty? Y))
  [X | Xs] [Y | Ys] Acc -> (zip-help Xs Ys [(@p X Y) | Acc]))

(define substitute
  Old New List -> (map (/. X (if (cons? X) (substitute Old New X) (if (= X Old) New X))) List))

(define substitute-with-zip
  [] List -> List
  [(@p O N) | Rest] List -> (substitute-with-zip Rest (substitute O N List)))

(define function?
  {A --> boolean}
  X -> (not (= (arity X) -1)))

(define user-function?
  F -> (and (function? F) (not (shen.sysfunc? F))))

(define kl-inline
  Kl NewParams -> (let A (reverse Kl)
      B (head (tail A))
      C (head A)
   (substitute-with-zip (zip B NewParams) C)))

(define walk-src
  Code Survey -> (let Chase (/. X (walk-src X Survey))
     UpdateChase (/. F X (walk-src X (cons F Survey))) 
     Fn (head Code)
  (if (user-function? Fn)
      (let Kl (ps Fn)
(if (empty? (intersection Kl Survey))
    (UpdateChase Fn (kl-inline Kl (map Chase (tail Code))))
    (cons Fn (map Chase (tail Code)))))
      (map Chase Code))) where (cons? Code)
  X _ -> X)

(defcc <kl-defun>
  defun F A C := [defun F A (walk-src C [F])];)

(define ps-inline
  F -> (compile <kl-defun> (ps F)))

\*
 * Tests 
 *
 *\

(define a
  X Y -> (+ X Y))

(define b
  0 -> 1
  X -> (a 2 X))

(define c
  0 -> 0
  X -> (b X) where (< X 50)
  X -> (- (b X) (a 5 X)))

(define pure-head
  [X | Xs] -> (pure-head X)
  X -> X)

(define even?
  1 -> false
  X -> (odd? (- X 1)))

(define odd?
  0 -> false
  X -> (even? (- X 1)))

(define safe-take-and-c
  0 _ Acc -> (map (function c) (reverse Acc))
  _ [] Acc -> (safe-take-and-c 0 _ Acc)
  N [X | Xs] Acc -> (safe-take-and-c (- N 1) Xs [X | Acc]))

(ps-inline c) \* yields Kl code calling + and - primitives *\
(= (ps pure-head) (ps-inline pure-head)) \* true : don't walk in a simple recursion *\
(ps-inline even?) \* written using itself *\
(ps-inline safe-take-and-c) \* don't expand recursion but c as +/- primitives *\

\* eof *\

Hope it helps,

Cheers,

--
Martial

Artella Coding

unread,
Sep 1, 2013, 10:18:57 AM9/1/13
to qil...@googlegroups.com
Is there any way to get the klambda code corresponding to system functions (besides manually looking into the sources)? For example right now I cannot do "(ps integer?)". Thanks.

Mark Tarver

unread,
Sep 1, 2013, 10:40:55 AM9/1/13
to qil...@googlegroups.com
Afraid not; if you want to find the klambda code for a system function the sources are the place to look.

The Ring was designed to extract this automatically for you.

Mark
Reply all
Reply to author
Forward
0 new messages