tomhrr / dale

Lisp-flavoured C
BSD 3-Clause "New" or "Revised" License
1.03k stars 48 forks source link

Implement concepts in refinements instead of reporting an error. #85

Closed porky11 closed 8 years ago

porky11 commented 8 years ago

Benefits: You don't have to search, which concepts still have to be implemented, the concepts own error messages will be called, showing which functions have still to be implemented (or other errors). Will cause no compile time overhead when manually defined anyway

tomhrr commented 8 years ago

On Wed, Sep 07, 2016 at 11:55:46AM -0700, Fabio Krapohl wrote:

Benefits: You don't have to search, which concepts still have to be implemented, the concepts own error messages will be called, showing which functions have still to be implemented (or other errors). Will cause no compile time overhead when manually defined anyway

I'm not sure I understand the suggestion. For example:

user@host:~$ cat test.dt
(import concepts)

(def mys (struct intern ((a int))))

(std.concepts.implement Container mys)
user@host:~$ dalec test.dt
test.dt:5:35: error: swap is not defined over this type (see macro at 315:26)
/home/tomh/work/dale/modules/concepts-core.dt:315:26: error: macro expansion error (see previous) (see macro at 5:1)
user@host:~$

Container refines Swappable, and the error message about the lack of a swap definition is coming about because of that refinement. Not that the error message is particularly wonderful (it should really include the concept name as well). Is there an instance where the above is not happening?

porky11 commented 8 years ago

This issue is also about trying to implement something automatically/implicitely, but at some other position

porky11 commented 8 years ago

A concept can be implemented even if the types in the refines-list are not implemented. They just call all the other concepts with the same type. I would prefer if all the types in the refines-list have to be implemented before implementing the type. This may also cause compile-time-benefits i.e. when the functions inside the concepts are large, because it only has to be checked, if the macros are implemented for the type. Because the concepts in the refines-list have to be implemented, they can even be implemented automatically, when the concept is implemented. Or is there any useful case, where a concept refines a concept, which is not implemented for that type?

Some useful case for implementing would be to implement Struct on some type, and Type is implemented then automatic, or adding some concepts like Add and Sub, and some concept MathType, which refines Add, Sub etc. and in most cases you would just implement MathType instead of all concepts in the refines-list

porky11 commented 8 years ago

I looked at the code, and the macroexpansions, and it seems it is already meant to be done this way, but does not work properly for example, when I define a concept BasicMath that (refines Add Sub Mul Div) and implement it for some type, it only implements the first element of the refines-list (i.e. Add) too, so this seems to be a Bug

tomhrr commented 8 years ago

On Mon, Sep 12, 2016 at 12:01:37PM -0700, Fabio Krapohl wrote:

I looked at the code, and the macroexpansions, and it seems it is already meant to be done this way, but does not work properly for example, when I define a concept BasicMath that (refines Add Sub Mul Div) and implement it for some type, it only implements the first element of the refines-list (i.e. Add) too, so this seems to be a Bug

Thanks, this has now been fixed.