Feature ASH function templates

heeheehee

Developer
Staff member
C++ has a notion of templates, e.g.
PHP:
template <typename T>
T max(T a, T b) {
  return a > b ? a : b;
}
...
max<int>(4, 13); // returns 13

The Java generics API is somewhat more concise (ignoring things like inheritance which just don't exist in ASH):
PHP:
<T> T max(T a, T b) {
    return a > b ? a : b;
}
Currently, I find myself duplicating code to change types of maps, e.g.
PHP:
string as_list(boolean[string] stuff) {
  buffer s;
  foreach thing in stuff {
    if (s.length() > 0) {
      s.append(", ");
    }
    s.append(thing);
  }
  return s.to_string();
}

string as_list(boolean[item] stuff) {
  buffer s;
  foreach thing in stuff {
    if (s.length() > 0) {
      s.append(", ");
    }
    s.append(thing);
  }
  return s.to_string();
}
...
as_list(item_array);
as_list(string_array);
I'd be happier if I could just write
PHP:
<T> string as_list(boolean[T] stuff) {
    ...
}
...
as_list<item>(item_array);
as_list<string>(string_array);

The functional programmer in me also notes that this could be combined with call to implement various well-known functional programming paradigms, e.g.
PHP:
<A> A[int] filter(string function_name, A[int] input) {
  A[int] output;
  foreach i in input {
    if (call boolean function_name(input[i])) {
      output[count(output)] = input[i];
    }
  }
  return output;
}

Initial comment regarding potential implementation: my understanding is that the compiler creates a new instance of the function for each distinct template specialization.
 
Last edited:

xKiv

Active member
Java generics do not make sense without inheritance (and interfaces). That's the only thing they do: let you write inheritance-aware code without constant up/downcasting. That's not something I can see being useful in ASH.

C++ templates are a laterally different concept. They are not code yet, they are *templates* for code, and need to be instantiated (or preprocessed, but by yet different part of the toolchain than the C/C++ preprocessor is). As you say, this generates new functions (and types, if you template-ize a struct). That's something I can see in ASH.
(C++ templates also allow for insane things at compile-time, with parameters that have computed values, but I don't think we want *that* in ASH ... yet)
 

heeheehee

Developer
Staff member
Java generics do not make sense without inheritance (and interfaces). That's the only thing they do: let you write inheritance-aware code without constant up/downcasting. That's not something I can see being useful in ASH.

Not true! The entire java.util.Collections library benefits largely from the use of generics, which in turn helps type-safety when using, say, a HashSet<String> (so you can't throw arbitrary other datatypes into the set).
 

xKiv

Active member
Not true! The entire java.util.Collections library benefits largely from the use of generics, which in turn helps type-safety when using, say, a HashSet<String> (so you can't throw arbitrary other datatypes into the set).

And they do even that by handling everything as Object and then up/downcasting automatically behind the scenes. You benefit mostly by not being able to forget to write those up/downcasts explicitly.
Templates don't need to have common ancestor, they only need duck-typing.

(one of the most visible differences is that you can template on a primitive type (like int), which is something you cannot do with generics)

But what I really meant is that, with generics, if you want to handle the generically parametrized objects in any way, you have to constraint the generic type to extend from some class or interface (in the case of collections, from Object - that's all you need for ==, equals(), hashCode(), and for passing references around), or explicitly cast. Which means that you often cannot generically handle third-party objects even though they have the right methods (but not the right interface). (and thus, wrapper objects proliferate).
 

heeheehee

Developer
Staff member
And they do even that by handling everything as Object and then up/downcasting automatically behind the scenes. You benefit mostly by not being able to forget to write those up/downcasts explicitly.
Templates don't need to have common ancestor, they only need duck-typing.
I don't disagree on that front; that's just a design choice (limitation?) of Java.

(one of the most visible differences is that you can template on a primitive type (like int), which is something you cannot do with generics)
...
(and thus, wrapper objects proliferate).
Yup, Integer, Float, etc. I guess my original Java example doesn't quite work, since you'd really want to be invoking a.compareTo(b), T would extend Comparable, etc.

Either way, I only cited Java's generic system because the syntax is ever so slightly more concise than C++'s templates, and the concept is similar.
 
Top