How to compare AliasSeq's in D - metaprogramming

Examples in std.meta suggest to use is(AliasSeq!(...) == AliasSeq!(...)), but this fails in cases like this:
static assert(is(TypeTuple!(3, int, "Zorro") == TypeTuple!(3, int, "Zorro")));
The example comes from the news group. In the same thread, there is a hint to use foreach to compare aliases one by one, but I found that the following is shorter and works well:
struct X(S...) {}
static assert(is(X!(AliasSeq!(3, int, "Zorro")) == X!(AliasSeq!(3, int, "Zorro"))));
or
static assert(is(X!(3, int, "Zorro") == X!(3, int, "Zorro")));
Do you know if there's any situation when this fails? Is there any better method to 100% reliably compare AliasSeqs?

Related

mypy with numbers.Number

I was hoping to use mypy's static duck typing facility to write a function that can process a sequence of number-like objects, where "number-like" is defined by numbers.Number:
from numbers import Number
from typing import Sequence
def something_numerical(xs: Sequence[Number]) -> Number:
...
print(something_numerical([1., 2., 3.]))
However, when I call this code with a list of floats or ints, I get a mypy error:
$ print(multiply([1., 2., 3.]))
foo/foo.py:9: error: List item 0 has incompatible type "float"; expected "Number"
foo/foo.py:9: error: List item 1 has incompatible type "float"; expected "Number"
foo/foo.py:9: error: List item 2 has incompatible type "float"; expected "Number"
I realize that the float type is not a subclass of numbers.Number. However, the numbers module provides a set of abstract base classes that are intended to be used to check whether an object has the requisite methods to do numerical operations. How might I rewrite this code so that (1) it can still process ints, floats, fractios.Fraction, and so on, and (2) so that it passes type checking by mypy?
The answer by #SUTerliakov is informative and accurate; however, while working on this problem I came across another way of solving the problem that I will post here for others who encounter this. I simply defined my own "Number" protocol from scratch:
from typing import Protocol
class Number(Protocol):
def __abs__(self) -> 'Number':
...
def __mul__(self, Number) -> 'Number':
...
def __add__(self, Number) -> 'Number':
...
def __lt__(self, Number) -> bool:
...
def __gt__(self, Number) -> bool:
...
def __truediv__(self, Number) -> 'Number':
...
def __rtruediv__(self, Number) -> 'Number':
...
Here the choice to include __mul__, __abs__, __truediv__ and so on were based on the operations I needed to perform inside my function, rather than based on any abstract notion of what a number ought or ought not to be.
It seems that the "number" concept in python is quite complicated and hard to fit all cases, so it really might make logical sense to define a per-project protocol like this.
It was stated in #bzu answer, but I'd like to add some explanation to it.
First thing to note: issubclass(int, Number) and issubclass(float, Number) both evaluate to True. This is very surprising type-checking behavior, but it was standardized in PEP484:
Rather than requiring that users write import numbers and then use numbers.Float etc., this PEP proposes a straightforward shortcut that is almost as effective: when an argument is annotated as having type float, an argument of type int is acceptable; similar, for an argument annotated as having type complex, arguments of type float or int are acceptable. This does not handle classes implementing the corresponding ABCs or the fractions.Fraction class, but we believe those use cases are exceedingly rare.
So to support built-in numbers you can use just int, float or complex. To handle other ABC's you should use appropriate numbers member. I don't know why float was not made compatible with numbers.Number.
For almost all cases you can use a type alias (TypeAlias was backported with typing_extensions module for python<3.10):
from fractions import Fraction
from numbers import Number
from typing import TypeAlias
AnyNumber: TypeAlias = Number | float
def f(x: AnyNumber) -> bool:
return x == 0
f(1)
f(1.0)
f(Fraction(1, 3))
This typechecks. One incompatible class I'm aware of is decimal.Decimal: it is not compatible (it would be expected, if Number were made compatible with float, because Decimal is not and Decimal(1) / 2 fails - but it is not the case, as we'll see later).
If your function uses AnyNumber and int together, everything dies:
def f(x: AnyNumber) -> float:
return x / 2 + 1 # E: Unsupported operand types for / ("Number" and "int")
Although you can, for example, do Fraction(1,2) / 2, Number does not guarantee int or float compatibility. You can use numbers.Real or numbers.Complex instead - they are compatible with float:
AnyReal: TypeAlias = Real | float
This allows x / 2 + 1 and remains incompatible with decimal.Decimal, but now it is intended behavior.
You can use this playground to investigate the topic further. Also having look at numbers in typeshed may help.
It seems using Union will be the way to go:
from numbers import Number
from typing import Sequence, Union
from fractions import Fraction
def something_numerical(xs: Sequence[Union[Number, float]]) -> Union[Number, float]:
return sum(xs)
if __name__ == '__main__':
print(something_numerical([1.2, 2, Fraction(1, 2)]))

python: what does the colon mean?

I am trying to read the code simpy, but i have some questions.
def __init__(self, initial_time: SimTime = 0):
self._now = initial_time
self._queue: List[
Tuple[SimTime, EventPriority, int, Event]
] = [] # The list of all currently scheduled events.
self._eid = count() # Counter for event IDs
self._active_proc: Optional[Process] = None
# Bind all BoundClass instances to "self" to improve performance.
BoundClass.bind_early(self)
what does the colon mean?
initial_time: SimTime = 0
self._queue: List[Tuple[SimTime, EventPriority, int, Event]] = []
thanks for your help.
It seems to be a Typedef Hint for a defined variable, with a special type of SimTime with value 0 being passed into the function.
If you get a chance, check out PEP483, PEP484, as well as the typing module for more information on Typedef hints.
Since it seems to be an uncommon type, I would check for Type Aliases as well. PEP613 is about Type Aliases.
I don't know what else it could be, but maybe it is something else.

Xtext: Create a unique ID for objects

I have a grammar that looks like
A:
...
B:
...
I want to be able to give each element of type B some serial ID. So every time that the grammar creates a B object, it gets a (unique) new ID as a field.
I tried to do something like:
B:
myID=Tracer.getID()
...
where:
class Tracer {
static int ID=0;
static int getID() { return ID++;}
But I can't call external java class from the grammar.
It would be better if it's solvable without touching the src-gen files.
Thanks.
Are you aware that in textual models, there is no such thing as object identity? I.e. you fundamentally can't say that any two objects in different ASTs are identical. You can only establish an interpretation of equivalence using diff algorithms.
That aside, if you only need a temporary identity, what about using Object.hashCode()?

Relational override on 'objects'?

I have a signature
sig Test {
a: Int,
b: Int,
c: Int
}
If I have two instances (atoms?) of this ( x,y:Test )
can I define a relation between these where only some parameters has changed without having to list all the other parameters as equal?
I want to avoid having to list all unchanged fields
as this can be error-prone assuming I have many fields.
Currently I am using x.(a+b+c) = y.(a+next[b]+c) but would like to use something like x = y ++ (b->next[y.b])
from what I understand about Alloy I think the answer is No: you cannot talk about all relations where some atom is involved in without explicitly naming these relations. But some experts may correct me if I'm wrong.

dot operators on functions

I don't know if this is possible, but are there any languages where you can use a dot operator on a function per se. I'll give an example.
function blah returns type2
type 2 looks like this
{
data
number
}
when I call blah are there any languages that support blah.number, so that when it makes the function call and gets the type2, it then grabs number and returns that. I'm sorry if this is an obvious answer, but I couldn't even think of a good way to word it to google it.
I just ran into a situation that would be convienient to have that, rather then make an intermediate variable you just make sure you return the type.
I know that I could add a "get" function that would get the specific number variable from that type, but that's an additional function someone would have to add so I am excluding that as a option (as I can just return the type and access using a variable there isn't really a dire need for a new function).
EDIT: I feel like an idiot.....
EDIT # 2: For some reason I had it in my head that you couldn't do dot operations on functions, (I don't care about the parentheses I was just trying to give an example)
Edit # 3: Is there a name for this or is it still just a dot operation?
Well this works in C if the function returns a struct like this:
struct retval {
char * data;
int number;
};
retval foo() {
// do something and then return an instance of retval
}
// call
int a = foo().number;
I would like to know if there is any language that does not support something like this.
About Edit #3
The name would generally be member access, since all you do is to access a member of the return value. This could differ across languages though.
In most languages you can do Blah().Member ... the typing of a pair of parentheses won't kill you, will it? These languages include C, C++, Java, C# etc.
Yep, to the best of my knowledge, most modern languages (if not most languages in general) support this.
Maybe I misunderstand you, but in most languages, you can already do that.
in java for example, if you have a function get_foo() returning an object of type foo, and foo is defined as
Class Foo{
public int bar;
public double baz;
}
you can do get_foo().bar returning bar
Any language that allows a function to return an object/struct will support that... And languages like Ruby (where the () are optional) will make it exactly like you tiped (blah.number instead of blah().number).
Another way of avoiding the parentheses is using a property or an equivalent idiom... So C#, VB.NET and Python would also allow that.
If you want to make a new function out of an existing one, it's possible with lambda expressions. In C#, for example, it'd be var fooblah = (x => foo(x).blah); Obviously, if there's an overloading available in the language, you can't do it without giving a list of arguments.
Er...you mean, like a returning a class or a struct?
In C#
private class Blah
{
public string Data {get; set;}
public int Number {get; set;}
}
public Blah DoSomething()
{
return new Blah{Data="Data",Number=1};
}

Resources