tomhrr / dale

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

Type `size` seems not useful #112

Closed porky11 closed 8 years ago

porky11 commented 8 years ago

in a function-call I sometimes have to cast every number to size (example (fread (cast buf (p void)) (cast 1 size) (cast 321 size) file))

tomhrr commented 8 years ago

On Sun, Sep 18, 2016 at 04:29:01PM -0700, Fabio Krapohl wrote:

in a function-call I sometimes have to cast every number to size (example (fread (cast buf (p void)) (cast 1 size) (cast 321 size) file))

Integral arguments to 'extern-c' functions are implicitly cast, where possible. The only cast that should be required is that of the pointer:

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

(def main (fn extern-c int (void)
  (def x (var auto (p file) (fopen "/dev/urandom" "r")))
  (def y (var auto (array-of 2 char)))
  (fread (cast y (p void)) 1 2 x)
  (printf "%d %d\n" (@$ y 0) (@$ y 1))
  0))
user@host:~$ ./dalec test.dt
user@host:~$ ./a.out
104 -102
user@host:~$
porky11 commented 8 years ago

no, normally I have to cast number types explicitely, else method selection wouldn't work correctly, also if I have (+ x 0.0) it only works, if x is float.

tomhrr commented 8 years ago

On Mon, Sep 26, 2016 at 04:56:39AM -0700, Fabio Krapohl wrote:

no, normally I have to cast number types explicitely, else method selection wouldn't work correctly,

That should only be the case for procedures with 'intern' or 'extern' linkage, rather than 'extern-c' linkage.

also if I have (+ x 0.0) it only works, if x is float.

The 'prime' functions (e.g. +') will work for this case. In general, I'm much more in favour of adding extra macros or functions to handle casting inconvenience, rather than adding implicit language-level casting. 'extern-c' is an exception to that, since casting there doesn't lead to any potential ambiguity/confusion.

porky11 commented 8 years ago

I also thought about something like searching for a matching function if there are multiple implementations for a function, and use the most specific, if onle value may be used for multiple types, and select one, if only one is possible (so (+ x 1.0) would see x as type t and 1.0 as something that can be any floating-point type, (this could also work for structs, where ((a 1)) could be any struct)) So this should be implemented as macro too, I think. Something else: Would it be preferable to implement overloading as dale-macro, so that all functions are extern-c by default, and all macros are untyped by default, and overloading would be implemented as a module?

tomhrr commented 8 years ago

On Tue, Sep 27, 2016 at 09:14:13AM -0700, Fabio Krapohl wrote:

I also thought about something like searching for a matching function if there are multiple implementations for a function, and use the most specific, if onle value may be used for multiple types, and select one, if only one is possible (so (+ x 1.0) would see x as type t and 1.0 as something that can be any floating-point type, (this could also work for structs, where ((a 1)) could be any struct)) So this should be implemented as macro too, I think.

This sounds like a reasonable approach.

Something else: Would it be preferable to implement overloading as dale-macro, so that all functions are extern-c by default, and all macros are untyped by default, and overloading would be implemented as a module?

This is an interesting idea, and perfectly possible to do, but quite time-consuming. The benefits would be limited to making the core more elegant, too (not that that's unimportant). If this were being written again from the start, though, I would probably go with your idea.

porky11 commented 8 years ago

Yes, seems too time consuming, since the overloaded versions would be used anyway most of the time, I think, and only the core would get smaller. The only benefit as user may be the ability to change how the dispatch works, wich already is possible, but you can't exclude the default dispatch