bug-apl
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Bug-apl] [PATCH]: allow using lambdas in ]USERCMD


From: Christian Robert
Subject: Re: [Bug-apl] [PATCH]: allow using lambdas in ]USERCMD
Date: Thu, 23 Feb 2017 12:32:32 -0500
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101 Thunderbird/45.7.0

It would be fun if those ]USERCMD could be saved in workspace  and )loaded back.

Not sure if it's possible ...

Xtian.


On 2017-02-23 12:04, Juergen Sauermann wrote:
Hi Alexey, Blake,

I have applied the patch, *SVN 892*.

I don't think that it hurts too much even though its not APL.
Nor are lambdas, so the ⍎ of )COMMANDs and {...} should fit nicely.

/// Jürgen


On 02/23/2017 08:47 AM, Alexey Veretennikov wrote:
Hi,

I'm updating the ]USERCMD functionality which is already non-standard extension 
in GNU
APL. Similar extension exists in Dyalog APL for quite many years as
well. These commands targeted use in the interpreter and have nothing to do
with a new syntax.
What I did is just fixed its limitation where I always had to
create a named function to add a user command.

P.S. Example with ]pwd was bogus, the proper one is

      ]usercmd ]pwd {⎕FIO 30 ⍵}
    User-defined command ]pwd installed.
      ]pwd
/Users/alexeyv


Blake McBride <address@hidden> writes:

Not sure I like this. Doesn't seem like APL. You are mangling program-ability 
with system commands. APL
has no history of that. It may be an okay idea, but it's not APL.

Adding program-ability to system commands is essentially adding a whole new 
syntax to APL.

Just one opinion.

Blake

On Wed, Feb 22, 2017 at 4:18 PM, Alexey Veretennikov <address@hidden> wrote:

 Hi,

 The proposed patch allows usage of dfns as a ]USERCMD.
 The mode (monadic or dyadic) is not needed since it is derived from the
 lambda function itself.

 Possibility to use lambdas as a user commands allows to have commands
 without polluting the global namespace with the function names.

 Usage example:

 ]usercmd ]pwd {⎕FIO 30 ⍵ ← ⍺}
 User-defined command ]pwd installed.

 ]pwd
 /Users/alexeyv/Sources/apl-svn/src

 ]usercmd ]cd {⎕FIO[54] (⎕IO+1) ⊃ ⍵ ← ⍺}
 User-defined command ]cd installed.

 ]cd /Users/alexeyv
 0

 ]pwd
 /Users/alexeyv

 --
 Br,
 /Alexey

 Index: src/Command.cc
 ===================================================================
 --- src/Command.cc (revision 891)
 +++ src/Command.cc (working copy)
 @@ -1277,6 +1277,7 @@
 // ]USERCMD REMOVE ]existing-command
 // ]USERCMD ]new-command APL-fun
 // ]USERCMD ]new-command APL-fun mode
 + // ]USERCMD ]new-command LAMBDA-fun
 //
 if (args.size() == 0)
 {
 @@ -1321,14 +1322,54 @@
 return;
 }

 - if (args.size() > 3)
 + // check if the user command is not followed by the string
 + if (args.size() == 1)
 + {
 + out << "BAD COMMAND+" << endl;
 + MORE_ERROR() << "user command syntax in ]USERCMD: ]new-command APL-fun 
[mode]";
 + return;
 + }
 + UCS_string command_name = args[0];
 + UCS_string apl_fun = args[1];
 + int mode = 0;
 +
 + // check if lambda
 + bool is_lambda = false;
 + if (apl_fun[0] == '{')
 {
 + // looks like the user command is a lambda function.
 + UCS_string result;
 + // lambdas could contain spaces, collect all arguments in one string
 + for (int i = 1; i < args.size(); ++ i)
 + {
 + result << args[i];
 + }
 + // check if lamda-function closed properly
 + if (result.last() == '}')
 + {
 + is_lambda = true;
 + apl_fun = result;
 + // determine the mode: if both alpha and omega present, assume dyadic,
 + // otherwise - monadic usage
 + mode = (apl_fun.contains(UNI_OMEGA) && apl_fun.contains(UNI_ALPHA)) ? 1 : 0;
 + }
 + else
 + {
 + out << "BAD COMMAND+" << endl;
 + MORE_ERROR() << "not found closing } in lambda function";
 + return;
 + }
 + }
 +
 + if (args.size() > 3 && !is_lambda)
 + {
 out << "BAD COMMAND+" << endl;
 MORE_ERROR() << "too many parameters in command ]USERCMD";
 return;
 }

 -const int mode = (args.size() == 3) ? args[2].atoi() : 0;
 + // check mode
 + if (!is_lambda && args.size() == 3) mode = args[2].atoi();
 if (mode < 0 || mode > 1)
 {
 out << "BAD COMMAND+" << endl;
 @@ -1339,11 +1380,11 @@

 // check command name
 //
 - loop(c, args[0].size())
 + loop(c, command_name.size())
 {
 bool error = false;
 - if (c == 0) error = error || args[0][c] != ']';
 - else error = error || !Avec::is_symbol_char(args[0][c]);
 + if (c == 0) error = error || command_name[c] != ']';
 + else error = error || !Avec::is_symbol_char(command_name[c]);
 if (error)
 {
 out << "BAD COMMAND+" << endl;
 @@ -1355,28 +1396,31 @@
 // check conflicts with existing commands
 //
 #define cmd_def(cmd_str, _cod, _arg, _hint) \
 - if (check_name_conflict(out, cmd_str, args[0])) return;
 + if (check_name_conflict(out, cmd_str, command_name)) return;
 #include "Command.def"
 - if (check_redefinition(out, args[0], args[1], mode))
 + if (check_redefinition(out, command_name, apl_fun, mode))
 {
 out << " User-defined command "
 - << args[0] << " installed." << endl;
 + << command_name << " installed." << endl;
 return;
 }

 // check APL function name
 - //
 - loop(c, args[1].size())
 + // Only needed when not a lambda function
 + if (!is_lambda)
 {
 - if (!Avec::is_symbol_char(args[1][c]))
 - {
 - out << "BAD COMMAND+" << endl;
 - MORE_ERROR() << "bad APL function name in command ]USERCMD";
 - return;
 - }
 + loop(c, apl_fun.size())
 + {
 + if (!Avec::is_symbol_char(apl_fun[c]))
 + {
 + out << "BAD COMMAND+" << endl;
 + MORE_ERROR() << "bad APL function name in command ]USERCMD";
 + return;
 + }
 + }
 }

 -user_command new_user_command = { args[0], args[1], mode };
 +user_command new_user_command = { command_name, apl_fun, mode };
 user_commands.append(new_user_command);

 out << " User-defined command "






reply via email to

[Prev in Thread] Current Thread [Next in Thread]