Closed porky11 closed 7 years ago
On Sat, Sep 10, 2016 at 06:17:26AM -0700, Fabio Krapohl wrote:
I'd like to write something like this:
(def x (var auto (Array int 2) (array 1 2)))
instead of:
(def x (var auto (Array int 2))) (setf ($@ x 0) 1) ;…
Can this be done by overloading
setf-move-init
orsetf-copy-init
?
It can be done that way, but those functions are generally only needed for specialised copy/move behaviour (e.g. UniquePtr). In the current case, a retval function can be used instead. For example:
(import cstdio)
(import array)
(std.concepts.instantiate Array int 2)
(def array (fn intern (retval (Array int 2)) ((a int) (b int))
(setf ($ (@ retval) 0) a)
(setf ($ (@ retval) 1) b)
(return)))
(def main (fn extern-c int (void)
(def x (var auto (Array int 2) (array 1 2)))
(printf "%d %d\n" (@$ x 0) (@$ x 1))
(setv x (array 2 1))
(printf "%d %d\n" (@$ x 0) (@$ x 1))
0))
(def x (var auto T))
calls
init
with new instance of T as argument when defined and(def x (var auto T val))
calls
setf-move-init
orsetf-copy-init
with new instance of T and val as arguments by default and is the same as(def x (var auto T)) (setf x val)
and init won't be called in this case did I get it right?
Yes, except for a couple of things. 'setf-move-init' is only called when 'val' is an rvalue reference, so it's not applicable here. Also, in the second case, 'setf-copy-assign' is used instead of 'setf-copy-init', because x will already be initialised due to the implicit call to 'init'. For example:
(import cstdio)
(import array)
(def mys (struct intern ((a int) (b int))))
(def init (fn intern bool ((dst (ref mys)))
(printf "Called init\n")
(setf (:@ dst a) 1)
(setf (:@ dst b) 2)
true))
(def setf-copy-init (fn intern bool ((dst (p mys)) (src (p mys)))
(printf "Called setf-copy-init\n")
(memcpy (cast dst (p void)) (cast src (p void)) (sizeof mys))
true))
(def setf-copy-assign (fn intern bool ((dst (p mys)) (src (p mys)))
(printf "Called setf-copy-assign\n")
(memcpy (cast dst (p void)) (cast src (p void)) (sizeof mys))
true))
(def main (fn extern-c int (void)
(def x (var auto mys))
(printf "After init\n")
(def y (var auto mys x))
(printf "After setf-copy-init\n")
(setv x y)
(printf "After setf-copy-assign\n")
0))
yields:
Called init
After init
Called setf-copy-init
After setf-copy-init
Called setf-copy-assign
After setf-copy-assign
but initialising with other types or even using macros doesn't seem possible this way, so how should this be implemented then?
The various 'setf' operations can be overloaded on the second argument, which allows for initialisation with other types. Macros for the 'setf' operations are not supported, mainly because I haven't seen a use case that couldn't be met by way of the current mechanisms.
I think the built-in macro-like initialization-forms for structs and arrays, and overloading really seems to be enough, and when I want macros, i use macros just for the value. Maybe macros could be used instead of the default initialization forms, too. They seem a bit unclean to me.
this can be done by macros. also see #139
I'd like to write something like this:
instead of:
Can this be done by overloading
setf-move-init
orsetf-copy-init
?calls
init
with new instance of T as argument when defined andcalls
setf-move-init
orsetf-copy-init
with new instance of T and val as arguments by default and is the same asand init won't be called in this case did I get it right?
but initialising with other types or even using macros doesn't seem possible this way, so how should this be implemented then?