Closed cosmos72 closed 8 years ago
Could you elaborate a bit more about the example? I think I'm not getting the idea well.
Let me add the C++ equivalent, and see if it helps: the CL template
(template (<t1> <t2>)
(defstruct pair
(first nil :type <t1>)
(second nil :type <t2>)))
is equivalent to C++
template<class T1, class T2>
struct pair
{
T1 first;
T2 second;
};
Then in C++, a partial specialization for pair, for example when first
and second
are both std::vector<T>
for some T
, would be:
template<class T>
struct pair<std::vector<T>, std::vector<T> >
{
std::vector<T> first;
std::vector<T> second;
};
I proposed to represent such partial specialization with the syntax:
(template (<t>)
(:specialized-for ((array <t>) (array <t>))
(defstruct pair
(first nil :type (array <t>))
(second nil :type (array <t>))))
Thinking about it, one alternative could be the syntax:
(template (<t>)
(defstruct (pair (array <t>) (array <t>))
...))
it has one objective advantage: it is almost identical to C++. In my opinion it has a disadvantage too: the meaning of a single (template ...)
containing multiple definitions is probably less clear
I got it. (1) The first syntax looks better than the alternative syntax because the latter changes the defstruct
syntax. Next, (2) The point "multiple definitions is probably less clear" is not obvious to me. I guess it would have to repeat the partial specialization, e.g.:
(template (<t>)
(defstruct (pair (array <t>) (array <t>))
...)
(defun (less (array <t>) (array <t>)) (a b)
...))
which is a disadvantage, but it could be refined by typedef
equivalent (discussed later). Anyway, although (2) is not obvious to me, due to (1), I also vote for the first syntax.
Question: Are those arguments matched to the original parameters by the positions? For example, "will it blend" if you mix two templates with the different parameter names?
(template (<t1> <t2>)
(defstruct pair1 ...))
(template (<t2> <t3>)
(defstruct pair2 ...))
(template (<t>)
(:specialized-for ((array <t>) (array <t>))
(defstruct pair1 ...)
(defstruct pair2 ...))
Re: typedefs. proposal:
(template (<t>)
(:typedef <t1> (array <t>)) ;; this does not imply specialization --- just a local alias
(:specialized-for (<t1> <t1>)
(defstruct pair
(first nil :type <t1>)
(second nil :type <t1>)))
On Apr 30, 2016 3:51 AM, "Masataro Asai" notifications@github.com wrote:
I got it. (1) The first syntax looks better than the alternative syntax because it changes the defstruct syntax. Next, (2) The point "multiple definitions is probably less clear" is not obvious to me. I guess it would have to repeat the partial specialization, e.g.:
(template (
) (defstruct (pair (array ) (array )) ...) (defun (less (array ) (array )) (a b) ...)) which is a disadvantage, but it could be refined by typedef equivalent (discussed later). Anyway, although (2) is not obvious to me, due to (1), I also vote for the first syntax.
Ok, it makes sense. Thanks for the feedback
Question: Are those arguments matched to the original parameters by the positions? For example, "will it blend" if you mix two templates with the different parameter names?
(template (
) (defstruct pair1 ...)) (template ( ) (defstruct pair2 ...)) (template ( ) (:specialized-for ((array ) (array )) (defstruct pair1 ...) (defstruct pair2 ...))
Yes, parameters are matched by position
Re: typedefs. proposal:
(template (
) (:typedef (array )) ;; this does not imply specialization ;; just a local alias (:specialized-for ( ) (defstruct pair (first nil :type ) (second nil :type )))
I was thinking about local types too... CL has flet and macrolet, but no typelet. Not a big problem usually, because deftype is not used heavilly, but with templates requiring explicit types it would be very useful. No idea how to implement typelet in the most general case though... easy to do immediately inside (template... ), but what about outside it, or deep inside a template function?
Regards, Massimiliano
Implemented syntax (1) i.e.
(template (<t>)
(:specialized-for ((array <t>) (array <t>))
(defstruct pair
(first nil :type (array <t>))
(second nil :type (array <t>))))
I am open to suggestions :)
Given a general case like
my idea for partial specialization syntax is something like:
I also had a look at OPTIMA, but if I introduce general pattern matching, once there are multiple partial specializations for the same general template, I have no idea how to write the algorithm for deciding which one is the most specific (or to decide that none is more specific than the others)
Any thoughts? @guicho271828 ?