How do you use #call directive for Red function with string datatypes as parameters? - red

Given a script, such as below, which does not compile yet, how can I use #call to use my Red function from within Red/System?
Red []
pff: function [a [string!] ][print a]
#system [
#call [pff "hello"]
]
There is a type mismatch. What do you need to do to convert the string to the proper Red/System datatype?

To expand on Peter's correct answer, in this particular case, you need to internalize the c-string as a red-string!, using string/load, like this:
Red []
pff: function [a [string!] ][print a]
#system [
s: "hello"
hello: string/load s 1 + length? s UTF-8
#call [pff hello]
]
Notes:
Red/System's strings are ASCII only for now, so you need to specify UTF-8 as the source encoding format.
You need to pass the size of the c-string accounting for the terminal NUL (hence the + 1).
The internal API is not documented as it is not finalized. Feel free to ask here or on our other communication channels if you need any info about it.

You need to make calls to the Red runtime API to perform the transformation. The Red runtime API isn't documented yet so you either have to read the code or ask one of the few people who are familiar with it. (I did a little of both).
I wrote a function to convert a Red string! to a UTF-8 encoded Red/System c-string!, it's on github.

Related

How to print unicode to console in Eiffel?

Evidently in python:
print u'\u0420\u043e\u0441\u0441\u0438\u044f'
outputs:
Россия
How do I do this in Eiffel?
An example at the first page of eiffel.org (at the time of writintg) suggests the following code:
io.put_string_32 ("[
Hello!
¡Hola!
Bonjour!
こんにちは!
Здравствуйте!
Γειά σου!
]")
It is supported since EiffelStudio 20.05. (I tested the example with EiffelStudio 22.05.)
In this particular case, using print instead of io.put_string_32 works as well. However, in some boundary cases, when all character codes in the string are below 256, you may need to specify the string type explicitly:
print ({STRING_32} "Zürich") -- All character code points are below 256.
Of course, you can write the character code points explicitly:
io.put_string_32 ("%/0x041f/%/0x0440/%/0x0438/%/0x0432/%/0x0435/%/0x0442/%/0x0021/")
The output code page defaults to UTF-8 for text files and the current console code page for CONSOLE (the standard object type of io). If needed, the default encoding can be changed to any other encoding:
io.standard_default.set_encoding ({SYSTEM_ENCODINGS}.console_encoding)
On my linux OS, this code print exactly what you want:
make
-- Initialisation of `Current'
local
l_utf_converter:UTF_CONVERTER
l_string:STRING_32
do
create l_string.make_empty
l_string.append_code (0x420)
l_string.append_code (0x43e)
l_string.append_code (0x441)
l_string.append_code (0x441)
l_string.append_code (0x438)
l_string.append_code (0x44f)
print(l_utf_converter.utf_32_string_to_utf_8_string_8 (l_string))
end
In a nutshell, STRING_32 use UTF-32 and the linux console use UTF-8. The UTF_CONVERTER class can be use to convert UTF-32 to UTF-8.
I do not know if it is possible on a Windows console.

TYPO3 8.7 multiple arguments in locallang translations

I recently found that one can pass arguments to translations either in fluid
<f:translate key="something.test" arguments="{0: 'something'}" />
or in PHP
\TYPO3\CMS\Extbase\Utility\LocalizationUtility::translate('something.test', $extKey, $arguments);
And with the latter I realized that I do not understand how exactly this works and I couldn't find the documentation for these arguments. And I got stuck trying to pass multiple arguments.
The translation with the argument looks something like the following:
<trans-unit id="something.test">
<source>this is the argument: %1$s</source>
</trans-unit>
What I do not understand is why has the placeholder the following format: %1$s?
Does the number "1" have to do anything with the index of the arguments? If yes, why does it start with 1 if I pass the argument with key 0?
I understood that it's possible to pass multiple arguments by passing an array, but I don't know how to put correct placeholders at the corresponding places.
What I want to do is the following:
Controller:
$arguments = array('something1', 'something2', 'something3');
\TYPO3\CMS\Extbase\Utility\LocalizationUtility::translate('something.test', $extKey, $arguments);
locallang.xlf:
<trans-unit id="something.test">
<source>Test: [placeholder for something1] [placeholder for something2] [placeholder for something3]</source>
</trans-unit>
Could someone explain to me how this works? Thanks beforehand :-)
What you see in your format string (%1$s) is what's called argument swapping (see examples 1-4 for a thorough understanding).
You'd use it if the order of your placeholders is different from the order of the arguments. An example:
You have the string
$str = "%s had a %s %s";
and the array
$args = [
'Mary',
'little',
'lamb',
];
And your formatting result would be "Mary had a little lamb". But what would happen if the arguments were in a different order, like this:
$args = [
'lamb',
'Mary',
'little',
];
Then you would get "lamb had a Mary little". By using argument swapping (confusing name, I know), you tell the formatter where exactly to look for a given argument. These placeholders are configured position-wise not index-wise, so they start from 1, not from 0.
So to get the correct output for the above mentioned, unordered arguments, you would need the format string to be:
$str = "%2$s had a %3$s %1$s";
Note that argument swapping makes sense if, and only if you can guarantee that the order of the arguments in your array will always be the same. Also, if you can't control the order of the arguments (but can guarantee it will be the same), you would most likely need to use it, too.
As noted by Bernd Wilke πφ, argument swapping is very helpful when dealing with localization, such as in your case.
Different languages have different linguistic typologies, that is, where e.g. subject, verb and object are placed in a sentence or even how a date is written.
The standard English date format is, for example, month-day-year. In Germany, it is formatted as day.month.year and the Japanese format it as year-month-date. Now, when you get your argument array from wherever, containing the values for year, month and day, in this order
$arguments = [
"2019",
"03",
"20",
];
you would not get around using argument swapping to place the elements in the correct order.
In English, your format string would be %2$s-%3$s-%1$s, for German %3$.%2$.%1$ and for Japanese either %1$s-%2$s-%3$s or even %s-%s-%s (as coincidentally, the arguments are already in the correct order, but to avoid confusion and stay consistent, you should use the positional formatting as with the other languages).
When you can control the argument order, it is usually easier to use a non-positional formatstring, but as explained above, this does not work well for localization, if at all.

What am I allowed to name a function in Powershell?

PS > function ]{1}
PS > ]
1
PS >
PS
Why does this work?
What else can I name a function? All I've found so far that works is * and ].
You can name it almost anything. You can even include newlines and emoji* in the name.
function Weird`nFunctionの名前😀 { Write-Host hey }
$c = gcm Weird*
$c.Name
& $c
Escaping helps with lots of things like that:
function `{ { Write-Host cool }
`{
function `0 { Write-Host null }
gci function:\?
I'll add that this is true for variables too, and there's a syntax that removes the need to do most escaping in the variable name: ${varname} (as opposed to $varname).
With that, you could easily do:
${My variable has a first name,
it's
V
A
something
R,
whatever I dunno
🤷} = Get-Process
You'll note that if you then start typing like $MyTAB it will tab complete in a usable way.
To (somewhat) answer why this should work, consider that the variable names themselves are just stored in .Net strings. With that in mind, why should there be a limit on the name?
There will be limits on how some of these names can be used in certain contexts, because the parser will not understand what to do with it if the names don't have certain characters escaped, but literal parsing of PowerShell scripts are not the only way to use functions or variables or other language constructs, as I've shown some examples of.
Being less limiting also means being able to support other languages and cultures by having wide support for character sets.
To this end, here's one more thing that might surprise you: there are many different characters to represent the same or similar things that we take for granted in code, like quotation marks for example.
Some (human) languages or cultures just don't use the same quote characters we do in English, don't even have them on the keyboard. How annoying would it be to type code if you have to keep switching your keyboard layout or use ALT codes to quote strings?
So what I'm getting at here is that PowerShell actually does support many quote characters, for instance, what do you think this might do:
'Hello’
Pretty obvious it's not the "right" set of quotes on the right side. But surprisingly, this works just fine, even though they aren't the same character.
This does have important implications if you're ever generating code from user input and want to avoid sneaky injection attacks.
Imaging you did something like this:
Invoke-Expression "echo '$($userMsg -replace "'","''")'"
Looks like you took care of business, but now imagine if $userMsg contained this:
Hi’; gci c: -recurse|ri -force -whatif;'
For what it's worth, the CodeGeneration class is aware of this stuff ;)
Invoke-Expression "echo '$([System.Management.Automation.Language.CodeGeneration]::EscapeSingleQuotedStringContent($userMsg))'"
* PowerShell Console doesn't have good support for Unicode, even though the language does. Use ISE to better see the characters.

How do I write a perl6 macro to enquote text?

I'm looking to create a macro in P6 which converts its argument to a string.
Here's my macro:
macro tfilter($expr) {
quasi {
my $str = Q ({{{$expr}}});
filter-sub $str;
};
}
And here is how I call it:
my #some = tfilter(age < 50);
However, when I run the program, I obtain the error:
Unable to parse expression in quote words; couldn't find final '>'
How do I fix this?
Your use case, converting some code to a string via a macro, is very reasonable. There isn't an established API for this yet (even in my head), although I have come across and thought about the same use case. It would be nice in cases such as:
assert a ** 2 + b ** 2 == c ** 2;
This assert statement macro could evaluate its expression, and if it fails, it could print it out. Printing it out requires stringifying it. (In fact, in this case, having file-and-line information would be a nice touch also.)
(Edit: 007 is a language laboratory to flesh out macros in Perl 6.)
Right now in 007 if you stringify a Q object (an AST), you get a condensed object representation of the AST itself, not the code it represents:
$ bin/007 -e='say(~quasi { 2 + 2 })'
Q::Infix::Addition {
identifier: Q::Identifier "infix:+",
lhs: Q::Literal::Int 2,
rhs: Q::Literal::Int 2
}
This is potentially more meaningful and immediate than outputting source code. Consider also the fact that it's possible to build ASTs that were never source code in the first place. (And people are expected to do this. And to mix such "synthetic Qtrees" with natural ones from programs.)
So maybe what we're looking at is a property on Q nodes called .source or something. Then we'd be able to do this:
$ bin/007 -e='say((quasi { 2 + 2 }).source)'
2 + 2
(Note: doesn't work yet.)
It's an interesting question what .source ought to output for synthetic Qtrees. Should it throw an exception? Or just output <black box source>? Or do a best-effort attempt to turn itself into stringified source?
Coming back to your original code, this line fascinates me:
my $str = Q ({{{$expr}}});
It's actually a really cogent attempt to express what you want to do (turn an AST into its string representation). But I doubt it'll ever work as-is. In the end, it's still kind of based on a source-code-as-strings kind of thinking à la C. The fundamental issue with it is that the place where you put your {{{$expr}}} (inside of a string quote environment) is not a place where an expression AST is able to go. From an AST node type perspective, it doesn't typecheck because expressions are not a subtype of quote environments.
Hope that helps!
(PS: Taking a step back, I think you're doing yourself a disservice by making filter-sub accept a string argument. What will you do with the string inside of this function? Parse it for information? In that case you'd be better off analyzing the AST, not the string.)
(PPS: Moritz++ on #perl6 points out that there's an unrelated syntax error in age < 50 that needs to be addressed. Perl 6 is picky about things being defined before they are used; macros do not change this equation much. Therefore, the Perl 6 parser is going to assume that age is a function you haven't declared yet. Then it's going to consider the < an opening quote character. Eventually it'll be disappointed that there's no >. Again, macros don't rescue you from needing to declare your variables up-front. (Though see #159 for further discussion.))

What is the meaning of ${} in powershell?

I have a script where function parameters are expressed like this:
param(
${param1},
${param2},
${param3}
)
What does it mean? I have been unable to find documentation on this.
What's the point of writing parameters that way instead of the more usual
param(
$param1,
$param2,
$param3
)
?
#MikeZ's answer is quite correct in explaining the example in the question, but as far as addressing the question title, there is actually more to say! The ${} notation actually has two uses; the second one is a hidden gem of PowerShell:
That is, you can use this bracket notation to do file I/O operations if you provide a drive-qualified path, as defined in the MSDN page Provider Paths.
(The above image comes from the Complete Guide to PowerShell Punctuation, a one-page wallchart freely available for download, attached to my recent article at Simple-Talk.com.)
They are both just parameter declarations. The two snippets are equivalent. Either syntax can be used here, however the braced form allows characters that would not otherwise be legal in variable names. From the PowerShell 3.0 language specification:
There are two ways of writing a variable name: A braced variable name, which begins with $, followed by a curly bracket-delimited set of one or more almost-arbitrary characters; and an ordinary variable name, which also begins with $, followed by a set of one or more characters from a more restrictive set than a braced variable name allows. Every ordinary variable name can be expressed using a corresponding braced variable name.
From about_Variables
To create or display a variable name that includes spaces or special characters, enclose the variable name in braces. This directs Windows PowerShell to interpret the characters in the variable name literally.
For example, the following command creates and then displays a variable named "save-items".
C:\PS> ${save-items} = "a", "b", "c"
C:\PS> ${save-items}
a
b
c
They are equivalent. It's just an alternative way of declaring a variable.
If you have characters that are illegal in a normal variable, you'd use the braces (think of it as "escaping" the variablename).
There is one additional usage.
One may have variable names like var1, var2, var11, var12, var101, etc.
Regardless if this is desirable variable naming, it just may be.
Using brackets one can precisely determine what is to be used:
assignment of $var11 may be ambiguous, using ${var1}1 or ${var11} leaves no room for mistakes.