Closed PhilLast closed 4 years ago
Have committed and pushed anyway. The protocol for functions mirroring the commands that take -options is as follows:
It appears that Link uses a namespace as an optional left argument. I prefer this to positional booleans. Another alternative I guess is a left argument of name/value pairs, also optional.
Finally, is it possible to pass everything in on the right, so the API looks similar to the UserCommand?
For example: ]UserCommand Arg1 Arg2 -op1 -op2=y
APICall Arg1 Arg2 ('op1' '') ('op2' 'y')
I guess a problem would be an optional 2nd argument. But could it be inferred from the structure? In other words, is it possible for a user command to have an argument that is not a simple string?
If this works it seems the best. There is high degree of similarity between user command and API call, no positional stuff, and no need to create and populate a namespace.
I have re-read the user command user guide.
By definition, every argument is a simple text string. Therefore if we insist that modifiers are two item vectors, it should be no problem to mimic the syntax of a user command. In fact, we could even go as far as letting the user put the modifiers before, after, or inbetween arguments as user commands allow, though I'm not suggesting that.
Any reason this worn work or is not a good idea?
One advantage is that this leaves the left argument available for something else, perhaps a namespace reference for explicit context. When executing a user command, often the current namespace is an implicit argument. When calling the API equivalent, we don't want to change the current space just to get the command to run, so passing in a ref to space as the left arg is quite useful.
Re. the last point the API framework already takes care of this. If you )CS into a project space then the item(s) of the argument to a project or item method will be prefixed with the current space if they don't start with "#". After )cs #.myproject
both of
⎕se.acreAPI.itemmethod 'this' 'and.that'
]acre.itemmethod this and.that
will result in the itemmethod
method receiving the argument
'#.myproject.this' '#.myproject.and.that'
.
The structure of the argument to API fns is rather flexible. By the time an acre method gets its argument via the user command framework and acre's shared/project/item process or via the API framework it's a vector of strings - words and quoted strings - and the options are variables in a locally accessible space. The argument to ⎕se.acreAPI.openproject
is a folder path as a simple string or nested singleton; or a two item nested vector of folder path and target space.
But certainly there is currently no expectation that any item will be itself a nested string so your first option is feasible.
... and although I hate typing I must admit it's probably better than the positional thing I described even though it is rediculously verbose. I suppose we could still use abbreviation.
Currently we can do
]createproject folder space -var=on ⍝ vs -variables=on
so I suppose we could do
⎕se.acreAPI.createproject 'folder' 'space' ('var' 'on') ⍝ vs ('variables' 'on')
I'd prefer to use it even though I'd rather not have to code it.
If we passed a single option pair to a method without an argument it would have to be enclosed:
⎕se.acreAPI.method ⊂'option' 'value'
I agree with space delimited name value pairs over ordered inputs.
It makes the whole thing much easier to extend and with how seldom I do it, I don’t have an issue typing full parameter names.
If we passed a single option pair to a method without an argument it would have to be enclosed
True. Alternatively, would it be possible to insist on at least an empty argument ala a dfn? For example:
⎕se.acreAPI.method '' ('option' 'value')
Or, every API call requires precisely two arguments - a list of argument and a list of option/value pairs:
⎕se.acreAPI.method (arg1 arg2) (('op1' 'value') ('op2 'val2') etc )
Phil, I'm not trying to over think this (I think!), I'm trying to come up with something that will work for other apps as well as Acre - that's why I was concerned about leaving the left arg available.
One problem regarding my posting one hour ago is that the process to prefix items with the current space doesn't actually work!!
... (but it will do.)
Currently proceeding on the basis of a potentially mixed depth three list of arg strings and option pairs
⎕se.acreAPI.fn 'arg1' ( 'opt1' '' ) 'arg2' ( 'opt2 '' )
.
But can easily institute the two list
⎕se.acreAPI.fn ( 'argument' 'list' ) ( ( 'option' 1 ) ( 'list' 0 )
at a later stage if needed.
The API framework consists in a couple of small functions that have become a mess so it's easier to rethink and rewrite.
One thing that could be changed at this time is that the ⎕SE.acre.run
function could disappear and the pointer functions in ⎕SE.acreAPI
could be put into ⎕SE.acre
itself.
⎕SE
but would require changes to make at your end if you've automated any calls.
One thing that could be changed at this time is that the ⎕SE.acre.run function could disappear and the pointer functions in ⎕SE.acreAPI could be put into ⎕SE.acre itself.
Please do. I was just going to suggest this myself. I prefer one namespace in []SE.
One thing - would anyone object if I rename the primary code space from ⎕SE.acre._code
to ⎕SE.acre.zcode
or ⎕SE.acre.z_code
.
Although ⎕NL
puts '_' after the Latin capitals and the diacritical and "foreign" chars after the minuscules, autocomplete puts '_' first of all, the others interspersed after their unaccented counterparts, leaving 'zZ' to bring up the rear.
The renaming would put all the API functions before the namespace that can't easily be hidden.
I actually like @PaulMansour convention of using "Core" as the primary namespace.
I don't reach in there for anything, so I'm ok with any change. I've started using Main as the main space in new projects. It would be nice if top level namespace naming conventions were adhered to across projects. Same for resource folder names. I've been attempting this with AcreTools.
I would not rename the code space just so it shows up less prominently in autocomplete for those using the API.
I'm not suggesting you call it Main (yet!) … I haven't really thought about how AcreTools wants this stuff to look like in detail. Would like to discuss with all at some point.
I've been considering a clear separation of API vs core code simply by exporting a reference to a sub or sibling namespace. Consider the project space Acre
#.CarlisleGroup.Acre.API
#.CarlisleGroup.Acre.Core
The API space would hold public functions that simply call the private counterparts in either the parent or sibling space (eg. API.Open←{##.Core.Open ⍵}
). I'm not pretending this is a new concept, but this combined with the idea that packages are installed in a dedicated space and references then created to the API space would make it a bit more clear what the API is.
Say you install Acre in the session space. If acre is configured to expose the API
space, you would end up with something like this:
⎕SE._packages.CarlisleGroup.Acre
⎕SE.acre←⎕SE._packages.CarlisleGroup.Acre.API
Of course, this would only be a convention, nothing that could be enforced perhaps.
Gil, very nice. Solves the problem of arbitrary depth of namespace structure for dev purposes, and easy access to API.
I just built something like :
⎕SE._packages.CarlisleGroup.Acre
to hold the AcreTools code (and any other apps that use the AcreTools) for user command, which is fine, no one is bothered by the depth when using a UCMD. But for the API, obviously a problem. ( I also used the name []SE.AcreTools as the root, which is no good I realize, as I want that name at the top for the AcreTools API).
I am also trying to formalize the relationship between UCMD and API, and this fits in very well.
Phil, correct me if I am wrong, but if one is using the UCMD framework to instantiate the API, then unless you are doing some hackery in the List function, you can't make an API call until you have called an acre user command at least once.
I'm addressing this in AcreTools with my own start session framework.
I call acre.projects in my startup.dyalog to get around this.
On Fri, 9 Aug 2019, 17:47 Paul Mansour, notifications@github.com wrote:
Phil, correct me if I am wrong, but if one is using the UCMD framework to instantiate the API, then unless you are doing some hackery in the List function, you can't make an API call until you have called an acre user command at least once.
I'm addressing this in AcreTools with my own start session framework.
— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/the-carlisle-group/Acre-Desktop/issues/184?email_source=notifications&email_token=AD5XJHPHTEHS57RMGJV5ZMTQDWNQZA5CNFSM4H6LVAN2YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOD37GB4I#issuecomment-519987441, or mute the thread https://github.com/notifications/unsubscribe-auth/AD5XJHPV7VBAVOQGQSGY2OLQDWNQZANCNFSM4H6LVANQ .
Is it startup.dyalog or setup.dyalog?
Also do you know how this is called? Is it deep in the interpreter or a hack in []SE somewhere?
Sorry, setup.dyalog. it's part of the salt boot process.
On Fri, 9 Aug 2019, 18:02 Paul Mansour, notifications@github.com wrote:
Is it startup.dyalog or setup.dyalog?
Also do you know how this is called? Is it deep in the interpreter or a hack in []SE somewhere?
— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/the-carlisle-group/Acre-Desktop/issues/184?email_source=notifications&email_token=AD5XJHN6CODMKKIX4MYWVZDQDWPKJA5CNFSM4H6LVAN2YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOD37HIWI#issuecomment-519992409, or mute the thread https://github.com/notifications/unsubscribe-auth/AD5XJHPQEJ2BTFBILCGCUSLQDWPKJANCNFSM4H6LVANQ .
So that means is in OnWorkspaceLoaded callback somewhere. Ok, thanks.
Phil, correct me if I am wrong, but if one is using the UCMD framework to instantiate the API, then unless you are doing some hackery in the List function, you can't make an API call until you have called an acre user command at least once.
Bit late but yes indeed. Acre isn't there and is copied in by the first command that's called.
So that means is in OnWorkspaceLoaded callback somewhere. Ok, thanks.
In a new, unchanged session:
↑⎕se ⎕wg 'event'
GestureZoom ⎕SE.Fonts.ZoomSession
WorkspaceLoaded ⎕SE.Dyalog.Callbacks.WSLoaded
SessionPrint 0
Can't see any reference to "setup.dyalog" in ⎕SE.Dyalog.Callbacks.WSLoaded
or anywhere else in ⎕SE
. Not in 17.0 that is. But it's certain that WSLoaded
does get called at the start of the session.
Whatever you do, do not use setup.dyalog!
WSLoaded probably loads a script, which in turn runs setup.dyalog, my guess.
This is perhaps going off topic even further (and I know we've been invited to talk to Dyalog about all this post user meeting) but I think I would like to see the session configuration in a structured text file akin to the Acre Project config file.
Packages could then be installed in the session file and each package could contribute a number of user commands via its API.
Same thing with workspaces. They would be config files that optionally define projects and or packages to be loaded.
(and I know we've been invited to talk to Dyalog about all this post user meeting)
Not me!
But to the question at hand, why not just a scripted namespace instead, like a user command file, only done right?
Packages could then be installed in the session file and each package could contribute a number of user commands via its API.
Understood.
Same thing with workspaces. They would be config files that optionally define projects and or packages to be loaded.
Not understood… I vaguely remember a new name for the concept of workspace defined in a config file... but you had another name for it, no?
(and I know we've been invited to talk to Dyalog about all this post user meeting)
Not me!
OK, me neither. That was an optimistic interpretation of the email Kai copied us in on. I think the wording was that Morten has every intention to invite us all in the design discussions :)
but you had another name for it, no?
No, I couldn't think of a better name for it, so I called it a workspace. It is a slight change of perspective. You have defined that a project can load other projects via its config file. My suggestion is that you could extend that by defining a workspace as a collection of projects that are all opened at the same time. The config file would simply list the projects and potentially other IDE settings but lack properties that are project specific (ProjectSpace
, Name
, Version
etc.)
Reread Andy's mail that Kai forwarded to us. Is this what you're doing Kai? Using ]usetup?
]USetup -?? ⍝ for more info
───────────────────────────────────────────────────────────────────────────────
]UCMD.USetup
Initialise user's setup
This command is used to (re-)initialize a user's setup by running a specific function every
time the user command system is (re-)started, e.g. upon starting Dyalog APL (with SALT
enabled). The function can also be run at any time with ]USetup
To use this functionality, save a function named "Setup" (or namespace with such a function) in
a file called "setup.dyalog" in "C:\Users\Phil\Documents\MyUCMDs\" or in one of the current
SALT workdirs (C:\Users\Phil\Documents\Dyalog APL-64 17.0 Unicode Files\Code,
[DYALOG]\Library\Core, [DYALOG]\Library\Conga, [SALT]).
If the Setup function is monadic it will be called with ]USetup's argument or with 'init' when
Dyalog APL starts.
Examples:
To always let F2 list variables and F3 list functions:
Setup←{(')VARS',⊂'ER') (')FNS',⊂'ER') ⎕PFKEY¨2 3}
]Save Setup C:\Users\Phil\Documents\MyUCMDs\ -makedir
To return the filename which will be used followed by a Boolean indicating if it exists or
not:
]USetup -info
To return a list of all current search paths with a Boolean for each indicating if that file
exists:
]USetup -info=list
The file that will be run is the topmost existing one (if any exists).
]USetup -info=list
C:\Users\Phil\Documents\MyUCMDs\setup.dyalog 0
C:\Users\Phil\Documents\Dyalog APL-64 17.0 Unicode Files\Code\setup.dyalog 0
[DYALOG]\Library\Core\setup.dyalog 0
[DYALOG]\Library\Conga\setup.dyalog 0
[SALT]\setup.dyalog 0
Looks innocuous enough and given that there are no examples in any path in my machine it doesn't look as though I'd be likely to break anything by using it.
And even if Dyalog is thinking of replacing it, how many years are we looking at? I guess they would then be asking not just us few whose code they were about to break before abandonning it.
Even so I think I'd rather have things closer to home and initialise whatever I want when I want it. If I'm going to change anything I want to know what it was like beforehand. If my session is not default at the start I can't assume that what acre's doing is going to work the same anywhere else.
In any case, this doesn't bode well ...
]usetup -info
C:\Users\Phil\Documents\MyUCMDs\setup.dyalog 0
setup←{⎕←⍵}
]save setup C:\Users\Phil\Documents\MyUCMDs\ -makedir
C:\Users\Phil\Documents\MyUCMDs\setup.dyalog
]usetup -info
C:\Users\Phil\Documents\MyUCMDs\setup.dyalog 1
]usetup
* Command Execution Failed: VALUE ERROR
]usetup arthur
* Command Execution Failed: VALUE ERROR
It's case sensitive. The function I mean.
When you name it "Setup" it works as described.
I am using this mechanism for a long time now. Back then there was no ]Usetup. Back then it had to be a namespace script.
On Sat, 10 Aug 2019 at 08:32, PhilLast notifications@github.com wrote:
In any case, this doesn't bode well ...
]usetup -info
C:\Users\Phil\Documents\MyUCMDs\setup.dyalog 0
setup←{⎕←⍵} ]save setup C:\Users\Phil\Documents\MyUCMDs\ -makedir
C:\Users\Phil\Documents\MyUCMDs\setup.dyalog
]usetup -info
C:\Users\Phil\Documents\MyUCMDs\setup.dyalog 1
]usetup
Command Execution Failed: VALUE ERROR
]usetup arthur
Command Execution Failed: VALUE ERROR
— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/the-carlisle-group/Acre-Desktop/issues/184?email_source=notifications&email_token=AD5XJHOBLCBYX47AKJ2ER5DQDZVHLA5CNFSM4H6LVAN2YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOD4AIB7Y#issuecomment-520126719, or mute the thread https://github.com/notifications/unsubscribe-auth/AD5XJHPCQZCAP4PDJ75F7PTQDZVHLANCNFSM4H6LVANQ .
On the topic of case sensibility, ]User.Commands
are not but APL function names certainly are.
With API fns and commands to correspond one-to-one, I'm currently jumping through hoops to get them to run the same code as far as possible.
It would be much simpler if their names were actually identical. The reason they're not is because the API fns were initially just a few peeks into acre's internals that didn't seem to warrant being made into user commands and they were invoked by passing a case-agnostic "name" into the run
function.
Many acre commands have borne the same PascalCaseName for ten years and are referred to as such thoughout the documentation. The API is barely a couple of years in its oldest manifestation.
Given the availability of autocompletion I propose to rename all the API fns to pascal case mirroring the commands.
Sounds right to me.
Please do.
If one were going to generalize the concept of an API with an acre project, what name would give the parameter that specifies the API space: API
or EntrySpace
or something else?
API
is better. The API could in theory be a simple/single function.
This became a very wide ranging thread but the main issue was settled in Acre 6.0.0+258 2019-08-31 21:51.
Latest change Acre 6.0.2+270 2019-09-10 13.13 allowed the option names to be abbreviated and added then to the command log message.
I now have acreAPI functions that mirror all acre commands. Still a few hiccups here and there but working in the main.
Decision to make is what to do about options.
So far the only one to rear its head was -when that I set at zero for acreAPI.changes and one for acreAPI.projects. With acreAPI.createproject, acreAPI.erase and acreAPI.openproject it gets more complicated. So for now I've used the optional left argument to supply values:
For -when,
changes arg
defaults to no date but1 changes arg
adds the date-time and with a string date-time'2019-07-05 13:30' changes arg
restricts to changes made since.Also for -when
projects ''
defaults to no date while1 projects''
adds the date-time.For -casecode, -keephistory and -variables
createproject arg
defaults to having them all Off while for -track and -dependenciesopenproject arg
defaults to both On.How to supply an alternative? Simplest would be a positional boolean:
e.g.
1 0 1 createproject arg
meaning-casecode=On -keephistory=Off -variables=On
[say] but then the order would have to be prescribed.We could reproduce the option spec; hyphens, equal-signs an' all; and run it through Dan's parser but I was hoping for a bit less verbosity.
Any ideas?