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: Juergen Sauermann
Subject: Re: [Bug-apl] [PATCH]: allow using lambdas in ]USERCMD
Date: Thu, 23 Feb 2017 19:54:12 +0100
User-agent: Mozilla/5.0 (X11; Linux i686; rv:45.0) Gecko/20100101 Thunderbird/45.2.0

Hi Alexey,

I believe it would be more useful to have a facility that loads an arbitrary apl script at startup
instead of a specific one for user defined commands.

Actually you can do that already with the )CONTINUE workspace, which is loaded automatically
if it exists. You could replicate the )CONTINUE logic (or simply call your workspace CONTINUE.apl).

I would also suggest that we try to exploit existing functionalities before we invent new ones.
Most non-standard functions of GNU APL are fairly useless because nobody knows them.

/// Jürgen


On 02/23/2017 07:11 PM, Alexey Veretennikov wrote:
Hi,

Actually I'm thinking about a patch which will load these usercmds from
the config file at the startup. In this case every user will be
able to create own commands (like ]pwd and ]cd below) to interact with
interpreter and store them independent of the workspaces.

It will definitely helpful for me, what about others?

Christian Robert <address@hidden> writes:

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]