While Unix did win, that doesn't mean that Unix's names won. It's Unix's features that won. So it's reasonable to provide certain operations, but implementing them in terms of (system "unix-command-name ...") is not.
Of course, I use Mac OS X, so it's not like I'm adversely impacted. But the point still stands.
(def inf-iter (f c)
" Creates a lazy-list-like scanner whose first element
is `c' and whose succeeding elements are the result of
`f' applied on the previous element. "
(let d nil
(make-scanner
'car (fn () c)
'cdr (fn () (or d (= d (inf-iter f (f c))))) )))
arc> (= p2 (inf-iter [* 2 _] 1))
#3(tagged scanner (#<procedure> . #<procedure>))
arc> (car p2)
1
arc> (repeat 10 (= p2 (cdr p2)) (prn (car p2)))
2
4
8
16
32
64
128
256
512
1024
nil
The more I think about these scanners, the cooler they seem. It's a very neat abstraction, and a great way to integrate laziness into Lisp in a very Lisp-y manner.
It would be neat too if function application would destructure using Arc-side 'car and 'cdr (Scheme side '_car '_cdr, or '__car '__cdr on Arc-wiki now that we have FFI). Basically the requirement for 'apply would be a scanner, not a 'cons; after all, 'apply does not mutate the applied list.
However as is it's possible to use p-m: or kennytilton's dsb (which should really be ds-b: and put on the arc-wiki.git) for destructuring scanners.
Also the syntax for creating scanners should really be neater. Possibly this might help:
(mac scanner args
(let (a d) nil
( (afn ((opt val . args))
(if
(iso opt ''car)
(= a val)
(iso opt ''cdr)
(= d val)
(err:tostring:pr "Unknown option - " opt))
(if args (self args)))
args)
(w/uniq (a-v d-v a-valid d-valid)
`(let (,a-v ,d-v ,a-valid ,d-valid) nil
(make-scanner
'car (fn ()
(if ,a-valid ,a-v
(= ,a-valid t
,a-v ,a)))
'cdr (fn ()
(if ,d-valid ,d-v
(= ,d-valid t
,d-v ,d))))))))
'inf-iter can then be defined somewhat more neatly as:
(def inf-iter (f c)
(scanner
'car c
'cdr (inf-iter f (f c))))
All the above untested of course, including the grandparent post ^^ I'm sitting bored in the office ^^
Yeah, agreed. In general, I'd like to see ac.scm calling out to Arc functions as much as possible, to maximize the power of in-Arc tinkering via redef/defm, like scanner.
First question: yes, the people here who've tried generally use an Apache front-end which ends up becoming a proxy server for localhost:8080. Second question: none that I know of. Try asking sacado and wfarr.
Hmm. How big is the change to ac.scm? We've already made at least one rather serious change to ac.scm on the arc-wiki.git (the define-your-own-object-in-functional-position thing), I wonder how much ac.scm will eventually change.
One of the changes is that mzscheme's FFI import a few names starting with an underscore, thus clashing with Arc's namespace. I modified ac.scm so that Arc's names start with a double underscore.
The other problem is that the mzscheme type #<cpointer> is not recognized by Arc : I had to change ac-type so as to add it.
Ah. Right. (And I even worried about similar things when writing make-br-fn...). Well, it would work in simple cases, but let/with are looking like better ideas.
Actually, if we add another primitive (with $ or xdef) which works using mzscheme's namespace-undefine-value!, we could have tempset maintain a global list of tempset variables, and cleartemps go through and undefine them.
Yeah, definitely. But, this specific problem is in the context of writing a restricted eval, like for a browser plugin or something like that. I was thinking of doing a global replace of set with tempset and then cleaning up after one plugin runs. But maybe that is the wrong way to do it.
If you did this for all local variables, and then used namespace-undefine-variable! to delete any defs that had been evaluated, I think you would get a fairly well restricted eval.
I agree with you - I think this is roughly the right idea, I just hadn't found namespace-undefine-variable! when I asked this question.
I think there's still somewhat of a problem with wrapping variables in a "let" with their deep copies - that prevents internal code from wrapping builtins and having other builtins use the wrap, because the let will make the builtin-wrap scope different from the outer scope. But you can do the special-suffix thing in this case.