Hi Guys,

Sorry for disappearing for two weeks, it was due to the increase load at work. 
I read through the Concepts manual proposal on Github. It is a long manual with 
clear descriptions and examples. Congrats! The rest of my post might feel 
negative a bit, but I'm really happy with this progress.

Here are some comments.
    Peter

**1**:

> Within the concept body, types can appear in positions where ordinary values 
> and parameters are expected.

I'm against this. I understand this is very handy, I can clearly see that the 
examples are easy to follow, and I know that this is only the syntax. And I can 
live with this if everybody thinks that this is the right way. However, it 
makes an extra twist in the language. I think that Python is great because you 
can do almost everything after learning about list, tuple and dict. Lisp is so 
powerful, because once you accept its dummy function syntax `(+ 1 2)`, you can 
modify your code from code. That is why I'm against any special treatment in 
concepts: if I (finally learn how to) generate code from a tempate/macro, then 
I cannot use exactly the same language for concepts.

> In order to check for symbols accepting `typedesc` params, you must prefix 
> the type with an explicit `type` modifier.

(Sorry, I'm going to be mean here just to make a point.) Following this logic 
should this code: 
    
    
    AdditiveMonoid* = concept x, y, type T
      x + y is T
      ...
    

be something like this? 
    
    
    AdditiveMonoid* = concept x, y, type T
      x + y is type T
      ...
    

Or the `is` magic is an exception from this rule?

**2**: 
    
    
    proc transpose*[R, C, T](m: AnyMatrix[R, C, T]): m.type.basis[C, R, T] =
      for r in 0 .. <m.R:
        for c in 0 .. <m.C:
          result[r, c] = m[c, r]
    

What is `basis` here?

(Very unimportant comment, just some words about this example: we can have a 
(very inefficient) matrix implementation which stores the elements in an SQL 
database, or just simple on the heap. Is it ok not to initialize the result 
here? The `AnyMatrix` concept suggest that we must have it on the stack with an 
`Array` object (only the order can be different, e.g., Fortan vs C). So how 
about adding an `m.init()` to the concept, and a `result.init()` just before 
setting the values?)

**3**:
    Unbound types can appear both as params to calls such as s.push(T) and on 
the right-hand side of the `is` operator in cases such as x.pop is T and x.data 
is seq[T].

and later 
    
    
    type
      MyConcept = concept x
        type T1 = auto
        x.foo(T1)
        x.bar(T1) # both procs must accept the same type
    

Please don't. First, I still find it very strange that we overload the `is` 
operator. But having any function calls to infer types looks very dangerous. If 
you still think that this is the way to go, then please answer the following 
questions:

What happens if we have several `proc foo(x: ..., a: ...)` and `proc bar(x: 
..., b: ...)` functions, do the compiler find a type in common? What happens if 
there are more than one type in common? (It has to be unique, just think that 
you can access this type from outside if it is generic.) Can I break a concept 
match by adding a new function? What happens if I have `proc foo(x:..., a: 
auto)`? Or let's twist it, I can have `proc foo(x:..., a: seq[any])`, what 
happens there? If I have `foo` functions which eat 8 different types, then can 
I force the compiler to find a way to put 8 queens on the chess board not 
attacking each other? How fast will it be? Can we force it to return the first 
in lexicographic order, or is it going to be random/all?

**4**:

In the example of _Converter type classes_, there are `Stringable` and 
`makeStringRefValue`. These symbols are given only once (you are creating a 
concept, which is not used, you are calling a function which is not defined). 
Is this on purpose?

Is everything used for the calculation has to be after the `return` keyword? 
Can you do some precalculation before the `return` line? I guess not, because 
those lines are used for the concept check. Let me point out again that before 
return this is valid, and after return this is not valid: `x.f(string, float)`.

**5**:

I can't comment on _VTable types_. I guess using this I could have a function 
which actually eats many types, but still have one implementation in C which 
does the type check at runtime. Sounds awesome in some cases, and very 
complicated. I'm not sure that we can afford this complication at this point, 
but I haven't seen the code for this. 

Reply via email to