basic: changing curry operator to (~<), i thought plunger (or grabber) is semantically less awkward than the arrow

This commit is contained in:
minjaesong
2020-12-27 02:56:18 +09:00
parent 31ae5bbbbc
commit 83a53499bc
10 changed files with 18 additions and 36 deletions

View File

@@ -1255,7 +1255,7 @@ if no arg text were given (e.g. "10 NEXT"), args will have zero length
}
return keys;
}},
"<~" : {f:function(lnum, stmtnum, args) { // CURRY operator
"~<" : {f:function(lnum, stmtnum, args) { // CURRY operator
return twoArg(lnum, stmtnum, args, (fn, value) => {
// TODO test only works with DEFUN'd functions
if (fn.astLeaves === undefined) throw lang.badFunctionCallFormat("Only works with DEFUN'd functions yet");
@@ -1421,12 +1421,12 @@ bF._opPrc = {
"STEP":41,
"!":50,"~":51, // array CONS and PUSH
"#": 52, // array concat
"<~": 100, // curry operator
"~<": 100, // curry operator
"~>": 101, // closure operator
"=":999,
"IN":1000
};
bF._opRh = {"^":1,"=":1,"!":1,"IN":1,"~>":1}; // <~ and ~> cannot have same associativity
bF._opRh = {"^":1,"=":1,"!":1,"IN":1,"~>":1}; // ~< and ~> cannot have same associativity
// these names appear on executeSyntaxTree as "exceptional terms" on parsing (regular function calls are not "exceptional terms")
bF._tokenise = function(lnum, cmd) {
var _debugprintStateTransition = false;
@@ -2887,24 +2887,6 @@ bF._interpretLine = function(lnum, cmd) {
}
});
// automatically apply currying
// '(<~) FNQ (P X Y)' into '(<~) FNQ ((<~) P ((<~) X Y))'
// FIXME this autocurrying is very likely to be a janky-ass-shit
syntaxTrees.forEach(syntaxTree => {
if (syntaxTree !== undefined) {
bF._recurseApplyAST(syntaxTree, tree => {
if (tree.astValue == "<~" && tree.astLeaves[1] !== undefined && tree.astLeaves[1].astLeaves[0] !== undefined) {
let subTree = new BasicAST();
subTree.astValue = "<~";
subTree.astType = "op";
subTree.astLnum = tree.astLnum;
subTree.astLeaves = [tree.astLeaves[1], tree.astLeaves[1].astLeaves[0]];
tree.astLeaves[1] = subTree;
}
});
}
});
if (_debugprintHighestLevel) {
syntaxTrees.forEach((t,i) => {
serial.println("\nParsed Statement #"+(i+1));

View File

@@ -160,13 +160,13 @@ Here, \code{K} will contain the values of $1!$, $2!$ \ldots\ $10!$. Right now we
\begin{lstlisting}
10 DEFUN F(K,T)=ABS(T)==K
20 CF=F<~32
20 CF=F~<32
30 PRINT CF(24) : REM will print 'false'
40 PRINT CF(-32) : REM will print 'true'
\end{lstlisting}
% NOTE: you can't use \basiccurry within \code{}
Here, \code{CF} is a curried function of \code{F}; built-in operator \code{$<\!\sim$} applies \code{32} to the first parameter of the function \code{F}, which dynamically returns a \emph{function} of \code{CF(T) = ABS(T) == 32}. The fact that Curry Operator returns a \emph{function} opens many possibilities, for example, you can create loads of sibling functions without making loads of duplicate codes.
Here, \code{CF} is a curried function of \code{F}; built-in operator \code{$\sim\!<$} applies \code{32} to the first parameter of the function \code{F}, which dynamically returns a \emph{function} of \code{CF(T) = ABS(T) == 32}. The fact that Curry Operator returns a \emph{function} opens many possibilities, for example, you can create loads of sibling functions without making loads of duplicate codes.
\section[Wrapping-Up]{The Grand Unification}
@@ -176,8 +176,8 @@ Using all the knowledge we have learned, it should be trivial\footnote{/s} to wr
10 DEFUN LESS(P,X)=X<P
11 DEFUN GTEQ(P,X)=X>=P
12 DEFUN QSORT(XS)=IF LEN(XS)<1 THEN NIL ELSE
QSORT(FILTER(LESS<~HEAD(XS),TAIL(XS))) # HEAD(XS)!NIL #
QSORT(FILTER(GTEQ<~HEAD(XS),TAIL(XS)))
QSORT(FILTER(LESS~<HEAD(XS),TAIL(XS))) # HEAD(XS)!NIL #
QSORT(FILTER(GTEQ~<HEAD(XS),TAIL(XS)))
100 L=7!9!4!5!2!3!1!8!6!NIL
110 PRINT L
120 PRINT QSORT(L)

View File

@@ -62,7 +62,7 @@
%% BASIC operators %%
\newcommand\basicexp{\raisebox{0.25ex}{\scriptsize\wedge}}
\newcommand\basiccurry{$<\!\sim$}
\newcommand\basiccurry{$\sim\!<$}
\newcommand\basicclosure{$\sim\!>$}
% Title styling