Calling same-named-function from abstruct object

2020-09-27 Thread chaemon
I am wrote the following three files. There are two objects ModInt and 
FormalPowerSeries. FormalPowerSeries has generics T and it takes ModInt. Both 
objects has proc named pow. Pow is called from FormalPowerSeries and in the 
proc, it also call pow of generics T.

test.nim: 


import modint
import formal_power_series

var v = FormalPowerSeries[ModInt](data: @[ModInt()])

echo v.pow(2)


Run

formal_power_series.nim: 


#import modint

type FormalPowerSeries*[T] = object
  data*:seq[T]

proc pow*[T](self:FormalPowerSeries[T], k:int):auto=
  @[T().pow(k)]


Run

modint.nim: 


type ModInt* = object
  a*:int

proc pow*(a:ModInt, k:int):ModInt = a


Run

Then, I compiled test.nim, getting error that 


Error: type mismatch: got 
but expected one of:
proc pow[T](self: FormalPowerSeries[T]; k: int): auto
  first type mismatch at position: 1
  required type for self: FormalPowerSeries[pow.T]
  but expression 'T()' is of type: ModInt

expression: pow(T(), k)



Run

It seems that the function pow of T(=ModInt) is not recognized. But I know that 
changing the proc name "pow" of ModInt to any other name and making these proc 
different works. I also know that inserting a line "import modint" (which is 
commended out now) to formal_power_series.nim works. But it is not prefered 
because I want to make the object FormalPowerSeries abstruct i.e. it works any 
object T which has proc pow.

Are there any way to avoid error?


Calling same-named-function from abstruct object

2020-09-27 Thread Araq
This should do the job:


proc pow*[T](self:FormalPowerSeries[T], k:int):auto=
  mixin pow
  @[pow(T(), k)]



Run


Calling same-named-function from abstruct object

2020-09-27 Thread chaemon
Thanks! I didn't know mixin statement. 


Calling same-named-function from abstruct object

2020-09-27 Thread shirleyquirk
If your intention is for `pow` to be overloaded, you can declare it an "open 
symbol" with the [mixin 
statement](https://nim-lang.org/docs/manual.html#generics-mixin-statement)

like this: 


type FormalPowerSeries*[T] = object
  data*: seq[T]

proc pow*[T](self: FormalPowerSeries[T], k: int): auto =
  mixin pow
  @[T().pow(k)]


Run

this causes dispatch to be delayed until instantiation. 


Calling same-named-function from abstruct object

2020-09-27 Thread chaemon
Thanks! I should learn mixin statement and open and closed symbol. Do you refer 
to the following?



I read it several time but I couldn't understand what "open symbol" is. 


Calling same-named-function from abstruct object

2020-09-27 Thread shirleyquirk
open means a symbol can refer to something that didn't exist at the time the 
symbol was defined

in your case, `Modint` doesn't exist within formalpowerseries.nim, and `pow` 
can only refer to the `pow` in that file, that's the "context at definition"

when we make `pow` an open symbol, it also takes into account the "context at 
instantiation", i.e. within test.nim, where `Modint` and `pow(Modint,int)` 
exist.


using db_odbc with ms sql server on windows 10

2020-09-27 Thread shirleyquirk
you could try editing that line in your local db_odbc.nim to accept 
SUCCESS_WITH_INFO and/or give you more error info on failure. 


if (res and not 1)!=0: dbError("Error: unable to initialise ODBC 
enviroment.")
#or
#if not (res in [SQL_SUCCESS,SQL_SUCCESS_WITH_INFO]):


Run

how to get the error code out is with 
[SqlGetDiagRec](https://docs.microsoft.com/en-us/sql/odbc/reference/syntax/sqlgetdiagrec-function?view=sql-server-ver15)
 but god that looks like actual work. 


using db_odbc with ms sql server on windows 10

2020-09-27 Thread sdmcallister
I downloaded and installed (full install including the sdk): Download Microsoft 
ODBC Driver 17 for SQL Server (x64) I tried also installing older versions but 
still received the same error.

I've also tried the odbc nim library. 


import odbc

var
  con = newODBCConnection()
con.driver = "SQL Server Native Client 11.0"
con.host = "x.xx.xx.xxx"
con.database = "x"
con.integratedSecurity = false
con.userName = "xxx"
con.password = "xxx"

if not con.connect:
  echo "Could not connect to database."


Run

With this library I see:


src\gitlab.com\nim-sqlserver\odbc\odbc\odbchandles.nim(44, 35) Error: type 
mismatch: got 
but expected one of:
proc SQLSetEnvAttr(EnvironmentHandle: SqlHEnv; Attribute: TSqlInteger;
  Value: SqlPointer; StringLength: TSqlInteger): 
TSqlSmallInt
  first type mismatch at position: 3
  required type for Value: SqlPointer
  but expression 'odbcVersion' is of type: TSqlInteger

expression: SQLSetEnvAttr(envHandle, TSqlInteger(200), odbcVersion, 0)


Run


using db_odbc with ms sql server on windows 10

2020-09-27 Thread shirleyquirk
I don't see how that call could ever have compiled, but i suppose it must have. 
there's an [issue`](https://github.com/coffeepots/odbc/issues/18) submitted. 
I'd stick with the version in the stdlib.


Is there a concept like "equality of refs" in Nim?

2020-09-27 Thread jiyinyiyong
JavaScript trick: `===` can be used to detect two object "a" and "b" if there 
are pointed to the same object. An object in JavaScript is kind like `ref 
object` in nim and every data mutation directly to `a` can be accessed from `b` 
when they are `===` equal. It's much faster to just compare `a === b` to know 
they are identical than comparing every properties.

Suppose in Nim, I have a type:


type A = ref object
  x: int

let a = A(x: 1)

let b = a

echo a == b

echo a.unsafeAddr.repr
echo b.unsafeAddr.repr


Run

when it compares with `==`, it compares values and returns `true`. But their 
pointers are different:


true
ptr 0x10fbabc28 --> ref 0x10fbd1048 --> [x = 1]

ptr 0x10fbabc30 --> ref 0x10fbd1048 --> [x = 1]



Run

Since we learnt the trick of JavaScript, and noticed that both `a` and `b` 
refers to the ref `ref 0x10fbd1048`. Can I skip value comparing and just figure 
out that they are the same ref?


Is there a concept like "equality of refs" in Nim?

2020-09-27 Thread ElegantBeef
You did sorta allude to a solution that works for atleast the C backend. 
Although I'd argue you would want to use an alternative operator or properly 
implement this into a smarter way. 


type A = ref object
  x: int

let a = A(x: 1)

let b = a

proc `==`(a, b: A): bool = a.unsafeAddr == b.unsafeAddr

echo a == b

echo a.unsafeAddr.repr
echo b.unsafeAddr.repr


Run


Is there a concept like "equality of refs" in Nim?

2020-09-27 Thread jiyinyiyong
I was not sure if I could comparing pointers directly, they seen to have 
diffreret addreses.


a.unsafeAddr == b.unsafeAddr


Run

I need to try again when back to keyboard...


Is there a concept like "equality of refs" in Nim?

2020-09-27 Thread ElegantBeef
Yea sorry you're right, dereferencing the variable gives the right address. As 
the console output shows it's a pointer to a pointer. `ptr 0x55a7f3cb0d20 --> 
ref 0x7f39004f2048 --> [x = 1]`


Is there a concept like "equality of refs" in Nim?

2020-09-27 Thread timothee
a.unsafeAddr is not what you want here, instead: 


cast[pointer](a) == cast[pointer](b)


Run


Is there a concept like "equality of refs" in Nim?

2020-09-27 Thread jiyinyiyong
looks neat. Thanks.


Is there a concept like "equality of refs" in Nim?

2020-09-27 Thread mratsim
ref have reference semantics, meaning 2 refs are only equal if their 
reference/pointer are equal.

2 refs having the same content do not mean they are equal.

In short `==` does what you want, no need to cast to a pointer. This is one of 
the main reason to use reference semantics after all. I.e. 2 persons having 2 
arms and 2 legs do not mean they are the same person or 2 memory locations 
having the same size and all zeros do not mean they are the same.