(defmacro mymacro
[X Y] <- (if (= X car) [head Y] (fail)))
(13-) (defmacro mymacro
[X Y] <- (if (= X car) [head Y] (fail)))
macro
mymacro
(14-) (car [3 4 5])
3
(15-)
Explanation:
1. Macros are applied to AST untill the fix point of the transformation
is reached.
2. Your macro do next thing: if it gets expression (A B) it translates
this expression to either (head B) or symbol wrong.
3. Steps of macro expansion for (car [1 2 3]):
input AST resulting AST working macro comment
a. (car [1 2 3) (head [1 2 3]) mymacro AST was changed, so
macro expander makes next iteration
b (head [1 2 3]) wrong mymacro AST was changed,
macro expander makes next itaration
c wrong wrong - -
So, your macro will be applied twice to expression (car X) and finally
you'll get symbol wrong.
Right way to write macro is to leave AST unchanged, if macro should not
be applied.
As variant:
(defmacro mymacro
[car Y] -> [head Y])
Or whole macro for c[ad]*r:
(defcc <expr> -*- := -*-;)
(defcc <a-d-to-head-tail>
"a" <a-d-to-head-tail> := [head <a-d-to-head-tail>];
"d" <a-d-to-head-tail> := [tail <a-d-to-head-tail>];
"r" <expr> := <expr>;)
(defcc <cxr?>
"c" "a" <a-d-to-head-tail> := [head <a-d-to-head-tail>];
"c" "d" <a-d-to-head-tail> := [tail <a-d-to-head-tail>];)
(define cxr?
Sym Expr <- (compile (function <cxr?>) (append (explode (str Sym))
[Expr]))
_ _ -> (fail))
(defmacro mymacro
[X Y] <- (cxr? X Y))
(20-) (caddddddddddddddddr [1 2 2 2 2 2 2 2 2 2 2 2 3 3 4 4 45 5 4 54
56 45 3 64 563 45 63])
45
05.02.2012 03:34, racke...@hotmail.com пишет:
Yes, your code is fully functional and ok.
https://gist.github.com/1752144
Critics are welcomed. To sum up; I generate a tuple containing two lists: one for CARs, one for CDRs using combinations found by a prolog.
(0-) (build-fun-template 2)
=> (@p [car cadr caar] [cdr cddr cdar])
Then I eval a definition for each symbol-function in those lists. They are separated because of the different types to declare.
(1-) (build-cxrs 4)
(1-) (tc+)
(2-) (cddddr [1 2 3 4 5 6 7])
[5 6 7] : (list number)
Racket noob, you can gain some lines in your code by writing:
(let CXR (map (function intern) (explode (str X))) ... ) instead of using (function str->symlist).
Cheers,
Minor changes may be done in CC part (some cleanup), as follows:
(defcc <expr> -*- := -*-;)
(defcc <a-d-to-head-tail>
"a" <a-d-to-head-tail> := [head <a-d-to-head-tail>];
"d" <a-d-to-head-tail> := [tail <a-d-to-head-tail>];
"r" <expr> := <expr>;)
(defcc <cxr?>
"c" "a" <a-d-to-head-tail> := [head <a-d-to-head-tail>];
"c" "d" <a-d-to-head-tail> := [tail <a-d-to-head-tail>];)
(defmacro mymacro
[X Y] <- (compile (function <cxr?>) (append (explode (str X))
[Y])))
Types for cxr maybe generated in-place by macro:
(tc +)
\* first, introduce type for declare function *\
(datatype declare-type
let B1 (shen-decons B)
A : symbol;
___________________
(declare A B) : B1;)
\* second, make list of cxr symbols, which already have type signatures *\
(datatype cxr-typed-list
___________________________
(value cxr) : (list symbol);)
(set cxr [])
\* third, declare a function which checks and declare type for cxr *\
(define declare-type-for-cxr
{ (list string) --> symbol --> A }
["c" "a" | Rest] Sym -> (declare Sym [[list A] --> A])
["c" "d" | Rest] Sym -> (declare Sym [[list A] --> [list A]]))
(define check-and-declare
{ symbol --> boolean}
CXR -> false where (element? CXR (value cxr))
CXR -> (do (declare-type-for-cxr (explode (str CXR)) CXR) (set cxr
[CXR | (value cxr)]) true))
(tc -)
\* with (tc +) defcc does not work properly - fails with syntax error
later I'll try to figure out why *\
(defcc <expr> -*- := -*-;)
(defcc <chek-for-a-d-r>
"a" <chek-for-a-d-r> := skip;
"d" <chek-for-a-d-r> := skip;
"r" <expr> := (do (check-and-declare (head <expr>)) <expr>);)
(defcc <check-for-cxr?>
"c" "a" <chek-for-a-d-r> := skip;
"c" "d" <chek-for-a-d-r> := skip;)
(defmacro declare-types-for-cxr-inplace
[X Y] <- (compile (function <check-for-cxr?>) (append (explode (str X))
[X Y])))
It would be great if shen-libs got a package to get datatypes of declare..., in order to type DECLARE and then DEFINE without {} if the type is to be able to code everytime in (tc +) mode if we want (except for Yacc for now).
To go back on my gist example, I do not use defmacro mymacro (I commented it actually) in order to auto-define a strict number of functions. Theoritically (function something) returns (fail) (or should) if I read the 'Shen Functions' page on Shen website correctly and if so, using mymacro to auto-generate functions may be obscure. How do we check CAR exists if it's not defined nor announced in *macros* ?
Anyway your explanation is great to understand how to build better program using typechecking, especially in these both cases (macro + defcc / eval + define + prolog + defcc). I hope the Shen Book will contain a lot of more examples than in the Qi Book.
Thanks,
At Mon, 06 Feb 2012 20:53:27 +0300,
> --
> You received this message because you are subscribed to the Google Groups "Qilang" group.
> To post to this group, send email to qil...@googlegroups.com.
> To unsubscribe from this group, send email to qilang+un...@googlegroups.com.
> For more options, visit this group at http://groups.google.com/group/qilang?hl=en.
>