Explanation of Oslo error "M0197: 'Text' cannot be used in a Type context"? - oslo

In Microsoft Oslo SDK CTP 2008 (using Intellipad) the following code compiles fine:
module M {
type T {
Text : Text;
}
}
while compiling the below code leads to the error "M0197: 'Text' cannot be used in a Type context"
module M {
type T {
Text : Text;
Value : Text; // error
}
}
I do not see the difference between the examples, as in the first case Text is also used in a Type context.
UPDATE:
To add to the confusion, consider the following example, which also compiles fine:
module M {
type X;
type T {
X : X;
Y : X;
}
}
The M Language Specification states that:
Field declarations override lexical scoping to prevent the type of a declaration binding to the declaration itself. The ascribed type of a field declaration must not be the declaration itself; however, the declaration may be used in a constraint. Consider the following example:
type A;
type B {
A : A;
}
The lexically enclosing scope for the type ascription of the field declaration A is the entity declaration B. With no exception, the type ascription A would bind to the field declaration in a circular reference which is an error. The exception allows lexical lookup to skip the field declaration in this case.
It seems that user defined types and built-in (intrinsic) types are not treated equal.
UPDATE2:
Note that Value in the above example is not a reserved keyword. The same error results if you rename Value to Y.
Any ideas?
Regards, tamberg

From what I am seeing you have redefined Text:
Text : Text
and then you are attempting to use it for the type of Value:
Value : Text
which is not allowed. Why using a type name as a property redefines a type I'm not entirely clear on (still reading M language specification), but I'm sure there's a good reason for it. Just name Text something that's not already a defined type (escaping it with brackets ([Text]) does not work either).

http://social.msdn.microsoft.com/Forums/en-US/oslo/thread/fcaf10a1-52f9-4ab7-bef5-1ad9f9112948

Here's the problem: in M, you can do tricks like this:
module M
{
type Address;
type Person
{
Addresses : Address*;
FavoriteAddress : Address where value in Addresses;
}
}
In that example, "Addresses" refers to Person.Addresses. The problem, then, is that when you write something innocuous like
module M
{
type T
{
Text : Text;
SomethingElse : Text;
}
}
...then the "Text" in the type ascription for SomethingElse refers not to Language.Text, but to T.Text. And that's what's going wrong. The workaround is to write it like this:
module M
{
type T
{
Text : Text;
SomethingElse : Language.Text;
}
}
(You may wonder why things like "Text : Text" work in the example above. There's a special rule: identifiers in a field's type ascription cannot refer to the field itself. The canonical example for this is "Address : Address".)

Related

How we call an struct inside of another struct as embedded?

Why we don't call person field as embedded?
“type user struct {
 name  string
 email string
}
 
type admin struct {
 person user  // NOT Embedding
 level  string
}”
But in other cases like below we call it embedded:
“type user struct {
 name  string
 email string
}
 
type admin struct {
 user  // Value Semantic Embedding
 level  string
}”
What I think is that person is also embedded like value/pointer semantic embedding. What I'm missing here?
Because that's how the Go language specification defines it:
A field declared with a type but no explicit field name is called an embedded field.
I can see how the term "embedded" would be confusing. After all, named and unnamed fields end up with the same memory layout, "embedded" into the parent struct. "Anonymous field" might have been a better name for it, but that's not the name that the Go language designers chose.
With the first code you can't treat an admin object as a user object, like using member access or type assertion. This also affects how an embedding struct satisfies interfaces.
For example, the following code works with proper embedding, but not a simple member struct:
var a admin
a.name = "asdfg"
u := a.(user)

parse simple terraform file using go

I now tried, everything but cant get this simple thing to work.
I got the following test_file.hcl:
variable "value" {
test = "ok"
}
I want to parse it using the following code:
package hcl
import (
"github.com/hashicorp/hcl/v2/hclsimple"
)
type Config struct {
Variable string `hcl:"test"`
}
func HclToStruct(path string) (*Config, error) {
var config Config
return &config, hclsimple.DecodeFile(path, nil, &config)
But I receive:
test_file.hcl:1,1-1: Missing required argument; The argument "test" is required, but no definition was found., and 1 other diagnostic(s)
I checked with other projects using the same library but I cannot find my mistake .. I just dont know anymore. Can someone guide me into the right direction?
The Go struct type you wrote here doesn't correspond with the shape of the file you want to parse. Notice that the input file has a variable block with a test argument inside it, but the Go type you wrote has only the test argument. For that reason, the HCL parser is expecting to find a file with just the test argument at the top-level, like this:
test = "ok"
To parse this Terraform-like structure with hclsimple will require you to write two struct types: one to represent the top level body containing variable blocks and another to represent the content of each of the blocks. For example:
type Config struct {
Variables []*Variable `hcl:"variable,block"`
}
type Variable struct {
Test *string `hcl:"test"`
}
With that said, I'll note that the Terraform language uses some features of HCL that hclsimple can't support, or at least can't support with direct decoding like this. For example, the type argument inside variable blocks is a special sort of expression called a type constraint which hclsimple doesn't support directly, and so parsing it will require using the lower-level HCL API. (That's what Terraform is doing internally.)
Thanks to #Martin Atkins, I now have the following code that works:
type Config struct {
Variable []Variable `hcl:"variable,block"`
}
type Variable struct {
Value string `hcl:"name,label"`
Test string `hcl:"test"`
}
With that I can parse a variables.tf like:
variable "projectname" {
default = "cicd-template"
}
variable "ansibleuser" {
default = "centos"
}

How to add default values to input arguments in graphql

I have this input type and I would like to add a default Value to one of the fields. I want to add 0 to the value field inside the ExampleInput.
type ExampleType {
value: Int
another: String
}
type Mutation {
example(input: ExampleInput): ExampleType
}
input ExampleInput {
value: Int
another: String
}
Any ideas?
It looks like the grammar allows default values on input object types, so you can declare
input ExampleInput {
value: Int = 0
another: String
isAvailable: Boolean = false
}
The spec is clear that default values exist and explains how they get used (first bullet under "Input Coercion").
(Whether any specific tooling supports this is probably variable: graphql.org had an informal version of the IDL for quite a while before it was actually in the spec, and I have the impression some libraries haven't caught up to the released spec yet.)

anonymous fields in type declaration?

I came across this type declaration:
type Handler func(*Conn)
type Server struct {
Handshake func(*Config, *http.Request) error
Handler
}
(this is a simplified version of https://github.com/golang/net/blob/38c17adf51120973d1735785a7c02f8ce8297c5e/websocket/server.go#L55-L66
The second field in the Server structure is anonymous. There is just type and no name.
Here is the grammar for type declarations (https://golang.org/ref/spec#Type_declarations):
TypeDecl = "type" ( TypeSpec | "(" { TypeSpec ";" } ")" ) .
TypeSpec = identifier Type .
and it clearly requires an identifier name. But yet the section that I referenced that contains the grammar, also mentions anonymous fields.
I do not understand why this syntax is correct and how anonymous fields are used.
You want to look at the part of the grammar that has to do with structures, not just types. See: Struct types and the use of AnonymousField. Looking just at the production for TypeSpec is focusing attention on the wrong place. Instead, look at FieldDecl; the grammar shows that we have two possibilities: named fields (IdentifierList Type), or anonymous fields (AnonymousField).
Anonymous fields are typically used for embedding. In your example, a Server will act like a Handler because it has embedded that field.

Can I use gcc visibility attributes on an enumeration?

I have the following enum:
__atttribute__((visibility ("default") )) enum MSG
{
OK,
FAIL,
};
When I compile, it gives me the warning:
warning: attribute ignored in declaration of ‘enum MSG’
warning: attribute for ‘enum MSG’ must follow the ‘enum’ keyword
When I put the attribute after the enum, I get the following errors:
warning: type attributes are honored only at type definition
error: use of enum ‘MSG’ without previous declaration
error: expected unqualified-id before ‘{’ token
Can anyone tell me how to fix this?
The visibility attribute applies to symbols like functions and variables. A definition of an enumeration type that doesn't contain a variable name doesn't create any symbols.
Enumeration type without a variable:
enum msg { OK, FAIL };
An enumeration variable:
enum msg message;
Enumeration type together with a variable:
enum msg { OK, FAIL } message;
In the first case, there's no symbol the visibility attribute could affect at all.
You can fix this by declaring the type of your enum like this:
enum class MSG : std::uint32_t __atttribute__((visibility ("default") ))
{
OK,
FAIL,
};
Though it seems like this is a bug in GCC that was fixed in versions 6+. Related SO post

Resources