Arc Forumnew | comments | leaders | submitlogin
1 point by evanrmurphy 5567 days ago | link | parent

I got Anarki and have been experimenting with 'src. It appears to be exactly what I was looking for:

  arc> (src map1)
  (from "arc.arc")
  (def map1 (f xs)
    (if (no xs)
        nil
        (cons (f (car xs))
              (map1 f (cdr xs)))))t
Handy that it prints the source file's name too. It even works for functions defined at the REPL:

  arc> (def testfn () (pr "this is testfn"))
  #<procedure: testfn>
  arc> (src testfn)
  (def testfn nil
    (pr "this is testfn"))t
'src will be very useful to me, and it seems the natural extension of the implementation-as-specification idea put forth in the tutorial:

  The definitions in arc.arc are also an experiment in another way.
  They are the language spec.  [...]
  It may sound rather dubious to say that the only spec for something
  is its implementation.  It sounds like the sort of thing one might
  say about C++, or the Common Lisp loop macro.  But that's also how
  math works.  If the implementation is sufficiently abstract, it
  starts to be a good idea to make specification and implementation
  identical.
Now I can access the details of the implementation--which is the specification--right from the REPL. Thanks, shader! (I'm presuming you're the author, in which case would you mind explaining the trailing 't printed on calls to 'src?)


2 points by waterhouse 5567 days ago | link

I, my curiosity provoked, looked through Anarki, and I can answer your question: t is the value returned by 'src, by virtue of being the value returned by 'ppr. (A call to 'src expands to a call to 'ppr-source, and the last expression in 'ppr-source is (ppr source.name). (Actually it's source* but putting that in italicizes the rest of this message.)) It is 'ppr by itself that has this annoying property.

  arc> (ppr '(def meh (x) (list (+ x 2) (+ x 3))))
  (def meh (x)
    (list (+ x 2) (+ x 3)))t
It would be nice if ppr printed a newline at the end. In fact, I'm almost certain it should, because a) it seems one would use it to print code for human eyes, and nothing else, b) readable code does not generally have separate expressions on the same line, and c) anything printed on one line is by definition not prettily formatted and can be pr'd instead of ppr'd.

I would like to simply redefine ppr, thus:

  (let old-ppr ppr (def ppr args (apply old-ppr args) (prn))
Unfortunately, ppr is apparently defined in terms of itself. And when recursive functions get redefined, the calls to what used to be themselves get redefined too. Using the above makes ppr print out way too many newlines:

  arc> (src defop)
  (from "srv.arc")
  (mac defop
  
       (name parm . body)
  
       (w/uniq gs
  
               (quasiquote (do (wipe (redirector* '(unquote name)
  ...
It's just horrible. Simple hack fix: go to pprint.arc, replace all instances of "ppr" with "ppr-fn", and then add (def ppr args (apply ppr-fn args) (prn)). Or just put up with the t.

-----

3 points by shader 5566 days ago | link

Yep, the trailing t and lack of newline are due to ppr.

Fortunately, I also happen to have an alternative version of ppr on anarki, under the lib folder, which has just been updated to handle multiple expressions and print newlines.

Just pull anarki again, and use

  (load "lib/ppr.arc")
It should redefine sp, len, and ppr, and make source code printing much more readable than the pprint.arc version ;)

-----