<@ OMT>-------------------------- |
|
<@ LETVARLIT>string|\n</@> |
<@ OMT>two characters, \ and n</@> |
<@ LETVARLIT>string|Jon 'Maddog' Orwant</@> |
<@ OMT>literal single quotes</@> |
<@ OMT>-------------------------- |
|
<@ LETVARLIT>string| |
<@ OMT>a "newline" character</@> |
<@ LETVARKEY>string|__Newline</@> |
<@ OMT>a "newline" character</@> |
<@ LETVARLIT>string|Jon "Maddog" Orwant</@> |
<@ OMT>literal double quotes</@> |
<@ LETVAREXPLIT>string|Jon &pipe;Maddog&pipe; Orwant</@> |
<@ OMT>Because | and <@ and </@ are significant there are ways to quote them</@> |
<@ LETVARLIT>Bruce Goose|布魯斯鵝</@> |
<@ OMT>a variable name containing spaces. |
<@ OMT>-------------------------- |
|
<@ OMT>Multi-line strings. |
|
<@ LETVARLIT>a| |
|
<@ LETVARLIT>string|This is a multiline string |
|
<@ OMT>-------------------------- |
Past (20 years or so) and present code. A variety of languages and platforms. Some gems. More gravel. Some useful stuff and some examples of how not to do it.
Showing posts with label Protium. Show all posts
Showing posts with label Protium. Show all posts
Saturday, December 12, 2009
[Protium] PLEAC 1.0
[Protium] PLEAC in Protium
PLEAC, for those unfamiliar with it, is the Programming Language Examples Alike Cookbook. This is a brilliant site which takes examples of Perl, given in Perl Cookbook by Christiansen and Torkington, and invites contributors to demonstrate how other languages implement the same functionality. Many languages are in the process of being compared and contrasted in this way, including Python, Ruby, Tcl and Haskell. All manner of functionality is covered, from Strings, Numbers, Dates and Times through to Internet Services, CGI Programming and Web Automation.
For the next few postings I am going to do a PLEAC for Protium. You won't find Protium on PLEAC's pages because PLEAC is limited to open-source languages. Protium is proprietary and closed-source (at present.)
The challenge with converting from Perl to Protium is similar to that faced by linguists translating from one human language to another: do you translate the sense of the utterance, or do you just translate word for word. For example, the Tok Pisin word rabisman literally means "rubbish man". However, it is almost never used that way. Instead it often carries the sense of "fool" or "good-for-nothing." So when converting the Perl to Protium, I've tried to give the sense of the Perl, rather than follow it line for line or word for word.
There will be the odd non-PLEAC posting, but I will try to work my way through the entire PLEAC, all 300K's worth.
For the next few postings I am going to do a PLEAC for Protium. You won't find Protium on PLEAC's pages because PLEAC is limited to open-source languages. Protium is proprietary and closed-source (at present.)
The challenge with converting from Perl to Protium is similar to that faced by linguists translating from one human language to another: do you translate the sense of the utterance, or do you just translate word for word. For example, the Tok Pisin word rabisman literally means "rubbish man". However, it is almost never used that way. Instead it often carries the sense of "fool" or "good-for-nothing." So when converting the Perl to Protium, I've tried to give the sense of the Perl, rather than follow it line for line or word for word.
There will be the odd non-PLEAC posting, but I will try to work my way through the entire PLEAC, all 300K's worth.
Tuesday, January 08, 2008
[Protium] Master Class #1 (Part 2)
Demonstration - Oblique Strategies
"The Oblique Strategies are a deck of cards. Up until 1996, they were quite easy to describe. They measured about 2-3/4" x 3-3/4". They came in a small black box which said "OBLIQUE STRATEGIES" on one of the top's long sides and "BRIAN ENO/PETER SCHMIDT" on the other side. The cards were solid black on one side, and had the aphorisms printed in a 10-point sans serif face on the other.Oblique StrategiesA web-based installation of Oblique Strategies is supplied in the standard Protium install. Using the "Internet Information Services" snap-in, create a virtual directory pointing to C:\protium\Code\prx\os. Specify its default as index.prx, call it 'os', and share the C:\protium\Code\prx\os directory (Microsoft Access is picky about being able to write to databases even when only reading.)
...
The deck itself had its origins in the discovery by Brian Eno that both he and his friend Peter Schmidt ... tended to keep a set of basic working principles which guided them through the kinds of moments of pressure — either working through a heavy painting session or watching the clock tick while you're running up a big buck studio bill. Both Schmidt and Eno realized that the pressures of time tended to steer them away from the ways of thinking they found most productive when the pressure was off. The Strategies were, then, a way to remind themselves of those habits of thinking — to jog the mind."
--
Further information on setting up IIS can be found in the Protium document "C:\protium\bin\plugins\Configuring Windows IIS 5 to use with Protium and Isis.html"
The Protium code in the index.prx file is as follows: The above code (indented only to more clearly demonstrate document structure) outputs a different strategy each time the page is refreshed. The syllables translate as follows:
| <@ DEFKEYLIT>__Transput|__HTMLTransput</@> | define the Transput as HTML |
| <@ SAYPRO>@> | output a document prologue. (What is output by the PRO syllable depends on the Transput defined, as is the case for all document related syllables.) |
| <@ SAYDOC>@> | Enclose a document. |
| <@ SAYDHD>@> | Enclose a document header, in the context of an existing document. |
| <@ SAYDTT>Oblique strategies</@> | set the document title, in the context of an existing document body and header. |
| <@ SAYDBD></@> | enclose a document body, in the context of an existing document. |
| <@ DEFDBFLIT>os</@> | opens this data source, by default a JET/MSAccess database. |
| <@ DEFRSTCAP>select * from os where cardid = <@ SAYRANLIT>100</@></@> | Open record source defined by captured output. |
| <@ SAYRANLIT>100</@> | return a random number between 1 and 100. |
| <@ SAYDPR></@> | enclose a document paragraph, in the context of the existing document. |
| <@ SAYFLD>message</@> | print the contents of the field called 'message' which, in this context, is part of the 'os' recordset. |
The changed syllables translate as follows:
| <@ DEFRSTLIT>os</@> | Select every record in the database. |
| <@ LETVARSZERST>upper|___</@> | assign to the variable 'upper' the size of the default (marked by three underscores) recordset. |
| <@ RSTCAP>select * from os where cardid = <@ SAYRANVAR>upper</@></@> | Select a new recordset, capturing the output from RAN but using the variable 'upper' to specify the limit. |
| <@ ACTMOVRANRST></@> | move the record pointer to a random place in the recordset. |
Questions and Answers
I can't see a main() anywhere. Where's the start?Protium implements a single-pass code evaluation model. This is quite unlike most other languages which implement double-pass code evaluation: first pass to discover and make a map; second pass to evaluate.
Protium starts at the beginning of a named file, and builds its awareness of context from there. Because of this approach, we may never examine code we aren't interested in.
I keep using the same construction over and over again. Is there a way of abbreviating Protium words?
What you can do is create a compound operator (a concept borrowed from OPS-3). These are defined using the KOP syllable. If you wanted to define LVK as a shorthand for LETVARKEY, for example, then you would code
Thereafter you would be able to use the abbreviated form, replacing code like with
There are other ways of doing this, including UDS (user-defined syllable) and BLK (code block), but this is by far the simplest.
© Copyright Bruce M. Axtens, 2008
Monday, January 07, 2008
[Protium] Master Class #1 (Part 1)
Protium is ...
Protium is essentially, and at heart, a way of finding data in a myriad of locations in a homologous manner, manipulating it in a myriad of ways, and then delivering it to a myriad of displays, in a myriad of [human] languages. A concomitant of that is that data be current, so this also involves updating old data, which means that a similar potential is there for making changes to data.But the overriding maxim is for a direct equivalence of task to operator at the conceptual level. This means that high-level / low-level language distinctions don't enter in: branching is a single operator, but so is "work out the utility matrix for this complex set of possibilities"; the iteration syllable is at the same level as that of add and of unique-sort.
Influences
"I had as a goal the economy and power ofAPL (minus the cryptic nature) while having the manipulation power of SNOBOL, the one-for-one power of multimedia-instruction-set assembler (e.g. QUEXAL), the task oriented nature of NODAL, the reality representation characteristics of ATLAS, and the data ordering capabilities of the 'lost languages' (Simscript, Dectab, dBase etc.), [such that] the data is available in a way that ordinary programming languages don't permit.
"The other thing I took from NODAL was JOSS's implicit mixing of code and data, which is much saner than LISP's, and also the way that there was an implicit hierachy of data.
"I also borrowed some control structures from RPG, temporary constructions from Miranda, generators from Icon, multiple outcomes from COMIT and compound operators from OPS-3.
"I rejected the naive form of IO (which bedevilled Algol and Fortran). I think the ability to display is the least-used functionality of programming, only touched on in screenwiping and SOAP.
"The idea of assignment [in most programming languages] is generally also naive - for instance the fact that it is a function has been overblown in functional languages, but ignored elsewhere. So [I implemented] scaling and multiple returns (present in LYaPAS in 1964), multiple assigns (common in FORTRAN, APL and the original BASIC), multiple functional transforms (common in any DSP language, e.g. Faust) as well as the closer knitting of data and code (from FORTRAN and dBase).
"The final point to note is that the entirety of Protium works with a SNOBOL-/COMIT-style success/failure flag, converted to a success / failure / don't-know ternary system. Any operation will set this, but it can be qualified (success, found, quantity more than zero, test type, pattern match, etc.)
"Essentially, the idea was to revisit the nature of the programming task, and learn from where the bounds had been stretched; to try to get a thought-to-line-of-code transference capability, rather than the reductive, ALGOL-ish, 'see-how-small-I-can-get-the-core' approach."
-- Diarmuid Pigott, personal correspondence, 9 January 2007.
How to Program in Protium
The overall Protium approach to programming is to work out what you want to do, then work out what it is that that would be in Protium terms. Sometimes this is very similar to the conventional way (most of the code examples are conventional in that way to secure familiarity). Sometimes it involves a simple task that is unfamiliar in those terms.Unlike most other programming languages, Protium does not force the programmer to work in either a top-down / decompositional or bottom-up / compositional way. Either approach can be taken. The art of Protium is in the discovery of the idiomatic form which best describes the solution to the problem.
Workflow in Protium programming is simply this: work out what data you need to solve a problem, then extract it and present it. When there is need to extract data according to a criterion, it is specified in two stages, first the data source, then the record source, in the following hierarchy: Data Source -> Record Source -> Record -> Field -> Subfield. Any number of Data Sources can be open at one time, and any number of Record Sources, but a Record Source will always be subordinate to its Data Source.
Protium supports a number of ways of addressing and participating in memory. Memory is untyped. It is a simple tuple of name => value (read name implies value) which can be late-bind typed using 'typifiers', but is inherently capable of any interpretation. There is one global memory space, but it is lexically divided (using namespaces) to make the equivalents of local, static etc. Memory is synthetic, in that it will create a variable (or a structure) on being first called — variables do not need to be declared nor the type of their content specified.
Protium relies heavily on the concept of aliases: when any complex computational task is invoked the operation is aliased, so that you can switch back to it at any time. Anything can be aliased: branching, looping, switching, creation and use of structures, and interaction with data. These aliases, also known as workareas, have two components: a type and a name.
Alias names can be invoked internally, so a field called 'ChinaCollection => DateOfPurchase' will automatically invoke the aliased workspace called ChinaCollection to fulfil the data request. This means that some very powerful manipulations are possible - such as the much-used scatter/gather (borrowed from FoxPro) to swap data between aliased workspaces.
Implicit in all of this is the idea that, where possible, everything should be invokable with one operator, so DCT (dictionary) without a name is the dictionary currently in scope, and of course implicit in the entire thing is a hierarchy of context - the field is always (unless specified) invoked in the context of the current record or the current recordset (or query or view) of the current database. It is this dependence on context - Protium's context-aware, rather than context-free, grammar - which trips up the beginning Protium programmer. That and the lack of appropriate casting of numerics - all comparisons in Protium are lexical (i.e. 'a' is less than 'c'; 5 is greater than 45000), so comparison syllables must bear an explicit number-cast syllable when a numeric comparison is required.
Conventions
Protium respects the following naming conventions with respect to the file type:| Extension | Meaning |
| .p | a Protium script in plain text format |
| .pr | a Protium script in rich text format (RTF) |
| .pre | a ProtiumWeb script (plain text, HTML or rich text) |
| .prx | a Protium executable project (plain text, HTML or rich text) |
| .plb | a Protium library (plain text, HTML or rich text) |
Generally we make two files per website, a default.prx and an index.prx, but of course it could be set up to look for an index.pre, if necessary.
© Copyright Bruce M. Axtens, 2008
Labels:
Diarmuid J Pigott,
Protium
Tuesday, October 23, 2007
[Protium] Splitting
Here's a short script for splitting a file. The file in this case is the perl language data file from the PLEAC website. pleac_perl.data contains sections marked with "# ^^PLEAC^^_" followed by a number. The section applies until the next section is marked. The script splits each section out of pleac_perl.data into pleac_perl_number.p. I'm working through these files and re-expressing the intent of the perl code in Protium.
The code may be described as follows:
© Copyright Bruce M. Axtens, 2007
The code may be described as follows:
- Define a work area, or alias, for the data file, calling it 'pleac'.
- Open the text file within that work area, using define-file-lit.
- Start a loop which iterates through an enumeration of the lines of data in the work area.
- Let a variable contain the data in the current line of the work area.
- Test whether the regular expression works for the current line.
- If it does work, let a variable contain the number found, ...
- ... turn off any output redirection, ...
- ... and redirect output to the file 'pleac_perl_' + the number found (in the same directory as the script).
- End of the if.
- Output the contents of the line.
- End of the iteration.
© Copyright Bruce M. Axtens, 2007
Saturday, September 08, 2007
[Protium] 'Assert' as a User-Defined Syllable (UDS)
From time to time, during development, it helps to have an assert. That is, a means of checking whether you got the answer you were expecting, but without having to write lots of repetitive code in the process. To that end, therefore, I've come up with a UDS, an user defined syllable, which implements the concept (and demonstrates other Protium functionality as well.)
For the sake of clarity, I've put each syllable, or "opcode", in title case. This is not something that must be done; Protium cares not what case or mix of cases the instructions are in.A UDS is 'defined', thus the DEF at the beginning. An UDS has 3 parameters: the syllable itself, then the kind of UDS (more about that later), and then the Protium code which is processed each time the syllable is used. In this case, the syllable is ASR, the type is '__Transformer' and the code starts with <@ SAO> (more about SAO later, too).
Parameters may be passed to UDSes, and retrieved using PAR. In this case, the variable lhs is given the value of the first parameter, and the variable rhs the value of the second.
Next comes the test which forms the basis of an assert: does what is contained in lhs equal what is contained in rhs? The fourth line's opcodes implement this test: if not exact-match variable variable literal, with the arguments lhs, rhs and then another Protium instruction which is only evaluated if the test for exact-match fails.
If lhs does not match rhs, an EKM (Expand Macro Key And Memory) of the literal string "Assertion error: '&lhs;' <> '&rhs;'" is performed. lhs and rhs are bracketed by ampersand and comma, with the result that these symbols are replaced with the values of the variables themselves. The result is stored in the RES (the result) of the UDS, which is handed back to the calling code. Next comes a block wrapped in IGN. This is an artefact from the development of ASR. Code inside an IGN is ignored, that is, not executed. IGNs are predominantly used for documentation but can just as easily be used to isolate parts of the code.Here are two invocations of the ASR syllable. The first generates nothing because the actioned RMD, the reverse-mid, actually does convert "Once a jolly swagman camped by a billabong" into "Once a jolly squatter camped by a billabong". The second invocation gives the error message because there's no way that that reverse-mid is going to be able to produce "all your base are belong to us".
Now SAO, aside from being the name of an Arnott's biscuit, also stands for "Suppress All Output". Usually text outside the <@> and </@> of a Protium instruction is echoed to the relevant transput (read input-output device). SAO suppresses that echoing. This explains why you don't see 'lhs=' and 'rhs=' each time ASR is invoked. SAO also suppresses everything output by SAY.
Regarding __Transformer, every syllable opcode belongs to a particular group of syllables and each group has certain specific behaviours. Other groups include __Modifier, __Alternator, __Evaluator and __Locator. Read the friendly manual.
Finally, a word about testing. It was the developer's original design to separate testing from branching, and it was due to pressure from the Protium user community which forced the merging of the two into the form seen in most other programming languages. According to the original design, the test and branch code should have looked like this:Both ways of doing it work. I'm starting to come round to the idea that the original design is the better one, especially seeing that Protium supports ternary logic (true, false, unknown). More about that some other time.
This article can also be found at Isotopes of Hydrogen on the Protium Blue Forum.
© Copyright Bruce M. Axtens, 2007
For the sake of clarity, I've put each syllable, or "opcode", in title case. This is not something that must be done; Protium cares not what case or mix of cases the instructions are in.A UDS is 'defined', thus the DEF at the beginning. An UDS has 3 parameters: the syllable itself, then the kind of UDS (more about that later), and then the Protium code which is processed each time the syllable is used. In this case, the syllable is ASR, the type is '__Transformer' and the code starts with <@ SAO> (more about SAO later, too).
Parameters may be passed to UDSes, and retrieved using PAR. In this case, the variable lhs is given the value of the first parameter, and the variable rhs the value of the second.
Next comes the test which forms the basis of an assert: does what is contained in lhs equal what is contained in rhs? The fourth line's opcodes implement this test: if not exact-match variable variable literal, with the arguments lhs, rhs and then another Protium instruction which is only evaluated if the test for exact-match fails.
If lhs does not match rhs, an EKM (Expand Macro Key And Memory) of the literal string "Assertion error: '&lhs;' <> '&rhs;'" is performed. lhs and rhs are bracketed by ampersand and comma, with the result that these symbols are replaced with the values of the variables themselves. The result is stored in the RES (the result) of the UDS, which is handed back to the calling code. Next comes a block wrapped in IGN. This is an artefact from the development of ASR. Code inside an IGN is ignored, that is, not executed. IGNs are predominantly used for documentation but can just as easily be used to isolate parts of the code.Here are two invocations of the ASR syllable. The first generates nothing because the actioned RMD, the reverse-mid, actually does convert "Once a jolly swagman camped by a billabong" into "Once a jolly squatter camped by a billabong". The second invocation gives the error message because there's no way that that reverse-mid is going to be able to produce "all your base are belong to us".
Now SAO, aside from being the name of an Arnott's biscuit, also stands for "Suppress All Output". Usually text outside the <@> and </@> of a Protium instruction is echoed to the relevant transput (read input-output device). SAO suppresses that echoing. This explains why you don't see 'lhs=' and 'rhs=' each time ASR is invoked. SAO also suppresses everything output by SAY.
Regarding __Transformer, every syllable opcode belongs to a particular group of syllables and each group has certain specific behaviours. Other groups include __Modifier, __Alternator, __Evaluator and __Locator. Read the friendly manual.
Finally, a word about testing. It was the developer's original design to separate testing from branching, and it was due to pressure from the Protium user community which forced the merging of the two into the form seen in most other programming languages. According to the original design, the test and branch code should have looked like this:Both ways of doing it work. I'm starting to come round to the idea that the original design is the better one, especially seeing that Protium supports ternary logic (true, false, unknown). More about that some other time.
This article can also be found at Isotopes of Hydrogen on the Protium Blue Forum.
© Copyright Bruce M. Axtens, 2007
Friday, August 31, 2007
[Protium] Templating
Finally, after much talk, here's some action on the Protium front. This the first posting in the 'Isotopes of Hydrogen' series, on the subject of Templating. IoH is housed at the Protium Blue Forum.
If you don't want to go through the process of forum registration, the article is reproduced below.
We're implementing a SOAP interface to Google's AdWords. There are a number of services and subroutines. The following code was developed to speed up the implementation by taking the service and subroutines names and turning them into VB6 subs. First there's the definition of template. Note that some parts of the template are Visual BASIC and some are something else: an ampersand, a word and a semicolon. These will be replaced with the text in the following list.params contains, as a first item, the name of the service. After it are all the routines germane to that service. I got these by copying and pasting from Google's AdWords API website.This bit takes the variable params, and converts it to a list, splitting on newlines. CND means 'construct delimited'. The list is called L (really original, I know.)Next we iterate by enumeration of the L list. Here we see one of the special qualifiers that can be used with iteration, INI, that only fires on the first pass through the iteration and is ignored otherwise. In this case, its 'payload' is to define a macro where Service contains the current (in this case, the first) element of the L list.
ONG means 'ongoing' and fires on the second and subsequent iterations. The payload is in two parts. The first is to define another macro, Function, with the value of the current element of L. The second is to evaluate template, using EKM, substituting &Service; and &Function; with the values stored in the Service and Function macros.
By using INI, Service gets set only once. ONG ensures that Function will never contain the name of the service, and always contain the current name of the function.
An abbreviated sample of the output is below. There are 11 services and over 40 subs in total. Granted, there's still quite a bit of work to make these subs useful, but a lot of the hack work has been done by the computer, which is what it's there for. © Copyright Bruce M. Axtens, 2007
If you don't want to go through the process of forum registration, the article is reproduced below.
We're implementing a SOAP interface to Google's AdWords. There are a number of services and subroutines. The following code was developed to speed up the implementation by taking the service and subroutines names and turning them into VB6 subs. First there's the definition of template. Note that some parts of the template are Visual BASIC and some are something else: an ampersand, a word and a semicolon. These will be replaced with the text in the following list.params contains, as a first item, the name of the service. After it are all the routines germane to that service. I got these by copying and pasting from Google's AdWords API website.This bit takes the variable params, and converts it to a list, splitting on newlines. CND means 'construct delimited'. The list is called L (really original, I know.)Next we iterate by enumeration of the L list. Here we see one of the special qualifiers that can be used with iteration, INI, that only fires on the first pass through the iteration and is ignored otherwise. In this case, its 'payload' is to define a macro where Service contains the current (in this case, the first) element of the L list.
ONG means 'ongoing' and fires on the second and subsequent iterations. The payload is in two parts. The first is to define another macro, Function, with the value of the current element of L. The second is to evaluate template, using EKM, substituting &Service; and &Function; with the values stored in the Service and Function macros.
By using INI, Service gets set only once. ONG ensures that Function will never contain the name of the service, and always contain the current name of the function.
An abbreviated sample of the output is below. There are 11 services and over 40 subs in total. Granted, there's still quite a bit of work to make these subs useful, but a lot of the hack work has been done by the computer, which is what it's there for. © Copyright Bruce M. Axtens, 2007
Subscribe to:
Posts (Atom)