Feedback.
What are you giving feedback on?
How I plan on implementing templates (similar to C++'s template arguments) and raw-types in Janky.
All feedback, good or bad, as long as it's constructive and non-sarcastic is accepted, and I'll be trying to respond, and take as many notes as possible.
Thanks in advance!
Templates.
Templates act like C++'s template arguments, but they look like Java's generics, here's what I'm thinking they'll look like:
// Should the `type` keyword be optional here?
// Type identifiers can also be used here, so I thought I should ask.
struct MyType<type T> {
MyType(T v) { this.value = v; }
T value;
}
Legal:
MyType<int>;
MyType<MyType>;
MyType<void>; // This is a special case.
MyType<T>;
Illegal:
MyType<null>;
MyType<0>;
MyType< MyType() >;
MyType< new MyType() >;
void
's special case...
Fun fact... did you know you can run this snippet of C++ legally, without any errors or warnings?
template<typename T> T create() {
return T();
}
create<void>();
T value = create<T>();
NOTE: Expansion to { T val/* = T()*/; return val; }
causes multiple errors if you pass void
.
Yeah! Passing in void works!
But... What does this mean for object-members in my language?
This means they'll (act as if they've) be(en) removed from the object.
Note, if void
is generic, then it may take any number of arguments for its constructors, consisting of any type.
Raw Types.
Love 'em or hate 'em, they have to come, they're too useful in the most niche of situations.
For example, if you want a heterogeneous array of a template type MyType
, so instead of MyType<type T>
, you could use raw MyType
.
raw
would be its own keyword, to:
- A: Avoid any confusion/ambiguity between raw types, and types with default template arguments.
- B: To make sure types aren't accidentally raw.
Regarding the type-safety of Raw Types (in Janky).
I know when it comes to raw-datatypes, types whose generic-type-arguments aren't specified, have some type-safety concerns, and such concerns are valid, because these types CAN be dangerous, and aren't afraid to help create nasty bugs.
But, I've put some forethought into the matter. and I'll discuss these briefly.
Where can Raw Types be passed?
Raw types (raw MyType
*) can be passed to functions, methods, constructors, and other callables just like how any other kind of types (MyType<T>
*) can.
There's a catch though, the type qualifiers for the MyType<T>
in the parameter signature should include raw
, meaning this:
void f(raw MyType value) {/* Do stuff... */}
void g(raw MyType<int> value) {
/* We'll talk about this in a minute... */
}
void h(MyType value) {
/* Illegal function definition: MyType must include
a(n) (type) argument for `T`. */
}
void j(MyType<int> value) {
/* Do stuff... */
}
raw MyType rawval = MyType<int>(10); // The `<int>` is required.
MyType<int> cookedval = MyType<int>(10); // The second `<int>` is optional.
f(cookedval); // Fine. It just "uncooks" the value.
g(cookedval); // Fine. (No "uncooking" needed.)
j(cookedval); // Fine.
f(rawval); // This is okay (obviously).
g(rawval); // This is fine... In this case...
j(rawval); // Not fine. - Raw and cooked types are not compatible.
What is (the elusive) raw MyType<T>
?
Maybe you've figured it out from the last example, maybe you haven't.
Anyways. The these types that are both cooked, but have the raw type-qualifier are called "undercooked" types. Though, I think a more accurate, and beautiful name for them may be "baked types" (Feedback for which name to use, if this should be implemented, is welcome!).
So, what are baked types? Well, as the last line of my elaborate example says, "Raw and cooked types are not compatible
". Meaning that, even if a raw MyType
contains an int
, it still isn't compatible with MyType<int>
.
But, I've decided to allow this "cooking" of the raw type on one condition, and that's if MyType<T>
has the raw
qualifier (this is a safety mechanism to stop types from being cooked accidentally).
Wrapping up.
So. Those were my ideas for Templates and Raw Types in Janky. Tell me your thoughts below!
Top comments (0)