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: Alexey Veretennikov
Subject: Re: [Bug-apl] [PATCH]: allow using lambdas in ]USERCMD
Date: Fri, 24 Feb 2017 20:24:46 +0100
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/25.1 (darwin)

Hi,

The solution with )continue is not helping me: I want to have the my
commands available in all workspaces.
Right now if I )load workspace, all functions from previous workspace
got lost.
But user commands stays! meaning they will refer to unexisting
functions.
With the introduction of lambdas as user commands one could overcome
this limitation by encoding necessary functionality as lambdas.

In Dyalog APL I can create a file MyUCMDs/setup.dyalog with the
contents:
Setup←{_←⎕SE.UCMD'cd /Users/alexeyv/Sources/apl/dyalog-workspaces '}

and every time I start the interpreter my current directory is changed
to the specified.

I want to have something like this in GNU APL, so every time I run
interpreter I can:
- change the directory
- set my user commands
regardless of existence of CONTINUE workspace.

This could be solved by introducing the ~/.gnu-apl/setup.apl file with
APL source code, which if exists executes before any other workspaces.

How does it sound? If it is ok I'll implement it.

Juergen Sauermann <address@hidden> writes:

> 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 "
>
>
>
>
>
>

-- 
Br,
/Alexey



reply via email to

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