| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384 | -module(scheme_prelude).-export([cons/2, car/1, cdr/1, list_p/1]).% Scheme prelude for programs compiled  from Scheme to Erlang.% A few conventions apply:%  - question marks become _p, so even? becomes even_p%  - exclamation marks are outlawed because the Scheme subset%    is pure-functional, so set! and its ilk are not present.%  - hyphens become _mn, so list-ref becomes list_mnref%  - underscores will become double underscores.% At present, this still leaves an ambiguity between even-p and% even?, but we will ignore that. All that aside, operator% symbols become three-character abbreviations whose names all% begin with an underscore. For example:%   + -> _pl%   * -> _st%   - -> _mn%   / -> _dv% Therefore, symbols can still be used in variable names, such% as *some-variable* which becomes _stsome_mnvariable_st. This% would be hideous to work with, but for our purposes is% transparent enough.% variadic functions_pl([A]) -> A;_pl([A|B]) -> A + _pl(B)._st([A]) -> A;_st([A|B]) -> A * _st(B)._mn([A]) -> A;_mn([A|B]) -> A - _mn(B).list(L) -> L._eq(A, B) -> A == B.cons(A, B) -> [A|B].car([A|_]) -> A.cdr([_|B]) -> B.append(A, B) -> lists:append(A, B).filter(Proc, L) -> lists:filter(Proc, L).map(Proc, L) -> lists:map(Proc, L).member(X, [X|L]) -> [X|L];member(X, [_|L]) -> member(X, L);member(_, []) -> false.assoc(X, [{X, A}|L]) -> {X, A};assoc(X, [{_, _}|L]) -> scheme_prelude:assoc(X, L);assoc(_, []) -> false.reverse(L) -> lists:reverse(L).reduce(Proc, [X|L]) -> lists:foldl(Proc, X, L).list_qs([_|B]) -> scheme_prelude:list_qs(B);list_qs([]) -> true;list_qs(_) -> false.null_qs([]) -> true;null_qs(_) -> false.pair_qs([_|_]) -> true;pair_qs(_) -> false.number_qs(X) -> is_number(X).equals_qs(X, Y) -> X == Y.length([X|Y]) -> 1 + scheme_prelude:length(Y);length([]) -> 0.symbol_qs(X) -> is_atom(X).boolean_qs(true) -> true.boolean_qs(false) -> true.boolean_qs(_) -> false.and(L) -> all(scheme_prelude:is_true, L).or(L) -> any(scheme_prelude:is_true, L).not(false) -> true;not(_) -> false.is_true(false) -> false;is_true(X) -> X.
 |