What does the type in the formatting types syntax do? - formatting

What does the ‘type’ in the formatting types syntax of format! do?
Of this, that is:
[[fill]align][sign]['#']['0'][width]['.' precision][type]
The rest appears to be well documented, but that particular one seems to have some information left out. Under its explanation it says:
type := identifier | ''
But what on Earth is it used for?
Edits
1.
Someone suggested that they be for named parameters, and that feels reasonable to assume. However, should the following code not work had that been the case?
println!("{:.2test}", test=32.432);
This generates me a rather depressing error:
error: unknown format trait `test`
--> src\main.rs:12:29
|
12 | println!("{:.2test}", test=32.432);
| ^^^^^^

What must be noted here is that the syntax above is for format_spec, which always follows a colon.
format := '{' [ argument ] [ ':' format_spec ] '}'
format_spec := [[fill]align][sign]['#']['0'][width]['.' precision][type]
With that in mind, the type part is used to specify formatting traits, which are documented as thus:
When requesting that an argument be formatted with a particular type, you are actually requesting that an argument ascribes to a particular trait. This allows multiple actual types to be formatted via {:x} (like i8 as well as isize).
[...]
If no format is specified (as in {} or {:6}), then the format trait used is the Display trait.
Here's an example (Playground):
println!("{:b}", 31); // prints 11111
println!("{:08b}", 31); // prints 00011111
Type formatting works for any data type that implements the corresponding formatting type, such as Binary or LowerHex.
At first I guessed it would be named parameters, but those actually go before the colon. Just for the record, this also works (Playground):
format!("{a:08b}", a = 31)

Related

Confusing .fmt behavior with nested Lists

The docs say that fmt
Returns a string where each element in the list has been formatted according to $format [the first argument] and where each element is separated by $separator [the second argument].
Based on that description, I expected to be able to call .fmt on a List of Lists, and then pass a printf-style format string containing a % directive for each element in the inner list. But that doesn't work.
If you'd told me that I was wrong about ^^^^, I'd have expected that .fmt was auto-flattening its arguments and thus that each argument would be formatted and separated by the $separator. But that's also not what happens.
Instead, running this code
say (<a b c>, <1 2 3>, <X Y Z>).fmt('→%03s|', "\n=================\n");
produces this output:
→00a| →00b| →00c|
=================
→001| →002| →003|
=================
→00X| →00Y| →00Z|
That is, the format string is applied to each element in the inner lists, those lists are then stringified (without using the format string; note the between each | and → character), and then the separator is inserted between each outer list.
That leaves me with three questions:
Have I correctly described/understood the current behavior? [edit: nope. See below]
Is this behavior intentional or an odd bug? (I checked Roast, but didn't see anything either way)
Assuming this is intentional, why? Is there some way that this is consistent with Raku's general approach to handling lists that I'm missing? Or some other reason for this (imo) surprising behavior?
Edit:
After further investigation, I've realized that the behavior I observed above only occurs if the format string contains a width directive. Changing the →%03s| format string from above to →%s| produces the following output:
→a b c|
=================
→1 2 3|
=================
→X Y Z|
That is, without a width, the format string is applied after the list is stringified rather than before.
So I'm back to being confused/thinking at least some of this behavior must be buggy.
Ok, it looks like there were at least two bugs here. This should be fixed with https://github.com/rakudo/rakudo/commit/a86ec91e36 . Writing spectests for these situations, would be appreciated :-)

Why is [CByte] not allowed as an Enum member when similar keywords can be used?

I have made the following (ill-advised) Enum:
Public Enum gtUnaryOperator
[CBool]
[CByte]
[CCur]
[CDate]
[CDbl]
[CDec]
[CInt]
[CLng]
[CLngPtr]
[CSng]
[CStr]
[CVar]
[CVDate]
[CVErr]
End Enum
... featuring the names of all the type conversion functions escaped in [] square brackets. This compiles fine, and I can refer to these enum members in code (provided I escape them - e.g. ?[CCur] will print 2 in the immediate window)
However I can't use [CByte] in the same way - all the others work, but entering ?[CByte] in the immediate window gives
Compile Error, Expected "("
I've been trying to read through the language specification 3.3.5.3 Special Identifier Forms for answers, but it's a bit dense (or maybe I am) and anyway nothing leaps out as an explanation.
NB. fully qualifying:
gtUnaryOperator.[CByte]
... works fine, but I don't see why that should be necessary
Any reason CByte should be different from the others - I'm aware it's not just a normal function, but treated as a language keyword (unlike VBA.CByte), but so are all the rest of the type conversion functions (try changing your text colours).
So I'm really at a loss!

Error: Kotlin: The floating-point literal does not conform to the expected type Float

I was making a simple maths calculator in kotlin, an error appeared on my screen when I tried to initialize the value of one of the variables used as 0.00 for float integer.
var x:Float= readLine()!!.toFloat()
var y:Float= readLine()!!.toFloat()
var sum:Float=0.00// the error message is showcased in this line
sum=x+y
println("Addition " + sum)
This is a key difference between Java and Kotlin. Kotlin does not do numeric type promotion like Java does. The comments to your question are showing you how to deal with this, by either matching up the two types Double and/or Float to begin with, or by explicitly converting one or the other so that the two types match up.
Your problems goes away if you make use of Kotlin's ability to infer variable types by taking the type specifications off of your variable definitions. The fact that Kotlin infers types is one reason it does not promote numeric types. Mixing the two would lead to a lot of confusion.
Here's an example of how to fix and simplify your code's type mismatch issues using type inference:
var x = readLine()!!.toFloat()
var y = readLine()!!.toFloat()
var sum = x + y
println("Addition " + sum)
I understand that this may be just test code that you're using to understand Kotlin better. With that said, I'll point out that this code will crash if your user types in non-numeric input. You could fix this by putting a try/catch around your input lines, and providing an nice error message. You might want to put each input in a loop, continuing to ask for an input until the user does provide a response that is of the expected format.

ERROR: function regexp_matches(jsonb, unknown) does not exist in Tableau but works elsewhere

I have a column called "Bakery Activity" whose values are all JSONs that look like this:
{"flavors": [
{"d4js95-1cc5-4asn-asb48-1a781aa83": "chocolate"},
{"dc45n-jnsa9i-83ysg-81d4d7fae": "peanutButter"}],
"degreesToCook": 375,
"ingredients": {
"d4js95-1cc5-4asn-asb48-1a781aa83": [
"1nemw49-b9s88e-4750-bty0-bei8smr1eb",
"98h9nd8-3mo3-baef-2fe682n48d29"]
},
"numOfPiesBaked": 1,
"numberOfSlicesCreated": 6
}
I'm trying to extract the number of pies baked with a regex function in Tableau. Specifically, this one:
REGEXP_EXTRACT([Bakery Activity], '"numOfPiesBaked":"?([^\n,}]*)')
However, when I try to throw this calculated field into my text table, I get an error saying:
ERROR: function regexp_matches(jsonb, unknown) does not exist;
Error while executing the query
Worth noting is that my data source is PostgreSQL, which Tableau regex functions support; not all of my entries have numOfPiesBaked in them; when I run this in a simulator I get the correct extraction (actually, I get "numOfPiesBaked": 1" but removing the field name is a problem for another time).
What might be causing this error?
In short: Wrong data type, wrong function, wrong approach.
REGEXP_EXTRACT is obviously an abstraction layer of your client (Tableau), which is translated to regexp_matches() for Postgres. But that function expects text input. Since there is no assignment cast for jsonb -> text (for good reasons) you have to add an explicit cast to make it work, like:
SELECT regexp_matches("Bakery Activity"::text, '"numOfPiesBaked":"?([^\n,}]*)')
(The second argument can be an untyped string literal, Postgres function type resolution can defer the suitable data type text.)
Modern versions of Postgres also have regexp_match() returning a single row (unlike regexp_matches), which would seem like the better translation.
But regular expressions are the wrong approach to begin with.
Use the simple json/jsonb operator ->>:
SELECT "Bakery Activity"->>'numOfPiesBaked';
Returns '1' in your example.
If you know the value to be a valid integer, you can cast it right away:
SELECT ("Bakery Activity"->>'numOfPiesBaked')::int;
I found an easier way to handle JSONB data in Tableau.
Firstly, make a calculated field from the JSONB field and convert the field to a string by using str([FIELD_name]) command.
Then, on the calculated field, make another calculated field and use function:
REGEXP_EXTRACT([String_Field_Name], '"Key_to_be_extracted":"?([^\n,}]*)')
The required key-value pair will form the second caluculated field.

How to tell if an identifier is being assigned or referenced? (FLEX/BISON)

So, I'm writing a language using flex/bison and I'm having difficulty with implementing identifiers, specifically when it comes to knowing when you're looking at an assignment or a reference,
for example:
1) A = 1+2
2) B + C (where B and C have already been assigned values)
Example one I can work out by returning an ID token from flex to bison, and just following a grammar that recognizes that 1+2 is an integer expression, putting A into the symbol table, and setting its value.
examples two and three are more difficult for me because: after going through my lexer, what's being returned in ex.2 to bison is "ID PLUS ID" -> I have a grammar that recognizes arithmetic expressions for numerical values, like INT PLUS INT (which would produce an INT), or DOUBLE MINUS INT (which would produce a DOUBLE). if I have "ID PLUS ID", how do I know what type the return value is?
Here's the best idea that I've come up with so far: When tokenizing, every time an ID comes up, I search for its value and type in the symbol table and switch out the ID token with its respective information; for example: while tokenizing, I come across B, which has a regex that matches it as being an ID. I look in my symbol table and see that it has a value of 51.2 and is a DOUBLE. So instead of returning ID, with a value of B to bison, I'm returning DOUBLE with a value of 51.2
I have two different solutions that contradict each other. Here's why: if I want to assign a value to an ID, I would say to my compiler A = 5. In this situation, if I'm using my previously described solution, What I'm going to get after everything is tokenized might be, INT ASGN INT, or STRING ASGN INT, etc... So, in this case, I would use the former solution, as opposed to the latter.
My question would be: what kind of logical device do I use to help my compiler know which solution to use?
NOTE: I didn't think it necessary to post source code to describe my conundrum, but I will if anyone could use it effectively as a reference to help me understand their input on this topic.
Thank you.
The usual way is to have a yacc/bison rule like:
expr: ID { $$ = lookupId($1); }
where the the lookupId function looks up a symbol in the symbol table and returns its type and value (or type and storage location if you're writing a compiler rather than a strict interpreter). Then, your other expr rules don't need to care whether their operands come from constants or symbols or other expressions:
expr: expr '+' expr { $$ = DoAddition($1, $3); }
The function DoAddition takes the types and values (or locations) for its two operands and either adds them, producing a result, or produces code to do the addition at run time.
If possible redesign your language so that the situation is unambiguous. This is why even Javascript has var.
Otherwise you're going to need to disambiguate via semantic rules, for example that the first use of an identifier is its declaration. I don't see what the problem is with your case (2): just generate the appropriate code. If B and C haven't been used yet, a value-reading use like this should be illegal, but that involves you in control flow analysis if taken to the Nth degree of accuracy, so you might prefer to assume initial values of zero.
In any case you can see that it's fundamentally a language design problem rather than a coding problem.