Perl6 - What is the $: for in some subroutine Signatures - signature

I came across this error message in another question and I would like to know what is the meaning of the $: part of the signature, please?
Cannot resolve caller index(Str: Str, Any); none of these signatures match:
(Str:D $: Cool:D $needle, *%_)
(Str:D $: Str:D $needle, *%_)
(Str:D $: Cool:D $needle, Cool:D $pos, *%_)
(Str:D $: Str:D $needle, Int:D $pos, *%_)

The $: is two distinct unrelated tokens, a $ and a :, that have been smooshed together.
The $ represents a single item1 aka a scalar2.
The single item / scalar hasn't been given a name, so there's no way to reference it. And there's already enough of a parameter (the Str:D) to let you and the compiler know that this parameter is a scalar (a single string). Either way, the $ is redundant and Elizabeth has made a related change.
The : is a special parameter separator. (The usual parameter separator is a comma ,.)
It may only be used immediately after the first parameter of a method or standalone signature. It may not be used in the signature of a routine that is not a method.
If used as a parameter separator after the first parameter in a signature, it marks that parameter as corresponding to a method's "invocant".
(If not used, the invocant parameter is implicit.)
The corresponding invocant argument will arrive anyway, and be aliased to self, whether or not the signature explicitly lists an invocant parameter. But if the invocant parameter is explicitly specified, it's possible to give it an additional/alternate name and/or explicitly constrain its type.
Crazy over-the-top footnotes for added entertainment. If they confuse you, just forget you ever read them.
1 A single item refers to data that is naturally a single thing, like the number 42, OR data that is naturally a composite thing (like an array) that is being treated like it's a single thing (like an array). (Did you see what I did there?) I like to point out the mnemonic that a $ symbol is like an S (for single) overlaid with an I (for item), or vice-versa. To me this represents the idea of emphasizing the single item nature of any data, hiding any plural aspect even if it's actually an array or other composite data item.
2 "scalar" is a traditional computing term. Wikipedia's Scalar disambiguation page lists "Variable (computing), or scalar, an atomic quantity that can hold only one value at a time" as a definition. Also, a single item aka scalar (all lowercase) is often/usually a Scalar (uppercase S), a special case of a single item that's a Single Item container that contains a Single Item (which can be composite data being treated as a single thing).

The : mark the first argument as an invocant.
my $word = "bananarama";
say $word.index( "r", 0 );
In this case, it indicates the invocant is going to be treated as an scalar, since it's constrained by a single $

Related

squeak(smalltalk) how to use method `findSubstring: in: startingAt: matchTable:`?

what I should send for matchTable: selector?
in the implementation, there are no examples or detailed explanation so
I don't understand which object is getting the message if I put the string in in: selector
The matchTable: keyword provides a way to identify characters so that they become equivalent in comparisons. The argument is usually a ByteArray of 256 entries, containing at position i the code point of the ith character to be considered when comparing.
The main use of the table is to implement case-insensitive searches, where, e.g., A=a. Thus, instead of comparing the characters at hand during the search, what are compared are the elements found in the matchTable at their respective code points. So, instead of
(string1 at: i) = (string2 at: j)
the testing becomes something on the lines of
cp1 := string1 basicAt: i.
cp2 := string2 basicAt: j.
(table at: cp1) = (table at: cp2).
In other words, the matchTable: argument is used to map actual characters to the ones that actually matter for the comparisons.
Note that the same technique can be applied for case-sensitive/insensitive sorting.
Finally, bear in mind that this is a rather low-level method that non-system programmers would rarely need. You should be using instead higher level versions for finding substrings such as findString:startingAt:caseSensitive:, where the argument of the last keyword is a Boolean.

How to get fields of a Julia object

Given a Julia object of composite type, how can one determine its fields?
I know one solution if you're working in the REPL: First you figure out the type of the object via a call to typeof, then enter help mode (?), and then look up the type. Is there a more programmatic way to achieve the same thing?
For v0.7+
Use fieldnames(x), where x is a DataType. For example, use fieldnames(Date), instead of fieldnames(today()), or else use fieldnames(typeof(today())).
This returns Vector{Symbol} listing the field names in order.
If a field name is myfield, then to retrieve the values in that field use either getfield(x, :myfield), or the shortcut syntax x.myfield.
Another useful and related function to play around with is dump(x).
Before v0.7
Use fieldnames(x), where x is either an instance of the composite type you are interested in, or else a DataType. That is, fieldnames(today()) and fieldnames(Date) are equally valid and have the same output.
suppose the object is obj,
you can get all the information of its fields with following code snippet:
T = typeof(obj)
for (name, typ) in zip(fieldnames(T), T.types)
println("type of the fieldname $name is $typ")
end
Here, fieldnames(T) returns the vector of field names and T.types returns the corresponding vector of type of the fields.

Makefile macro modifier

I am totally confused about the following macro modifier in a Makefile I have come onto,
TOOLS = $(TOOL_ROOTS:%=$(OBJDIR)%$(TOOL_SUFFIX))
Here
TOOL_ROOTS=some filename prefixes
OBJDIR=$HOME/obj/
TOOL_SUFFIX=.so
Can someone tell me what this line actually means?
TOOL_ROOTS must be getting assigned some value other than the empty string at some point or that does nothing (which I'll show in a moment).
So first things first just expanding the variables takes us from:
TOOLS = $(TOOL_ROOTS:%=$(OBJDIR)%$(TOOL_SUFFIX))
to:
TOOLS = $(:%=~/obj%.so)
(which we can immediately see doesn't look right, and as I'll explain in a moment doesn't do anything)
So lets pretend it has a value instead.
TOOL_ROOTS = shovel axe hammer
And try the expansion again:
TOOLS = $(shovel axe hammer:%=~/obj%.so)
(That OBJDIR definition looks odd also. I would expect it to be ~/obj/ or something... and that's ignoring that ~ is a bad choice here and that $HOME would be much better.)
The next thing we need to know is what that syntax is all about. Well it is a Substitution Reference.
A substitution reference substitutes the value of a variable with alterations that you specify. It has the form ‘$(var:a=b)’ (or ‘${var:a=b}’) and its meaning is to take the value of the variable var, replace every a at the end of a word with b in that value, and substitute the resulting string.
When we say “at the end of a word”, we mean that a must appear either followed by whitespace or at the end of the value in order to be replaced; other occurrences of a in the value are unaltered. For example:
foo := a.o b.o c.o
bar := $(foo:.o=.c)
sets ‘bar’ to ‘a.c b.c c.c’. See Setting Variables.
A substitution reference is actually an abbreviation for use of the patsubst expansion function (see Functions for String Substitution and Analysis). We provide substitution references as well as patsubst for compatibility with other implementations of make.
Another type of substitution reference lets you use the full power of the patsubst function. It has the same form ‘$(var:a=b)’ described above, except that now a must contain a single ‘%’ character. This case is equivalent to ‘$(patsubst a,b,$(var))’. See Functions for String Substitution and Analysis, for a description of the patsubst function.
For example:
foo := a.o b.o c.o
bar := $(foo:%.o=%.c)
sets ‘bar’ to ‘a.c b.c c.c’.
So, the first % there is matching the entirety of every word in the value of the variable (here shovel axe hammer) and then replacing each value with the expansion of the second part.
So shovel becomes ~/objshovel.so, etc. and we end up with:
TOOLS = ~/objshovel.so ~/objaxe.so ~/objhammer.so
See what I meant about OBJDIR being odd before? OBJDIR=~/obj/ would have left us with this instead:
TOOLS = ~/obj/shovel.so ~/obj/axe.so ~/obj/hammer.so
which makes a lot more sense to me.

How to use IN with a block instead of an object?

The IN function in Rebol finds out if a field is in an object:
USAGE:
IN object word
DESCRIPTION:
Returns the word or block in the object's context.
IN is a native value.
ARGUMENTS:
object (any-object! block!)
word -- (modified if series) (any-word! block! paren!)
The claim is it works with objects or blocks. It works okay if I try it with an object:
>> in object [foo: 10 bar: 20] 'foo
== foo
But if I just try it with a raw block, it gives back NONE:
>> in [foo: 10 bar: 20] 'foo
== none
Guess I'd understand if it didn't support blocks (Rebol2 didn't). But what's the case in which it wouldn't return NONE that blocks are allowed for?
And at the risk of making this two questions in one, what's the deal with accepting BLOCK! for the word parameter? I'd think it would take a block if you had a set of words you were looking for, but it seems to just return the block:
>> in object [foo: 10 bar: 20] [mumble frotz bar]
== [mumble frotz bar]
>> in object [foo: 10 bar: 20] [mumble frotz]
== [mumble frotz]
And at the further risk of making this three questions, what meaning would taking a PAREN! for word have?
The IN function isn't primarily meant for searching an object for a word, it is for returning a word or block of words that are in the object, or in Rebol terms bound to the object. It's a variant of the BIND function that is useful in different circumstances than BIND.
If there is no word of that name in the object, it returns none, sensibly enough. This gives it the side benefit of being able to be used in conditional expressions as a word detection function, but that's not its main use.
IN can take a block of objects for its object parameter and then try to bind the word to each object in turn, returning a word bound to the first object in the block that has that word. This was meant as a relatively quick way to do overriding word lookup for an old design of the Rebol 3 GUI, but it turned out to not be the best approach in that case so the GUI doesn't use that design now. However, IN block word was kept as a potentially useful feature for future use elsewhere.
In your example, there were no objects in that block, so there was nothing that IN could bind the word to. That is why IN returned none.
If you pass IN a block for the word parameter, it binds the block to the object before it returns it. This is to allow code like do in obj [print a]. It doesn't do a bind/copy though, so you should be careful about code like that. Or maybe IN object block should copy - is it too late to change that? Passing a paren for the word argument should have the same binding behavior as passing a block.
When last I checked, we didn't support having both the object an word parameters be blocks. This is because we couldn't figure out a good model for what that behavior should be, at least obviously. The overriding word lookup doesn't really work with a block of words because the results would be inconclusive.
It would be useful to have a function that rebound a block to a series of objects in order, especially for recreating Rebol's not-really-nested scopes, but it would be really confusing for that function to be IN.
This might not be as useful, but since it is not explicitly mentioned, and I think is the 'right' way to solve your first question for now:
red>> first find [foo: 10 bar: 20] 'foo
== foo:
This doesn't work on rebol2 tho, but quoteing the set-word! does :
>> first find [foo: 10 bar: 20] quote [foo:]
== foo:
Still has the slight disadvantage of returning a set-word!

Simple string replacement set of rules

I have an application where users set up a bunch of objects by filling up a bunch of text boxes which represent values that these objects will take. Just like setting up a Person object which requires you to enter a Name and a LastName properties.
Now I want to introduce global variables that the user will be able to assign values to, or which's values will change during the execution of the program. And I want the user to be able to use them when filling up any object's properties. My first idea was to choose an special character that will mark the beginning of a variable name, and then let the user use the character itself twice to represent the character itself.
For instance, say I have a global variable called McThing. Then, say the symbol I choose to mark the beginning of a variable is %. The user would then be able to enter as a person's last name the string "Mc. %McThing", which then I'd replace using the value of McThing. If McThing's value is "Donalds", the last name would become "Mc. Donalds".
The problem with this is that, if I'd have a variable called He and another called Hello and the user enters "%Hello" as the string I wouldn't know which variable needs to be replaced. I could change my rules to, for instance, use the "%" symbol to mark both the beginning and the end of the variable name. But I'm not sure whether this will cause any other problem.
What would be the simplest possible set of rules to achieve this such that the user will be able to represent every possible string without ambiguities? Ideally, the variable names can have any character but I could restrict their names to a given set of characters.
Your approach of marking both beginning and end with % has one problem. What happens if the input string is %foo%%bar%? Do I get the value of foo and the value of bar? Or do I get the value of foo%bar? (Of course if % in variable names isn't allowed, this isn't a problem.)
The simplest way I can think of to avoid this problem is to use one symbol for the beginning and another (e.g. #) for the end. That should avoid any ambiguity. If the user wants a # in text or a variable name, he escapes it like so: %#. This causes no problems, since empty variable names are not a thing (at least I hope not).
It will be fine and easy to implement on the assumptions that:
You have no empty variable names (i.e. if we see a %% is that a % or an empty variable name?)
Variable names cannot contain %s (i.e. if we see a % in a variable name, is that the end or a %?)
OR
Variable names cannot start or end with % and you cannot have 2 variable names in a row
(i.e. is %a%%b% = a and b or a%b?)
These assumptions will ensure that any %% always represents a % character, and any % always represents the start or the end of the string.
These assumptions might not necessarily be required, but at the very least they will make the implementation a lot more difficult (with the above assumptions, we never have to look more than 1 character forward).
An alternative with no such restrictions, loosely based on the way C/Java/etc. does it:
Have % take on a role similar to \ in C/Java/etc. - use:
%s to denote the start of the string
%e to denote the end of the string
%% to denote the % character
You can also use the same characters to represent the start and end, but, we may as well make them different so it's easier to read.

Resources