00:07:26 | * | lxdong joined #nim |
00:09:37 | * | [CBR]Unspoken joined #nim |
00:09:41 | * | castan joined #nim |
00:12:00 | * | toaoMgeorge joined #nim |
00:17:12 | * | sora quit (Ping timeout: 276 seconds) |
00:17:17 | * | toaoMgeorge quit (Quit: Bye) |
00:27:36 | dom96 | ldlework: problem with introducing new keywords is that it will always break some code out there |
00:27:42 | dom96 | it's better to start with a pragm |
00:27:43 | dom96 | a |
00:27:45 | * | Jesin quit (Quit: Leaving) |
00:29:46 | * | Jesin joined #nim |
00:33:18 | * | filwit joined #nim |
00:41:08 | * | PMunch quit (Ping timeout: 250 seconds) |
00:43:03 | * | darkf joined #nim |
00:55:54 | * | lxdong quit (Ping timeout: 252 seconds) |
01:02:01 | * | Demon_Fox joined #nim |
01:02:30 | * | castan quit (Ping timeout: 252 seconds) |
01:02:42 | * | [CBR]Unspoken quit (Ping timeout: 276 seconds) |
01:07:34 | * | jaco60 quit (Ping timeout: 250 seconds) |
01:10:14 | * | darkf_ joined #nim |
01:13:45 | * | darkf quit (Ping timeout: 276 seconds) |
01:16:05 | * | endragor joined #nim |
01:18:32 | * | [CBR]Unspoken joined #nim |
01:18:42 | * | darkf_ is now known as darkf |
01:19:54 | * | endragor quit (Remote host closed the connection) |
01:20:12 | * | endragor joined #nim |
01:20:28 | * | endragor quit (Remote host closed the connection) |
01:36:48 | * | endragor joined #nim |
01:46:38 | * | endragor quit (Remote host closed the connection) |
01:49:17 | * | endragor joined #nim |
01:49:57 | * | Sys joined #nim |
01:50:25 | * | francisl joined #nim |
01:53:17 | * | tyu joined #nim |
02:25:21 | * | lxdong joined #nim |
02:26:28 | * | space-wizard quit (Quit: My Mac has gone to sleep. ZZZzzz…) |
02:26:47 | * | bbl_ quit (Ping timeout: 268 seconds) |
02:31:15 | * | desophos joined #nim |
02:41:50 | onionhammer | o how do I go about using araqs new GC? |
02:45:55 | * | zxtx quit (Read error: Connection reset by peer) |
02:46:36 | * | zxtx joined #nim |
03:04:00 | * | space-wizard joined #nim |
03:04:58 | * | lxdong quit (Ping timeout: 252 seconds) |
03:18:35 | * | brson quit (Quit: leaving) |
03:22:18 | * | adbyte joined #nim |
03:47:40 | * | lxdong joined #nim |
03:53:30 | * | adbyte quit (Quit: Lost terminal) |
03:53:35 | * | pandey joined #nim |
03:56:13 | Demon_Fox | For some reason I can't but help think nim is slightly more memory managed than C++ |
03:57:52 | * | tyu quit (Quit: Connection closed for inactivity) |
03:59:30 | * | pandey quit (Quit: Page closed) |
04:16:11 | * | francisl quit (Quit: francisl) |
04:30:34 | * | darkf_ joined #nim |
04:32:39 | * | darkf quit (Ping timeout: 276 seconds) |
04:33:38 | * | darkf_ is now known as darkf |
04:40:38 | * | bozaloshtsh joined #nim |
04:45:31 | * | desophos quit (Read error: Connection reset by peer) |
06:22:59 | * | endragor_ joined #nim |
06:26:43 | * | endragor quit (Ping timeout: 248 seconds) |
06:45:45 | * | endragor_ quit (Remote host closed the connection) |
06:46:13 | * | endragor joined #nim |
06:51:03 | * | filwit quit (Quit: Leaving) |
06:52:20 | * | endragor_ joined #nim |
06:55:36 | * | endragor quit (Ping timeout: 246 seconds) |
07:01:02 | * | bjz joined #nim |
07:04:11 | * | endragor_ quit (Remote host closed the connection) |
07:15:34 | * | Sys quit (Quit: Page closed) |
07:17:42 | * | Kingsquee quit (Quit: https://i.imgur.com/qicT3GK.gif) |
07:19:33 | * | endragor joined #nim |
07:19:34 | * | endragor quit (Remote host closed the connection) |
07:20:02 | * | endragor joined #nim |
07:32:40 | * | endragor quit (Remote host closed the connection) |
07:58:44 | * | zepolen quit (Remote host closed the connection) |
08:00:10 | * | vendethiel- joined #nim |
08:01:50 | * | vendethiel quit (Ping timeout: 250 seconds) |
08:03:09 | * | mog quit (Ping timeout: 260 seconds) |
08:04:01 | * | yglukhov joined #nim |
08:07:50 | * | lxdong quit (Ping timeout: 252 seconds) |
08:07:56 | * | mog joined #nim |
08:12:18 | * | Trustable joined #nim |
08:22:06 | * | yglukhov quit (Ping timeout: 276 seconds) |
08:27:58 | * | zepolen joined #nim |
08:32:10 | * | zepolen quit (Ping timeout: 250 seconds) |
08:33:25 | * | endragor joined #nim |
08:34:07 | * | miko__ joined #nim |
08:34:08 | * | ics quit (Quit: Connection closed for inactivity) |
08:36:55 | * | space-wizard quit (Quit: My Mac has gone to sleep. ZZZzzz…) |
08:38:26 | * | zepolen joined #nim |
08:38:53 | * | endragor quit (Ping timeout: 248 seconds) |
08:48:18 | * | yglukhov joined #nim |
08:58:41 | * | Demon_Fox quit (Quit: Leaving) |
09:21:49 | vegansk | Hi to all! |
09:23:11 | vegansk | Is there any way to remove the effect? For example, I want to write a stack trace before some place in the code, that leads to crash is executed. But the calling function must be {.noSideEffects.} |
09:23:45 | * | endragor joined #nim |
09:27:44 | * | vendethiel joined #nim |
09:28:32 | * | vendethiel- quit (Ping timeout: 260 seconds) |
09:30:05 | flyx | vegansk: you can use http://nim-lang.org/docs/system.html#debugEcho |
09:31:47 | * | sorakun joined #nim |
09:33:35 | vegansk | flyx, thanks! |
09:41:04 | * | bjz_ joined #nim |
09:42:23 | * | bjz quit (Ping timeout: 250 seconds) |
09:56:51 | * | sorakun quit (Ping timeout: 248 seconds) |
10:12:45 | * | vendethiel quit (Ping timeout: 248 seconds) |
10:13:31 | * | vendethiel joined #nim |
11:52:51 | * | toaoMgeorge joined #nim |
11:53:37 | * | vendethiel- joined #nim |
11:54:39 | * | vendethiel quit (Ping timeout: 276 seconds) |
12:00:21 | vegansk | Araq, I found the reason, why threads works with mingw only when ``--tlsEmulation:on`` is used. https://github.com/nim-lang/Nim/pull/3921 |
12:03:29 | * | lxdong joined #nim |
12:05:50 | * | sora joined #nim |
12:05:52 | * | sora quit (Read error: Connection reset by peer) |
12:09:29 | * | sora joined #nim |
12:09:59 | * | sora quit (Read error: Connection reset by peer) |
12:12:27 | * | vendethiel- quit (Ping timeout: 260 seconds) |
12:13:03 | * | sora joined #nim |
12:13:24 | * | vendethiel joined #nim |
12:13:32 | * | sora quit (Read error: Connection reset by peer) |
12:15:31 | * | sora joined #nim |
12:18:34 | * | arnetheduck joined #nim |
12:23:55 | * | polde joined #nim |
12:34:21 | * | vendethiel- joined #nim |
12:34:37 | * | vendethiel quit (Ping timeout: 260 seconds) |
12:49:14 | cheatfate | vegansk, nice, but how did you find it? |
12:56:24 | * | lxdong quit (Ping timeout: 252 seconds) |
12:59:45 | * | PMunch joined #nim |
13:00:05 | PMunch | Hi, I'm having some trouble getting Nimble to work |
13:02:35 | * | yglukhov quit (Ping timeout: 250 seconds) |
13:04:34 | PMunch | I've got nim installed through the Manjaro repositories and tried to get nimble from there as well. However when I went to create a new project I got this: http://pastebin.com/yWBMJBVf |
13:30:13 | * | ics joined #nim |
13:37:40 | dom96 | PMunch: Sounds like Manjaro installs Nimble incorrectly |
13:37:51 | dom96 | try installing it manually |
13:37:54 | PMunch | Sounds like it, yes |
13:37:59 | PMunch | I'm trying that now |
13:38:09 | PMunch | Just did all Nims install commands in /tmp |
13:38:40 | PMunch | And the instructions tells me to add it to my path |
13:38:47 | PMunch | But add what? |
13:40:03 | PMunch | The entire Nim directory? That still includes all the sources.. |
13:43:44 | PMunch | Tried to copy the nim binary in /tmp/Nim/bin to /usr/bin and the contents of /tmp/Nim/lib to /usr/lib/nim |
13:44:30 | PMunch | It seems to work but when I run nim e /tmp/Nim/install_nimble.nims I only get the error: install_nimble.nims(2, 8) Error: cannot open 'ospaths' |
13:46:46 | r-ku | PMunch add Nim/bin dir to PATH |
13:47:04 | r-ku | it wont work if you move it elsewhere |
13:47:13 | PMunch | Hmm |
13:48:06 | PMunch | Thing is I did this in /tmp which gets deleted once I restart. I assumed it would add it's binaries to my path properly |
13:48:32 | r-ku | just move Nim folder out of /tmp, i dont see a problem |
13:49:01 | r-ku | and adding /tmp to PATH isnt best idea in general |
13:49:47 | r-ku | also its advised to not install Nim into standard dirs at all. best is to just check out repo, build it and add bin dir to PATH and thats all. works great |
13:52:26 | PMunch | So I have to move it out of /tmp and rebuild? |
13:56:34 | dom96 | You don't have to rebuild |
13:57:23 | dom96 | as long as you've already built it in /tmp |
13:59:05 | dom96 | Following the steps here: https://github.com/nim-lang/Nim#compiling |
13:59:13 | dom96 | is generally the best way to get a reliable Nim working |
14:00:25 | PMunch | That's what I tried to do |
14:00:57 | PMunch | But instead of setting the directory I tried to move the binary |
14:01:57 | PMunch | Now I'm getting: lib/nim/system.nim(284, 5) Error: type expected. [NimbleError] |
14:02:06 | * | yglukhov joined #nim |
14:02:57 | * | sora quit (Ping timeout: 246 seconds) |
14:08:25 | PMunch | nvm, fixedit |
14:08:35 | * | yglukhov quit (Ping timeout: 248 seconds) |
14:28:06 | * | endragor_ joined #nim |
14:30:23 | * | yglukhov joined #nim |
14:30:41 | * | Sys_ joined #nim |
14:30:58 | * | endragor quit (Ping timeout: 250 seconds) |
14:30:59 | * | yglukhov quit (Read error: Connection reset by peer) |
14:31:12 | * | yglukhov joined #nim |
14:33:15 | * | endragor_ quit (Ping timeout: 276 seconds) |
14:50:35 | * | pregressive joined #nim |
14:55:26 | * | Kingsquee joined #nim |
14:58:30 | vegansk | cheatfate, I created minimal example and then examined generated code :-) |
14:59:43 | PMunch | Does fmReadWrite clear existing files if they exist? |
15:00:51 | * | arnetheduck quit (Ping timeout: 248 seconds) |
15:04:56 | * | pregressive quit (Remote host closed the connection) |
15:09:33 | Sys_ | dom96: Are you here? |
15:09:54 | dom96 | yes |
15:10:49 | Sys_ | dom96: Sorry, never mind. Chapter 3 listing 3.3 I thought you specified paramCount() == 6: ... which didn't make sense. But it's just the horrible font formatting that Fedora has that makes it look like that. >_> |
15:11:38 | dom96 | I see :) |
15:16:22 | * | pregressive joined #nim |
15:29:03 | wuehlmaus | hmm, noone asked the question of PMunch if fmReadWrite clared existing files. i cannot imagne that but i am not experienced enough. |
15:29:11 | wuehlmaus | cleared |
15:29:21 | PMunch | It seems to |
15:30:02 | PMunch | I created a file with some content and tried to open it with fmReadWrite and then the file was empty.. |
15:39:30 | wuehlmaus | PMunch: to learn about nim rosettacode was quite useful to me. there are many examples there. |
15:39:51 | PMunch | Good tip wuehlmaus |
15:40:09 | PMunch | Do you know by the way how I can write a thin wrapper for a distinct type? |
15:41:21 | PMunch | I've made a distinct type Config for the type JsonNode but now I want to write a function that adds a key to the config, but for this I need to be able to access the JsonNode functions |
15:45:29 | dom96 | PMunch: You can just convert the type to a JsonNode: config.JsonNode |
15:47:10 | PMunch | I tried but it doesn't seem to work |
15:47:35 | PMunch | http://pastebin.com/WWGseFhg |
15:47:38 | PMunch | Thats what I got |
15:48:08 | dom96 | $(conf.JsonNode)? |
15:49:59 | PMunch | Same thing |
15:50:39 | dom96 | can you gist your code? |
15:51:01 | PMunch | Sure |
15:52:02 | PMunch | https://gist.github.com/PMunch/66884dce08a7a31600c0 |
15:52:05 | PMunch | There you go |
15:52:13 | PMunch | Problem is all in the first 10 lines |
15:53:17 | PMunch | Or rather first 11 |
15:53:21 | Sys_ | Is there a built in function to find a string within a string? Ex: s = "TATAUUUUUG" and t = "TATA" |
15:53:35 | dom96 | PMunch: take a look at the error, it's happening on line 41: https://gist.github.com/PMunch/66884dce08a7a31600c0#file-fronter-nim-L41 |
15:54:02 | dom96 | change that to echo config.JsonNode and it should work |
15:54:15 | PMunch | Ohhhh |
15:54:25 | * | nkr quit (Remote host closed the connection) |
15:54:25 | PMunch | That makes sense, silly me |
15:54:40 | dom96 | Sys_: http://nim-lang.org/docs/strutils.html#find,string,char,Natural |
15:55:18 | Sys_ | Weird, find wasnt in the index when I searched hmm |
15:59:18 | PMunch | What would I have to borrow from JsonNode to let my Config type print? |
15:59:25 | * | derka joined #nim |
15:59:34 | derka | Hi Guys |
16:00:28 | Sys_ | derka: Hey |
16:02:23 | dom96 | PMunch: proc `$`(c: Config) {.borrow.} should work |
16:03:40 | PMunch | Hmm, that gave me: SIGSEGV: Illegal storage access. (Attempt to read from nil?) |
16:05:39 | dom96 | from the compiler? |
16:05:42 | dom96 | if so then that's a bug |
16:05:46 | PMunch | it worked when I added the return type :string |
16:05:58 | dom96 | oh yeah |
16:05:58 | PMunch | So: proc `$`(c: Config):string {.borrow.} |
16:05:59 | dom96 | my bad |
16:06:11 | PMunch | Cryptic error message though |
16:07:31 | * | PMunch quit (Quit: leaving) |
16:08:30 | dom96 | That means the compiler crashed |
16:08:39 | dom96 | so please report it on github |
16:15:58 | * | Kingsquee quit (Read error: Connection reset by peer) |
16:16:31 | * | Kingsquee joined #nim |
16:19:56 | * | aziz joined #nim |
16:21:03 | * | pregressive quit (Remote host closed the connection) |
16:28:09 | * | krux02 joined #nim |
16:28:38 | krux02 | what does this error mean? "system.nim(2169, 16) Error: VM is not allowed to 'cast'" |
16:29:34 | * | darkf_ joined #nim |
16:29:53 | * | darkf quit (Disconnected by services) |
16:29:55 | * | darkf_ is now known as darkf |
16:31:33 | Sys_ | find(s, t) returns the index of the first occurence where t is found in s. How do I loop this so that it finds all the indexes where t is found in s? I've tried a variety of ways, but can't seem to make it work. |
16:37:01 | krux02 | darkf: just loop over the collection, and put an if in the beginning |
16:42:16 | Sys_ | krux02: Mind taking a look at a ghist? |
16:42:27 | Sys_ | I'm pretty sure i'm just missing the for loop, but can't get it right |
16:45:35 | * | thotypous quit (Quit: WeeChat 1.4) |
16:52:25 | * | filcuc joined #nim |
16:53:14 | * | sorakun joined #nim |
17:09:51 | * | filcuc quit (Read error: Connection reset by peer) |
17:09:57 | * | space-wizard joined #nim |
17:10:43 | * | space-wizard quit (Max SendQ exceeded) |
17:11:04 | * | nkr joined #nim |
17:12:16 | * | space-wizard joined #nim |
17:13:01 | * | ddmgy joined #nim |
17:13:01 | * | yglukhov quit (Ping timeout: 248 seconds) |
17:14:43 | * | ddmgy quit (Client Quit) |
17:15:38 | * | ddmgy joined #nim |
17:17:33 | * | darkf quit (Quit: Leaving) |
17:18:18 | ddmgy | Sys_: https://gist.github.com/ddmgy/f5ed9245127572587f65 |
17:19:01 | ddmgy | Sys_: find has a third argument start, which is the beginning index of the search. |
17:19:38 | Sys_ | ddmgy: thank you very much |
17:19:58 | ddmgy | No problem. |
17:21:01 | def- | krux02: cast is a reinterpretation of the bit pattern. it's implemented as a C cast and not available in the VM. Instead you can do a normal type conversion |
17:32:33 | * | pregressive joined #nim |
17:35:20 | * | ddmgy quit (Quit: Quit) |
17:40:06 | * | thotypous joined #nim |
17:52:55 | * | pregressive quit (Read error: Connection reset by peer) |
17:53:24 | * | pregressive joined #nim |
18:01:28 | * | brson joined #nim |
18:04:11 | * | Demon_Fox joined #nim |
18:04:46 | krux02 | def-: using binary search (adding echo until the location of the error is detected), I found out that I was not allowed to check weather a seq was nil. |
18:05:55 | * | yglukhov joined #nim |
18:06:08 | * | Gonzih quit (Quit: WeeChat 1.3) |
18:07:42 | * | yglukhov quit (Remote host closed the connection) |
18:07:57 | * | yglukhov joined #nim |
18:08:38 | * | zepolen quit (Remote host closed the connection) |
18:08:45 | def- | krux02: huh? isNil doesn't work or what? |
18:09:42 | krux02 | def-: I used '!= nil' |
18:10:17 | krux02 | def-: I guess that was wrong, but the error didn't give me any information at all, it didn't even tell, where the error was |
18:11:11 | def- | strange, but isNil should work |
18:11:48 | krux02 | I just removed the if != nil part, because I knew that it couldn't be nil there |
18:11:49 | krux02 | it works |
18:21:33 | * | space-wizard quit (Read error: Connection reset by peer) |
18:21:43 | * | space-wi_ joined #nim |
18:30:01 | * | OnO_ joined #nim |
18:31:14 | * | clone1018_ joined #nim |
18:32:08 | * | JStoker quit (Killed (wolfe.freenode.net (Nickname regained by services))) |
18:32:29 | * | JStoker joined #nim |
18:33:56 | * | samdoran joined #nim |
18:35:42 | * | Matthias247 joined #nim |
18:37:28 | * | clone1018 quit (Ping timeout: 264 seconds) |
18:37:28 | * | OnO quit (Ping timeout: 264 seconds) |
18:38:07 | * | clone1018_ is now known as clone1018 |
18:39:02 | * | sarlalian quit (Quit: WeeChat 0.4.2) |
18:39:44 | * | sarlalian joined #nim |
18:40:05 | * | sarlalian quit (Remote host closed the connection) |
18:40:20 | * | samdoran quit (Ping timeout: 252 seconds) |
18:46:25 | * | gunn_ joined #nim |
18:48:31 | * | asdf quit (Ping timeout: 268 seconds) |
18:49:08 | * | gunn quit (Ping timeout: 268 seconds) |
18:49:45 | * | GangstaCat quit (Ping timeout: 268 seconds) |
18:49:51 | * | asdf joined #nim |
18:50:16 | * | asdf is now known as Guest59586 |
18:51:30 | * | Guest59586 is now known as asdf |
18:51:55 | * | GangstaCat joined #nim |
18:53:37 | * | zxtx quit (Ping timeout: 240 seconds) |
18:57:35 | * | zxtx joined #nim |
18:59:37 | * | vegansk quit (Ping timeout: 268 seconds) |
19:00:01 | * | vegansk joined #nim |
19:01:27 | * | yglukhov quit (Remote host closed the connection) |
19:05:51 | * | yglukhov joined #nim |
19:07:33 | * | boopsiesisaway quit (Ping timeout: 276 seconds) |
19:08:15 | * | def- quit (Ping timeout: 268 seconds) |
19:08:22 | * | def- joined #nim |
19:10:01 | * | sarlalian joined #nim |
19:10:37 | * | Sys_ quit (Quit: Page closed) |
19:15:31 | * | zepolen joined #nim |
19:18:48 | * | sarlalia1 joined #nim |
19:19:55 | * | boopsiesisaway joined #nim |
19:25:40 | * | zielmicha quit (*.net *.split) |
19:25:40 | * | mal`` quit (*.net *.split) |
19:25:41 | * | tstm quit (*.net *.split) |
19:30:35 | wuehlmaus | just out of curiosity, can nim give me ony the intermediate c files without compiling them? |
19:31:29 | * | zielmicha joined #nim |
19:31:29 | * | mal`` joined #nim |
19:31:29 | * | tstm joined #nim |
19:32:33 | wuehlmaus | s/ony/only/ |
19:34:19 | def- | wuehlmaus: yes |
19:34:48 | def- | with --compileOnly or -c |
19:37:02 | * | miko__ quit (Ping timeout: 248 seconds) |
19:38:26 | * | yglukhov quit (Remote host closed the connection) |
19:38:40 | wuehlmaus | ah, thank you |
19:46:49 | * | Demon_Fox quit (Quit: Leaving) |
19:57:09 | * | yglukhov joined #nim |
20:01:01 | * | derka quit (Ping timeout: 248 seconds) |
20:01:07 | * | boopsiesisaway quit (Ping timeout: 248 seconds) |
20:04:57 | * | derka joined #nim |
20:15:33 | * | mahasamoot joined #nim |
20:19:15 | * | Matthias247 quit (Read error: Connection reset by peer) |
20:19:42 | * | derka quit (Ping timeout: 276 seconds) |
20:21:01 | * | derka joined #nim |
20:22:41 | * | Sergio965 joined #nim |
20:23:45 | Sergio965 | Hi all! I've been reading through the tutorials and manual in search of a way to do something like Java's interfaces, Haskell's typeclasses, or Rust's traits. is there a way to do this in Nim? If not, what's the workaround? I'm hoping it's not inheritance. |
20:25:24 | Sergio965 | In particular, I want to get a sequence of generic Ts, and I want to know that all of the Ts have some function f() that I can call on them. |
20:27:18 | Sergio965 | Also, some list somewhere says that Nim supports "dependant types*", with an asterisk. What is that referring to? I presume it's talking about object variants, but I may be missing something. |
20:27:32 | ldlework | Sergio965: There are multimethods, and concepts. |
20:27:46 | ldlework | Have you tried just making a proc generic on T and calling the function on it? |
20:27:48 | * | Ven joined #nim |
20:28:06 | Sergio965 | How would it know that T has that function, Idlework? |
20:28:12 | ldlework | Nims generics are extremely flexible by default and you generally dont need to do anything special to call a function on T |
20:29:06 | * | derka quit (Quit: derka) |
20:29:18 | ldlework | Basically your usage of T within the generic function is what defines the typeclass so to speak. |
20:29:29 | ldlework | Sergio965: does that make sense? |
20:29:57 | Sergio965 | Sure. But that seems a bit restrictive. |
20:30:05 | ldlework | Er what? |
20:30:30 | Sergio965 | Well, presumably this sort of conformance checking needs to happen recursively down the function. |
20:31:02 | ldlework | Well if you pass a T value to a sub function then that function needs to be generic too |
20:31:03 | Sergio965 | IE, if generic function a calls b, and a uses some function set f1, f2, and b uses some function set f3, f4, Nim needs to know that T needs f1, f2, f3, f4. |
20:31:10 | ldlework | And then yes T will be the sum of everything |
20:31:44 | * | derka joined #nim |
20:32:01 | Sergio965 | I suppose what I'm saying is that you wouldn't be able to call b() in Haskell/Rust since T doesn't implement f3, f4. |
20:32:08 | Sergio965 | "restrictive" wasn't quite the right word. |
20:32:35 | * | Ven quit (Client Quit) |
20:32:38 | Sergio965 | That's interesting though. Ad-hoc typeclasses. |
20:34:33 | Sergio965 | Hmm, does Nim enforce that all f()'s for some T have the same type signature? |
20:34:40 | Sergio965 | Where can I read about this? |
20:35:10 | Sergio965 | I suppose I'm asking: Is the check: forall T. exists f, or, exists f, forall T |
20:35:18 | Sergio965 | *I suppose I'm asking: Is the check: forall T. exists f, or, exists f. forall T |
20:35:40 | * | derka quit (Client Quit) |
20:36:23 | ldlework | I have no idea what you're saying right now |
20:36:51 | ldlework | But seriously just write the fucntion and call a proc on the value and see if it works. |
20:38:32 | * | Guest95751 is now known as Vivek |
20:38:49 | * | Vivek quit (Changing host) |
20:38:49 | * | Vivek joined #nim |
20:44:14 | Sergio965 | Huh. That's crazy |
20:44:36 | * | boopsiesisaway joined #nim |
20:45:28 | * | derka joined #nim |
20:46:31 | ldlework | Sergio965: if there can be a deep introspected effects system, why not the same for generics :) |
20:47:04 | ldlework | Sergio965: apparently concepts dont work so well, but thats okay because they act more like constraints than extra information for the compiler |
20:47:25 | ldlework | I was originally confused too |
20:48:11 | Sergio965 | Thanks for the tip, ldlework. |
20:48:21 | Sergio965 | Any idea about the dependant type stuff? |
20:48:34 | ldlework | Sergio965: do you mean HKTs? |
20:48:45 | Sergio965 | Does Nim have HKTs? |
20:48:56 | ldlework | No |
20:49:02 | Sergio965 | Lol |
20:49:11 | ldlework | :( |
20:49:27 | Sergio965 | Well, the object variant stuff acts strangely. |
20:49:37 | Sergio965 | I ask because I read somewhere that Nim had "dependant types*". |
20:49:45 | Sergio965 | dependent* |
20:49:50 | ldlework | I guess I dont know the term |
20:49:57 | ldlework | Are you referring to the object variants? |
20:50:09 | ldlework | Those are basically just union types. |
20:50:19 | Sergio965 | I'm not, no. |
20:50:24 | Sergio965 | I don't know what I'm referring to. |
20:50:34 | Sergio965 | I simply read somewhere on a feature list of Nim "dependent types*" listed as a feature. |
20:50:40 | Sergio965 | And I was wondering what it was referring to. |
20:50:55 | ldlework | "In computer science and logic, a dependent type is a type whose definition depends on a value." |
20:51:02 | ldlework | I think you are refering to the object variants. |
20:51:06 | Sergio965 | Well, no. |
20:51:15 | Sergio965 | Dependent types are much stronger than that. |
20:51:34 | ldlework | ok? |
20:51:38 | Sergio965 | The general idea is that you can create functions of the form: f(V) -> U where V is the type of all values and U is the type of all types. |
20:51:51 | Sergio965 | And then, you can do things like: "a: f(v)". |
20:52:02 | Sergio965 | To say that a has type f(v) which depends on the value `v`. |
20:52:18 | Sergio965 | Is sort of the general idea behind dependent types. |
20:52:28 | ldlework | Well |
20:53:01 | ldlework | I don't know of anything related to "the type of a value being dependent on some other value" in Nim other than object variants. |
20:53:14 | ldlework | Which is what the variants are, precisely. |
20:53:41 | Sergio965 | Sure, which is what I guessed it was referring to. |
20:53:46 | ldlework | Maybe someone was using the term dependent types loosely. |
20:53:49 | Sergio965 | See http://docs.idris-lang.org/en/latest/tutorial/typesfuns.html#dependent-types for a full description. |
20:54:02 | * | sarlalian quit (Quit: ZNC 1.6.1 - http://znc.in) |
20:54:04 | Sergio965 | Indeed, ldlework. They did take care to use an asterisk: "depedent types*". |
20:54:10 | Sergio965 | dependent |
20:54:15 | ldlework | Ah yeah nim doesn't have anything like this |
20:54:26 | Sergio965 | Oh, here it is: https://github.com/nim-lang/Nim/wiki/Nim-for-C-programmers |
20:54:29 | ldlework | in fact, the type of types, typedesc is super buggy in Nim |
20:54:40 | Sergio965 | "Partial support", it says. |
20:55:45 | ldlework | Sergio965: http://forum.nim-lang.org/t/436 |
20:56:18 | Sergio965 | Oh, hmm "static types". |
20:56:42 | Sergio965 | "static types, which allows any generic type to be dependent on a value" Where is that? |
20:57:15 | ldlework | The manual. |
20:57:31 | Sergio965 | I don't understand. Is that just a regular static type, or is there some overloading going on here? |
20:57:38 | Sergio965 | Is he just referring to type inference?... |
20:58:01 | * | space-wi_ quit (Quit: My Mac has gone to sleep. ZZZzzz…) |
20:58:05 | Sergio965 | (word overloading) |
20:58:11 | ldlework | http://nim-lang.org/docs/manual.html#special-types |
20:58:21 | ldlework | If you supply static[int] as a parameter type |
20:58:32 | ldlework | you get different implementations based on the compile-time value passed to the proc |
20:58:37 | * | space-wizard joined #nim |
20:58:44 | ldlework | Or as used as the type of a struct field or whatever |
21:00:38 | Sergio965 | Does the `re` function run at compile-time? |
21:01:06 | Sergio965 | Or, more precisely, the manual says that the regex is precompiled, presumably at compile-time. What causes this to happen? |
21:01:21 | Sergio965 | In the static[string] example. |
21:03:06 | ldlework | I assume because the static string, which is a compile time value, is passed to re() |
21:03:14 | ldlework | which means that re() is evaluated at compile time |
21:03:28 | ldlework | Since Nim's compiler features a VM and can compile and execute arbitrary code at compile time |
21:03:44 | ldlework | the Nim compiler realize you've passed a static value to re() and so evaluates the call at compile time |
21:04:07 | Sergio965 | Right, but I thought that only happened when you used `const`? |
21:04:21 | ldlework | static[] is exactly the same kind of thing |
21:04:34 | ldlework | Except that it accepts multiple values |
21:04:38 | ldlework | rather than a single constant value |
21:04:47 | ldlework | That's why you can call this multiple times with different strings |
21:04:57 | ldlework | rather than only producing a single constant regular expression |
21:05:24 | Sergio965 | So what's the difference between using static[] and createing a template that uses const inside? |
21:05:38 | ldlework | What |
21:05:49 | ldlework | I literally just explained. |
21:06:00 | * | cheatfate quit (Quit: Leaving) |
21:06:09 | Sergio965 | Uh?...Why can't you do that with a templat? |
21:06:13 | Sergio965 | template* |
21:06:14 | ldlework | If you use a template, you're generating multiple const expressions. |
21:06:20 | ldlework | You're not using a single const expression. |
21:06:58 | Sergio965 | Oh, for the same constant value, you're saying? |
21:07:03 | Sergio965 | IE, for the same string? |
21:07:24 | ldlework | Well no, the template is likely parametric, so you can generate different const expressions, so you get different regular expressions. |
21:08:16 | ldlework | If you were asking if you could get the same behavior that way, then yes. |
21:08:24 | ldlework | But without having to write a template, and just writing normal Nim code. |
21:08:31 | ldlework | And the compiler will take care of the expansion for you. |
21:08:44 | Sergio965 | Yes, I was asking that. |
21:09:00 | ldlework | So I guess that's your dependent type. |
21:09:06 | ldlework | type D = object |
21:09:12 | ldlework | size: static[int] |
21:09:20 | ldlework | Now you can have a D(1) or D(2), etc |
21:09:36 | * | derka quit (Ping timeout: 246 seconds) |
21:10:05 | * | space-wizard quit (Quit: My Mac has gone to sleep. ZZZzzz…) |
21:10:07 | Sergio965 | Yeah. |
21:11:00 | * | derka joined #nim |
21:11:32 | ldlework | It'd be cool if Araq wrote more about control-flow dependent typing |
21:12:10 | Sergio965 | I tried that out, with nil, but it doesn't seem to work quite as well as I'd hope, evenf or simple cases. |
21:12:39 | ldlework | for nil you need a reference type of course |
21:12:47 | Sergio965 | IE, let p = new(Person); // fill out p, p.call_some_func() won't compile if call_some_func checks not nil. |
21:13:02 | Sergio965 | You need to do: if p != nil: p.call_some_func(). |
21:13:03 | ldlework | Is Person a ref type? |
21:13:08 | Sergio965 | Yeah. |
21:13:14 | Sergio965 | Well, no, p is. |
21:13:29 | ldlework | p is a ref value |
21:13:41 | ldlework | no? |
21:13:51 | Sergio965 | I thought the type of p was "ref Person"? |
21:14:01 | ldlework | That's up to you |
21:14:05 | ldlework | type Person = object |
21:14:08 | ldlework | type Person = ref object |
21:14:13 | ldlework | depends on how you defined it |
21:14:17 | Sergio965 | The former. |
21:14:23 | ldlework | then there are no references here |
21:14:26 | Sergio965 | Uh... |
21:14:37 | ldlework | Nim has copy semantics |
21:14:38 | Sergio965 | When I do p.proc(), it calls the proc where the first parameter is "ref Person". |
21:14:51 | Sergio965 | Doesn't that mean p is type "ref Person"? |
21:14:51 | ldlework | lol no idea why that would work |
21:14:57 | ldlework | can you gist a minimal example? |
21:15:02 | Sergio965 | Sure. |
21:16:27 | Sergio965 | https://gist.github.com/SergioBenitez/ec55bbdaa09f9dd035ea |
21:17:11 | Sergio965 | Also, let p: ref Person = new(Person) works. |
21:18:11 | * | sarlalian joined #nim |
21:18:11 | Sergio965 | There should be an online Nim sandbox thing, similar to Rust's. |
21:19:51 | ldlework | Ah I see |
21:19:54 | ldlework | Its your use of new() |
21:20:01 | Sergio965 | Oh? |
21:20:07 | ldlework | Which allocates a Person directly on the heap |
21:20:49 | Sergio965 | Right |
21:20:55 | Sergio965 | That's what I expected. |
21:21:12 | ldlework | Sorry remind me what the question was? |
21:21:15 | Sergio965 | By the way, if I have proc do_something(p: Person), will that pass the entire Person object to `do_something`? |
21:21:36 | ldlework | yes, copy semantics by default |
21:21:37 | Sergio965 | Oh, we were talking about flow sensitive stuff, and I was saying how it didn't work for me for simple cases. |
21:21:47 | Sergio965 | Presumably I need to do p: ref Person. |
21:22:01 | Sergio965 | To get a reference. How do I create a reference on the other side? |
21:22:09 | Sergio965 | From an existing object? |
21:22:11 | ldlework | You cant |
21:22:19 | ldlework | Because a reference would mean a pointer to the data |
21:22:23 | Sergio965 | Right... |
21:22:23 | ldlework | the data lives on the stack |
21:22:25 | ldlework | so that'd be unsafe |
21:22:35 | ldlework | you can create a new instance on the heap and copy the data into it |
21:23:12 | ldlework | I love pretending like I know what I'm talking about relating to statically compiled languages ^^ |
21:23:14 | ldlework | its fun |
21:23:58 | Sergio965 | Meh. Nim draws the "unsafe" line at strange places. |
21:24:10 | Sergio965 | It allows null pointer exceptions, but not pointer to stack objects. |
21:24:15 | Sergio965 | pointers* |
21:24:20 | Sergio965 | Which, sure, is worse, but still. |
21:24:26 | ldlework | Well I'm pretty sure you could addr it |
21:24:33 | ldlework | Maybe. |
21:24:36 | ldlework | But probably not. |
21:24:41 | Sergio965 | Lol. |
21:24:45 | ldlework | Sergio965: the problem is that there is a GC at play |
21:24:57 | Sergio965 | Sure. |
21:25:00 | Sergio965 | How is that a problem? |
21:25:08 | Sergio965 | Or, what's the problem? |
21:25:19 | ldlework | Well Nim will let you dereference an unsafe pointer. |
21:25:27 | ldlework | It wont let you dereference a null ref object |
21:25:29 | ldlework | At least not easily. |
21:25:39 | ldlework | So what you said doesn't feel like an equivalence. |
21:25:56 | * | krux02 quit (Quit: Page closed) |
21:26:53 | Sergio965 | Oh, I didn't say they were equivalent. In fact, I said one was worse than the other. In fact, the system wouldn't be typesafe if it allows you to dereference a dangling pointer. |
21:27:03 | ldlework | Well it isn't strange, is what I meant. |
21:27:18 | Sergio965 | I just wish `nil` was not a thing |
21:27:25 | ldlework | That it lets you dereference a null unsafe unmanaged pointer is pretty typical actually. |
21:27:27 | Sergio965 | I hate saying null pointer exceptions. |
21:27:36 | Sergio965 | seeing* |
21:27:43 | ldlework | Why are you using unmanaged memory? |
21:27:48 | Sergio965 | I'm not. |
21:27:53 | ldlework | Uninitialized memory? |
21:27:56 | Sergio965 | Yep. |
21:28:01 | ldlework | Yeah but like |
21:28:03 | Sergio965 | I did it to see what would happen. |
21:28:07 | ldlework | You always know that its one or the other. |
21:28:09 | Sergio965 | Not because there was a bug in my thing. |
21:28:12 | ldlework | And if you're not using unamanged memory. |
21:28:19 | ldlework | You always know its uninitialized memory. |
21:28:27 | ldlework | So its really just a scary named for that. |
21:28:29 | Sergio965 | But, you know, new(Person) returns an unusable object. |
21:28:45 | ldlework | Only if person has ref fields |
21:28:47 | Sergio965 | Touching `name` causes a null pointer exception. |
21:28:50 | Sergio965 | It has a 'string'. |
21:28:55 | Sergio965 | Which is initialized to nil. |
21:28:56 | ldlework | yeah which is a ref type |
21:28:59 | ldlework | hehe |
21:29:06 | Sergio965 | Yeah, and that sucks. |
21:29:06 | ldlework | but like I said |
21:29:10 | ldlework | its super obvious what the problem is |
21:29:17 | Sergio965 | Sure, sure. |
21:29:20 | ldlework | its not a super hard to debug thing |
21:29:25 | Sergio965 | Well, I'm not sure that's true. |
21:29:26 | ldlework | trust me |
21:29:33 | Sergio965 | Because, say, this happens after the program has run for 3 hours. |
21:29:39 | ldlework | there are far harder bugs to defeat in Nim |
21:29:40 | Sergio965 | And BAM, null pointer exception. |
21:29:47 | ldlework | Any bug that happens 3 hours into your execution is hard to debug. |
21:29:52 | Sergio965 | Because some field is nil. Where did that happen? |
21:29:59 | ldlework | Because some field is 1 instead of 0 |
21:30:00 | Sergio965 | Lol, fair enough. |
21:30:02 | ldlework | Where did that heppen? |
21:30:04 | ldlework | :) |
21:30:13 | Sergio965 | I just don't think `nil` should exist. |
21:30:24 | ldlework | Well there is always Rust |
21:30:30 | Sergio965 | Inded. I'm well versed in Rust. |
21:30:32 | Sergio965 | Indeed* |
21:30:42 | Sergio965 | I'm playing with Nim because I'm creating a tiny EDSL. |
21:30:46 | ldlework | But given that we just agreed that the problem isnt' so bad |
21:30:55 | Sergio965 | Well, I don't think I agreed. Haha |
21:30:55 | ldlework | Is the upfront cost of Rust worth it to avoid this exception type? |
21:30:59 | ldlework | Okay then. |
21:31:06 | ldlework | You said fair enough :) |
21:31:15 | Sergio965 | Yeah, to knowing what type of problem it could be. |
21:31:23 | Sergio965 | But not to knowing what/where/why the problem occurred. |
21:31:46 | ldlework | Nim tells you where you access uninitalized memory |
21:32:09 | Sergio965 | Well, in Rust, this particular issue of not having uninitalized values doesn't have much of an upfront cost. |
21:32:19 | Sergio965 | The higher cost is in having safe pointers to things. |
21:32:23 | ldlework | Yeah except constantly supplying ownership information literally everywhere |
21:32:26 | Sergio965 | Cost to the developer, that is. |
21:32:31 | Sergio965 | Um |
21:32:37 | Sergio965 | Ownership information is implicit |
21:32:42 | Sergio965 | Perhaps you mean lifetimes? |
21:32:47 | ldlework | Sure |
21:32:53 | Sergio965 | Most lifetimes can be inferred. |
21:32:58 | Sergio965 | Except when they need to be named. |
21:33:04 | Sergio965 | In structs, for example. |
21:33:09 | ldlework | You should tell that to the authors of most Rust code I see. |
21:33:21 | Sergio965 | But usually, you don't need to name lifetimes in functions. |
21:33:35 | ldlework | Which is littered with details unspecified in other languages |
21:33:38 | * | cheatfate joined #nim |
21:33:44 | Sergio965 | Functions? |
21:33:48 | ldlework | No? |
21:33:53 | Sergio965 | Like what? |
21:33:59 | Sergio965 | Or, sorry, is that a sarcastic no? |
21:34:15 | Sergio965 | Or a question-ing no? |
21:34:47 | ldlework | I'm not interested in this conversation. If you stance is that writing Rust is the same operational effort as other languages we have had different experiences with the language. |
21:34:56 | Sergio965 | I didn't say that at all. |
21:35:04 | * | bjz_ quit (Quit: My MacBook Pro has gone to sleep. ZZZzzz…) |
21:35:18 | ldlework | "functions" are not the "litter of details unspecified in other languages" I was referring to. |
21:35:38 | Sergio965 | I made two claims: 1) The ownership stuff is implicit, so there's not too much upfront cost, and 2) lifetimes can typically be inferred, though they can't always be because they require names at times. |
21:35:44 | ldlework | With which Rust is generally characterized outside of this microcosim of a conversation :P |
21:36:00 | * | PMunch joined #nim |
21:36:27 | Sergio965 | Yeah, lifetimes can definitely be hairy. |
21:36:31 | Sergio965 | I won't argue that. |
21:36:41 | Sergio965 | It's especially true in library code. |
21:36:45 | Sergio965 | Unfortunately. |
21:36:54 | ldlework | Nim doesn't make library code very easy to write either. |
21:37:05 | ldlework | Polymorphsim is an uncomfortable story. |
21:37:05 | Sergio965 | Oh? |
21:37:57 | ldlework | Concepts don't work in the case important to polymorphic implementation and multi-methods work well, but not if any of your methods or your object is generic. |
21:38:16 | ldlework | So the only stable way of doing polymorphism is by passing closure which is just hilariously bad. |
21:39:01 | * | boopsiesisaway quit (Ping timeout: 252 seconds) |
21:39:21 | ldlework | Araq hates methods on principle and hates the Concepts implementation we have even more. |
21:39:31 | ldlework | So its not clear what the path forward is. |
21:39:56 | ldlework | Araq will jump in at any moment and say its one way or the other as he's said a million times, but I swear he flip flops on this issue weekly :D |
21:41:59 | Sergio965 | Lol |
21:42:08 | Sergio965 | I really like Traits/Typeclasses. |
21:42:18 | Sergio965 | But it's also quite nice to have implicit type contraints. |
21:42:21 | Sergio965 | Though scary. |
21:42:25 | ldlework | Concepts are basically typeclasses as I understand it. |
21:42:49 | ldlework | But implemented as explicit constraints on what is acceptable in the implementation. |
21:43:26 | Sergio965 | Yeah |
21:43:29 | Sergio965 | It's pretty wild. |
21:43:36 | ldlework | Which I think is pretty cool so I hope he doesn't give up on that. |
21:44:01 | ldlework | I like the theme of Nim wherein you just implement some stuff and the compiler derrives all that annotation from usage. |
21:44:04 | Sergio965 | Container[T] = concept c { for value in c: type(value) is T } is crazy. |
21:44:10 | ldlework | I hope it can be maintained. |
21:44:32 | Sergio965 | What even happens there? |
21:45:00 | ldlework | Well, I hope there is some awesome academics happening but I imagine its just a bunch of handrolled heuristics haha |
21:45:02 | Sergio965 | I mean, I know it's checking that the iterator always returns the same type T. |
21:45:16 | Sergio965 | But, what? What if the iterator is generic... |
21:45:18 | Sergio965 | Or is that not allowed? |
21:45:38 | Sergio965 | Or what if it does some of that weird T | A stuff, but always returns only Ts... |
21:46:03 | Sergio965 | Crazy stuff. |
21:46:15 | ldlework | The way it was explained to me |
21:46:22 | Sergio965 | The scary thing about some of Nim's stuff is that it seems very difficult to formalize. |
21:46:23 | ldlework | is that the compiler actually tries to compile the proof |
21:46:39 | ldlework | Rather than inspecting it at all |
21:46:41 | Sergio965 | But the proof should be trivial. |
21:46:44 | ldlework | It stages a type |
21:48:03 | Sergio965 | It should be: The user chooses a T for Container[T] for some A. Does the iterator for A return T? If yes, QED. |
21:48:15 | Araq | it's internally rewritten to a 'when compiles(x)' statement and that determines whether it matches or not |
21:48:18 | Sergio965 | This assumes generics aren't allowed for T. |
21:48:35 | Araq | this shifts the burden to system.compiles |
21:49:01 | Araq | which is not that hard to formalize, afaict |
21:49:09 | Sergio965 | Sorry, what is x? |
21:49:34 | ldlework | the concept block I think |
21:50:21 | Sergio965 | How do you check the `for value in c: type(value) is T`, Araq? |
21:50:53 | Sergio965 | Presumably, it shouldn't depend on the implementation of the iterator, but this seems to imply it does. |
21:51:04 | Sergio965 | Otherwise, you'd see something like iterator(c) is T, or something. |
21:52:00 | Sergio965 | At least I'd guess as much. |
21:52:13 | Araq | the iterator is typed, why would it depend on its implementation? |
21:52:33 | Sergio965 | Exactly. |
21:52:38 | Sergio965 | So why the `for` loop? |
21:53:00 | Araq | you only need to perform overloading resolution to determine which iterator is meant, but that's exactly what needs to happen |
21:53:34 | Araq | why the `for` loop? simple. so that we have the power of imperative Nim at our finger tips. |
21:54:23 | Araq | since we can check the typing for imperative code anyway, that's what we allow in a 'concept' |
21:54:53 | Araq | this means there is not another sublanguage within Nim to learn for concepts. |
21:55:06 | * | yglukhov quit (Remote host closed the connection) |
21:55:11 | Sergio965 | "iterator(c) is T" seems more uniform. |
21:55:14 | Sergio965 | But that's just me. |
21:55:46 | Araq | it's not uniform it's a special case since 'iterator(c)' is not used elsewhere in Nim. |
21:56:26 | Araq | you can argue it's more "intuitive", but there is no uniformity in something that otherwise doesn't exist. |
21:56:38 | Sergio965 | Lol |
21:56:48 | Sergio965 | Sure, sure. |
21:57:17 | Sergio965 | I suppose the oddity is that the for loop implies that a type is being checked n times when only one check is hapenning. |
21:57:24 | ldlework | I think "use the type how you expect to" is a lot more intuitive |
21:57:33 | * | derka quit (Ping timeout: 246 seconds) |
21:57:33 | ldlework | I'm not sure how anything could be more "intuitive" |
21:57:56 | ldlework | Sergio965: to be honest, not to be argumentitive, I never thought that |
21:58:07 | Araq | we used to have 'fooo is iterator' but that was a special case that was tedious to maintain in the compiler and so I removed it |
21:58:20 | Sergio965 | I suppose in Nim, iterators are special things. |
21:58:36 | Sergio965 | In most other languages, an iterator is just a function that yields. |
21:58:39 | ldlework | Sergio965: what do you think about iteration as a protocol? |
21:58:43 | ldlework | mmm |
21:58:52 | Sergio965 | Or a typeclass. |
21:59:01 | Araq | "most other languages" doesn't include Python then. |
21:59:08 | Sergio965 | How so? |
21:59:11 | ldlework | Well in python its just a typeclass. |
21:59:14 | Sergio965 | Python just yields to create a generator. |
21:59:14 | ldlework | a ducktypeclass. |
21:59:19 | ldlework | Sergio965: nah |
21:59:26 | ldlework | it has an actual iteration interface |
21:59:31 | ldlework | any object can be an iterator |
21:59:31 | Araq | just because Python uses 'def' for both doesn't mean it doesn't distinguish between these two |
21:59:39 | Sergio965 | ldlework: Yes, that doo. |
21:59:40 | Sergio965 | too* |
21:59:49 | ldlework | Sergio965: that's what Araq was referring to |
21:59:58 | ldlework | But I think you can consider the iterator interface in python just as a kind of typeclass. |
22:00:02 | Sergio965 | Indeed. |
22:00:52 | Araq | a resumable function is inherently different from a non-resumable function since a non-resumable function can keep its state on the stack. |
22:00:54 | ldlework | Araq: I guess I didn't realize that when we were talking about making Nim iteration a 'protocol' |
22:00:56 | Sergio965 | So, if Python had concepts, I'd do something like: c.__next__ is T or something. |
22:01:23 | Araq | at least in the context of "systems programming". |
22:01:36 | ldlework | Sergio965: eh but it might be easier to explain to just use a for-loop |
22:01:45 | Sergio965 | For who? |
22:01:57 | ldlework | Anyone? |
22:02:01 | Sergio965 | Not me! |
22:02:02 | Sergio965 | Haha |
22:02:13 | Sergio965 | I've programmed in a shit ton of languages, and that construct seems very foreign to me. |
22:02:22 | ldlework | It is very foreign |
22:02:27 | * | derka joined #nim |
22:02:27 | ldlework | I don't think I've seen it anywhere |
22:02:30 | Sergio965 | Not that Nim needs to be like other languages, in fact, it's nice that it's not. |
22:02:36 | ldlework | But it is certainly intuitive to build up a constraint through usage. |
22:02:39 | Sergio965 | But it also feelds wrong. |
22:02:42 | Sergio965 | feels* |
22:02:47 | Sergio965 | For loop do something once per item. |
22:02:50 | Sergio965 | That's what they do. |
22:03:02 | Sergio965 | In the concept, it doesn't do that. It just checks once. |
22:03:05 | ldlework | Not when it is clear the code isn't actually executing |
22:03:07 | Sergio965 | I mean, in this case, it's the same. |
22:03:13 | Araq | Sergio965: that particular feature was designed after every proposal for C++ was considered. |
22:03:35 | ldlework | Sergio965: it doesn't even run the code |
22:03:41 | Sergio965 | ldlework: I understand. |
22:03:42 | ldlework | Sergio965: it /compiles/ it. |
22:03:49 | ldlework | Sergio965: you said "checks once" vs "Checks each item" |
22:03:51 | ldlework | there are no items |
22:03:52 | Sergio965 | It seems like it just checks if it compiles. |
22:04:00 | Araq | yes! |
22:04:12 | ldlework | that's precisely what happens |
22:04:17 | Sergio965 | Sure, I get that. |
22:04:22 | ldlework | So it doesn't even check once. |
22:04:24 | Sergio965 | I'm just arguing about the syntax. |
22:04:29 | Sergio965 | Well, it does? |
22:04:32 | ldlework | No |
22:04:34 | Sergio965 | I mean, the compiler checks the types. |
22:04:35 | ldlework | No iterator is run |
22:04:37 | ldlework | No item is procuded |
22:04:41 | Sergio965 | Oh, I get that. |
22:04:44 | ldlework | No type of an item that was never produced was checked. |
22:04:47 | ldlework | So |
22:04:48 | Sergio965 | ... |
22:04:50 | Sergio965 | I get that. |
22:04:53 | Sergio965 | I really do, trust me! |
22:04:54 | Sergio965 | Haha. |
22:04:58 | ldlework | You're distinguishing between "checking once" and "checking multiple times" |
22:05:00 | ldlework | Checking what? |
22:05:02 | Sergio965 | Dude.. |
22:05:06 | Sergio965 | I'm talking about conceptually! |
22:05:10 | ldlework | So am I |
22:05:17 | Sergio965 | If you write a `for` loop, you're iterating through objects. |
22:05:20 | Araq | ldlework: *checking types* ;-) |
22:05:31 | Araq | that's the *what* ;-) |
22:05:34 | Sergio965 | Seeing a `for` loop in something is simply type-checked is a bit odd. |
22:05:37 | Sergio965 | that is* |
22:05:51 | Sergio965 | Because type-checking is a thing that happens once. |
22:05:53 | Sergio965 | For the most part. |
22:06:00 | ldlework | There is a difference between "checking once, that the code compiles" and "checking once, that by running the forloop and performing iteration once, the thing that would be wierd for a for loop to actually do, and checking the returned value is of a certain type" |
22:06:13 | ldlework | There is nothing strange about checking that a forloop *compiles once* |
22:06:23 | Sergio965 | :\ |
22:06:27 | ldlework | Since compiling a for loop has *nothing to do at all even conceptually* with what a for loop *does* |
22:06:35 | Sergio965 | I totally get that. |
22:06:39 | Sergio965 | My point is syntax. |
22:06:42 | ldlework | haha |
22:06:46 | ldlework | To compile a forloop |
22:06:47 | Sergio965 | The concept thing doesn't say, " |
22:06:52 | Sergio965 | "hey, check that this will compile" |
22:06:59 | Sergio965 | It says, "Check that these things are true." |
22:07:02 | Sergio965 | At least that's how I read it. |
22:07:11 | Sergio965 | And so, it looks like, to me, you're checking that each item has the same type via the iterator. |
22:07:14 | ldlework | Concepts, also known as "user-defined type classes", are used to specify an arbitrary set of requirements that the matched type must satisfy. |
22:07:17 | Sergio965 | Which is, in fact, what you're checking, conceptually. |
22:07:26 | ldlework | all of the expressions within the body can be compiled for the tested type |
22:07:28 | ldlework | all statically evaluatable boolean expressions in the body must be true |
22:07:36 | ldlework | It literally *does* say that it is going to check if the expressions *compile* |
22:07:44 | Sergio965 | Where? |
22:07:52 | ldlework | I just copied this from the manual |
22:07:57 | Sergio965 | Oh. |
22:08:00 | Sergio965 | It actually does say that. |
22:08:09 | ldlework | You've conflated compilation with execution conceptually. |
22:08:12 | Sergio965 | Well, there you go. |
22:08:18 | Sergio965 | I've done no such thing, ldlework . |
22:08:18 | ldlework | Nothing strange about compiling a for-loop once ;) |
22:08:33 | Sergio965 | You seem to assume I don't understand compiliation vs. type-checking vs. execution. |
22:08:39 | ldlework | You argued |
22:08:44 | ldlework | That writing a for loop is strange |
22:08:50 | Sergio965 | I understand them quite well, in practice, in theory, and in concept. |
22:08:52 | ldlework | Because you expect the for loop to do something multiple times |
22:08:57 | ldlework | Compared to the actual behavior |
22:08:57 | Sergio965 | I didn't! |
22:08:58 | Sergio965 | Jeez. |
22:08:59 | ldlework | of doing something once |
22:09:06 | Sergio965 | I said it _looks_ that way. |
22:09:25 | Sergio965 | In fact, I said I expect it, in the concept, to instantiate _one_ check. |
22:09:32 | ldlework | 14:02:31 Sergio965 | Not that Nim needs to be like other languages, in fact, it's nice that it's not. |
22:09:34 | ldlework | 14:02:35 ldlework | But it is certainly intuitive to build up a constraint through usage. |
22:09:36 | ldlework | 14:02:39 Sergio965 | But it also feelds wrong. |
22:09:38 | ldlework | 14:02:42 Sergio965 | feels* |
22:09:40 | ldlework | 14:02:48 Sergio965 | For loop do something once per item. |
22:09:42 | ldlework | Yes |
22:09:46 | Sergio965 | Dude. |
22:09:49 | Sergio965 | Outside of the concept. |
22:09:49 | Araq | ldlework: please stop. |
22:09:57 | Araq | there is no disagreement left. |
22:10:06 | Sergio965 | When you just write a for-loop, it iterates through each item. |
22:10:16 | Sergio965 | That's all I was saying. |
22:10:40 | gmpreussner | oh, there's a party here, and I missed it! |
22:10:46 | Sergio965 | gmpreussner, Welcome! |
22:10:59 | ldlework | Sergio965: okie dokie |
22:11:03 | * | boopsiesisaway joined #nim |
22:11:30 | Sergio965 | Anyway, the `concept` concept is interesting. |
22:12:06 | ldlework | gmpreussner: Araq has an important question to ask you. |
22:12:19 | Sergio965 | How do you say something must, uh, obey? some concept? Do you just ask for something of that type? EG: proc f[Comparable]? |
22:12:27 | ldlework | Yep |
22:12:35 | ldlework | or use it as a constraint on the generic parameter |
22:12:47 | Sergio965 | What's that syntax? |
22:12:52 | ldlework | wait I might be making that up |
22:13:20 | ldlework | Foo[T: C] I think? |
22:14:02 | ldlework | Explained in typeclasses, http://nim-lang.org/docs/manual.html#generics-type-classes |
22:14:29 | Sergio965 | I see, I see. |
22:14:38 | Sergio965 | So concepts are quite literally typeclasses. |
22:14:44 | ldlework | yeah |
22:14:54 | ldlework | user type classes as it says in the manual |
22:14:57 | Sergio965 | And presumably, seq[T: Concept] works out? |
22:15:17 | Sergio965 | And so when I iterate though it, I'm guaranteed Concept. |
22:15:20 | ldlework | Concepts are known to be buggy but I dunno exactly where |
22:15:40 | ldlework | But I think you can use the concept directly there |
22:15:48 | ldlework | seq[Concept] |
22:15:59 | Sergio965 | RIght. |
22:16:05 | Sergio965 | I just prefer seq[T: Concept]. |
22:16:16 | Sergio965 | Looks more like a typeclass/trait. |
22:16:27 | Sergio965 | Okay, neat. |
22:16:43 | Sergio965 | Thanks for the discussion, ldlework, Araq! |
22:17:01 | Sergio965 | Now if only I could do C-FFI calls at compile-time. |
22:17:08 | Sergio965 | I'd be pretty happy. |
22:17:13 | Araq | ldlework: I just fixed what I think was the hardest bug with concepts :-) |
22:17:28 | Sergio965 | (And `nil` didn't exist...) |
22:17:28 | Araq | Sergio965: use staticExec with the cache parameter as a workaround |
22:17:32 | ldlework | Oh I wonder if my polymorphism example will work now |
22:17:41 | ldlework | though I forget what it was |
22:17:42 | Araq | ldlework: uh oh ;-) |
22:18:12 | ldlework | Araq: seriously ask him he was he just a minute ago! |
22:18:19 | ldlework | here* |
22:18:27 | Araq | ldlework: we're skyping ;-) |
22:18:45 | ldlework | wonderful |
22:18:52 | Sergio965 | Oh, nice Araq! |
22:18:59 | Sergio965 | (staticExec) |
22:19:30 | Sergio965 | Don't I want `cache` to be empty, though? |
22:19:37 | Sergio965 | Maybe not. |
22:20:09 | Sergio965 | Sweet. Now I have more things to play with. |
22:20:13 | Sergio965 | Thanks, Araq, ldlework. |
22:20:18 | Sergio965 | Lunch-time. :D |
22:32:36 | gmpreussner | ldlework, Sergio965: i think concepts are better than type classes |
22:35:53 | * | mahasamoot quit (Ping timeout: 250 seconds) |
22:36:12 | ldlework | gmpreussner: they appear to be different words for the same thing |
22:36:17 | ldlework | what distinguishes them? |
22:36:37 | * | pregressive quit (Remote host closed the connection) |
22:43:13 | * | mahasamoot joined #nim |
22:44:04 | gmpreussner | concepts are more flexible |
22:44:25 | gmpreussner | the expressions in concepts can model more things that type classes a la Haskell can't |
22:46:06 | ldlework | Like what? |
22:46:42 | ldlework | I guess that's a dumb question. I suppose I can imagine that since the grammar is "arbitrary nim code" that it should be more flexible. |
22:47:11 | * | beatmox quit (Remote host closed the connection) |
22:47:17 | ldlework | gmpreussner: what is interesting to me is that concepts do not actually do what typeclasses in other languages appear to do |
22:47:25 | * | beatmox joined #nim |
22:47:31 | ldlework | that is, provide the compiler with extra information about what the capabilities of a type could do |
22:47:50 | ldlework | in Nim, it seems the compiler magically determines the capabilities of a generic type based on the usage in the generic implementation |
22:48:06 | ldlework | And that concepts are a thin constraint on what the generic implementation is allowed to do |
22:48:33 | ldlework | but the compiler already knows whether you're passing types to a generic implementation where the implementation does things that the concrete type does not support |
22:49:18 | gmpreussner | in Haskell it's more specific: type must implement function with a certain name, parameters and return type |
22:49:27 | ldlework | So its like, why do we even need concepts in the first place? |
22:49:44 | gmpreussner | in concepts, the constraints are relaxed to: if the expressions compile |
22:50:07 | ldlework | Sure but those expressions might contain assertions on functions with name parameters and return type right? |
22:50:10 | gmpreussner | to write algorithms over types that meet certain requirements |
22:50:18 | ldlework | Sure but you can just do that over T |
22:50:23 | gmpreussner | *generic / reusable algorithms |
22:50:25 | ldlework | And use the requirements in the generic implementation |
22:50:32 | ldlework | IE T.whatever() |
22:50:41 | gmpreussner | that's much more specific |
22:50:43 | ldlework | And assuming that you only ever pass types to the generic function that have .whatever |
22:50:45 | ldlework | it works |
22:51:03 | ldlework | IE |
22:51:16 | ldlework | We don't need a concept that asserts that the type has a .whatever |
22:51:25 | ldlework | and then define the proc as T: Whatever |
22:51:25 | gmpreussner | you cannot write algorithms that work on both generic and non-generic types at the same time like that |
22:51:29 | ldlework | because Nim already does this |
22:51:34 | ldlework | huh? |
22:52:19 | * | aziz quit (Remote host closed the connection) |
22:53:56 | gmpreussner | let's say you want to write a function over types that are Queue-like, meaning they implement enqueue(T) and queue(T). that function may look like this: proc doStuff(q: Queue[T], value: T): T = ... |
22:54:06 | gmpreussner | Queue[T] is a concept |
22:54:16 | gmpreussner | actual implementations may or may not be generic |
22:54:43 | gmpreussner | they may be SimpleQueue, or ArrayQueue[T], or FixedSizeQueue[T, N: static[int]] |
22:54:50 | gmpreussner | or something completely different |
22:55:06 | gmpreussner | you can't express that with just proc doSomething[T](..) |
22:55:32 | gmpreussner | could be FoobarQueue[U, V] |
22:55:56 | gmpreussner | there is no T in the type itself, nor can T be recovered for the 'value' parameter in doSomething() |
22:57:28 | ldlework | https://gist.github.com/dustinlacewell/fa73aef8687f6d62f544 |
22:57:31 | ldlework | is this what you mean? |
22:57:57 | ldlework | Just using T, the first blurt() works on both regular and generic types. |
22:58:12 | ldlework | no concepts invovled and I'm allowed to call .blurt() on the concrete type |
22:58:21 | ldlework | I could have named the concerete blurts something else |
22:58:27 | ldlework | actually let me make sure |
22:59:04 | ldlework | yep still works |
22:59:15 | ldlework | so its calling the first blirt, then the specific ones |
22:59:26 | ldlework | but I probably misunderstood what you meant entirely |
23:01:09 | gmpreussner | close... make blurt() take a parameter that is also used in T's proc implementations |
23:01:37 | ldlework | like say, the message to blurt? |
23:03:14 | gmpreussner | take a look at this: https://gist.github.com/gmpreussner/6424afb5d8dd181cde4e |
23:03:25 | gmpreussner | (it doesn't work right now, which is why i put it together) |
23:03:39 | gmpreussner | but the concept says: Foo must be a type that implements foo(T) |
23:04:00 | gmpreussner | you can replace FooImpl[T] with FooImpl[U] if the 'T' confuses you |
23:04:06 | gmpreussner | the T is not relevant further down |
23:04:07 | ldlework | I don't think you can pass T |
23:04:17 | ldlework | you must do, var v: T |
23:04:19 | ldlework | and pass v |
23:04:27 | gmpreussner | no, it works :) |
23:04:28 | ldlework | Unless you really mean, takes a typedesc |
23:04:30 | ldlework | what |
23:04:32 | ldlework | lol |
23:04:44 | ldlework | Araq: ?? |
23:04:51 | gmpreussner | yeah, I think Araq doesn't like it, but I love it |
23:05:19 | ldlework | It violates the principle that the code is compiling as normal |
23:05:26 | ldlework | I can't pass T in a normal generic function |
23:05:38 | Araq | ldlework is correct. afaict. |
23:05:40 | gmpreussner | it basically resolves to 'match any', as far as i understand |
23:06:13 | * | ldlework hides under a desk. |
23:06:44 | Araq | and I take it back: 'concept' seems to be so buggy that I consider throwing the implementation away. |
23:06:59 | gmpreussner | lol |
23:07:11 | gmpreussner | that feature is the main selling point for me |
23:07:52 | gmpreussner | i think it's not buggy per say, it's just not complete/consistent |
23:08:04 | gmpreussner | it seems pretty close though |
23:08:46 | Araq | yeah but I'll be honest: that's hard to take that seriously after you've shown us how Nim's macros revolutionize how virtual machines can be built ;-) |
23:09:10 | gmpreussner | alright, macros are #1, concepts #2 |
23:09:33 | Araq | also: I said I consider throwing the implementation away. |
23:09:46 | Araq | not the feature. nor its design. |
23:09:58 | gmpreussner | true |
23:10:42 | ldlework | Wait so are you supposed to be able to pass the T? |
23:10:55 | ldlework | Also is there a blog post on this VM business? |
23:11:00 | ldlework | I love macros :3 |
23:15:51 | Araq | though ... hmmm maybe I'll throw away 'concept' :-) |
23:16:10 | Araq | we could instead just do: |
23:16:41 | Araq | proc foo[T](x: predicate(T)) where 'predicate' is a compile-time function that returns true or false |
23:17:31 | Araq | that's what concept does internally anyway albeit giving it a declarative touch |
23:18:06 | Araq | without being all that declarative so maybe Sergio965 is right. |
23:20:07 | gmpreussner | well, declarative is not necessarily wrong |
23:20:10 | * | filwit joined #nim |
23:20:14 | gmpreussner | it makes it feel more 'functional' |
23:20:46 | gmpreussner | and it has the advantage of compositionality |
23:21:00 | gmpreussner | which, currently, with concepts you can only do via inheritance? |
23:21:17 | Araq | functions are composable by their very nature. |
23:22:02 | gmpreussner | perhaps for consistency, it should be predicate[T] |
23:22:16 | gmpreussner | which makes static[T] a built-in predicate function :) |
23:22:29 | gmpreussner | or something like that. i'm just babbling. |
23:25:43 | ldlework | I certainly find Concepts aesthetically pleasing as is |
23:26:31 | ldlework | gmpreussner: what did Araq mean about showing us what can be done with macros and vms? |
23:27:39 | Araq | ldlework: well the rewrite rule that the compiler uses internally should be its spec. |
23:28:27 | ldlework | I dont know what that means |
23:28:35 | Araq | no reason we can't keep the syntax, but the rewrite rule needs to be clear. |
23:28:49 | gmpreussner | Araq: i think i like predicate. it seems more flexible... a generalization of concept expressions to arbitrary compile time functions |
23:29:02 | Araq | and right now it's not clear at all. |
23:29:19 | Araq | in fact I cannot even say what 'concept x, y' means without looking at the implementation |
23:29:27 | gmpreussner | ldlework: i built a MOS6502 emulator using macros. it's not published yet. Araq used a small piece of it in his Oscom presentation |
23:29:51 | Araq | what's the x? what's the y? are they different? |
23:30:05 | gmpreussner | i think you're on to something :) |
23:30:14 | ldlework | I always figured it was both |
23:30:24 | ldlework | As in, literally any type that satisfies the interface |
23:30:32 | ldlework | which is both A, and B but also A against A |
23:30:54 | Araq | no it's an *instance* of the described concept type. |
23:30:59 | ldlework | Yes I understand that |
23:31:10 | Araq | so it's not a type, it's a value. |
23:31:12 | ldlework | I used "type" instead of "of type" |
23:31:14 | ldlework | sorry! |
23:31:23 | Araq | alright. |
23:31:33 | Araq | and I think 'y' is the same. |
23:32:47 | ldlework | If the purpose of a concept is to define the properties of a typeclass, then it makes sense that x and y are instances of any type that belongs to the typeclass |
23:33:06 | ldlework | A,A or A,B |
23:33:14 | ldlework | as long as both types are of the typeclass |
23:33:59 | ldlework | pretty sure that's how it works now, like the comparable example |
23:37:18 | * | lxdong joined #nim |
23:40:18 | * | zepolen quit (Remote host closed the connection) |
23:41:15 | gmpreussner | i agree |
23:41:25 | gmpreussner | i'm intruiged by predicate(T) though :) |
23:41:53 | gmpreussner | concept could be syntactic sugar (implemented in the stdlib) for predicates |
23:42:37 | * | Pisuke joined #nim |
23:42:54 | * | MyMind quit (Ping timeout: 260 seconds) |
23:44:03 | * | sethrmo joined #nim |
23:47:29 | Araq | gmpreussner: doesn't have to be in the stdlib, but it should be sugar and the transformation should be simple and described in the manual. |
23:47:31 | ldlework | yeah the predicate idea is neat too |
23:48:13 | ldlework | Araq: a concept just being a template that throws the block into a when compiles? |
23:48:20 | * | sethrmo quit (Ping timeout: 252 seconds) |
23:48:24 | Araq | something like that, yes. |
23:48:35 | Araq | btw this is what my todo.txt says "``concept`` needs to be refined, a nice name for the feature is not enough." |
23:48:46 | ldlework | so what you're really doing is |
23:48:47 | gmpreussner | true story |
23:48:57 | ldlework | raising up procs to typeclasses? o_O |
23:49:04 | gmpreussner | my problem is usually the other way around; i can't find nice names for things :D |
23:49:20 | Araq | we took the name from C++ :P |
23:49:31 | ldlework | Well does the language even need Concepts? |
23:49:45 | ldlework | Since Nim automatically derrives "typeclasses" from generic implementations? |
23:49:59 | ldlework | IE, bare T works for everything |
23:50:19 | Araq | I argued it doesn't but nobody respects my opinion in #nim |
23:50:41 | Araq | either way it does fill a niche. |
23:50:51 | ldlework | Araq: above gmpreussner tried to convince me there is a usecase where bare T does not work and you need a Concept to make it work |
23:50:56 | Araq | since you cannot overload based on a 'when compiles' check otherwise |
23:51:08 | gmpreussner | ^ that |
23:51:28 | gmpreussner | i find that very powerful |
23:51:50 | gmpreussner | not everything can be modeled with just generic functions |
23:52:01 | gmpreussner | that's like arguing Haskell doesn't need type classes either |
23:52:07 | ldlework | No I'm saying |
23:52:11 | ldlework | I thought what happened was |
23:52:13 | gmpreussner | well, we don't really 'need' any of this, but it sure is handy |
23:52:14 | Araq | no, Haskell works differently. |
23:52:14 | ldlework | When you use bare T |
23:52:23 | ldlework | that the implementation of the generic function *itself* was the "when compiles" |
23:52:40 | Araq | yes, ldlework that's right. |
23:52:41 | ldlework | So if you have two functions with the same name that take a T |
23:52:47 | ldlework | And you pass something to it |
23:53:01 | ldlework | resolution takes place based on whether the value satisfies the *usage* of T |
23:53:06 | ldlework | if that's the case I still don't understand the point |
23:53:12 | ldlework | But I'm weak at this stuff really. |
23:53:38 | gmpreussner | i think what i like about concepts is more akin to duck typing |
23:53:46 | ldlework | But bare T is exactly that |
23:53:50 | ldlework | without specifying anything |
23:54:01 | ldlework | it uses the usage of T in the generic function to determine if some value satisfies /this/ T |
23:54:02 | gmpreussner | i want to write algorithms that except a type X, where X meets certain conditions |
23:54:10 | ldlework | IE the T for this specific proc, and its internal implementation |
23:54:15 | gmpreussner | *accept a type X |
23:54:25 | ldlework | So just write an algorithm |
23:54:28 | ldlework | that uses a magic T |
23:54:32 | ldlework | that has all the methods you want |
23:54:37 | ldlework | and you will only be able to call it |
23:54:44 | ldlework | with values that satisfy the *implementation* of the *proc* |
23:55:04 | gmpreussner | maybe |
23:55:10 | gmpreussner | i have to think about this some more |
23:55:11 | ldlework | You dont need an external thing that says "this is what a T is" |
23:55:14 | Araq | ldlework: you cannot reliably overload on underspecified generics |
23:55:14 | ldlework | because the implementation is that |
23:55:20 | ldlework | Araq: I imagined that |
23:55:30 | Araq | that's what concepts enable. |
23:55:31 | ldlework | was what you were getting at above |
23:55:40 | ldlework | Okay cool |
23:56:00 | ldlework | It gives a name to the nonce typeclass that Nim would otherwise create |
23:56:00 | gmpreussner | my fear is that duck typing via generic procs is too underspecified, i.e. it matches a lot of things that i don't want to match |
23:56:23 | ldlework | sure so it is a constraint on the automatic typeclass |
23:56:32 | ldlework | That kinda sounds like a good way to understand concepts |
23:56:40 | Araq | gmpreussner: it's really like in C++. error messages tend to suck, I don't think it's bug prone though. |
23:56:54 | Araq | since eventually it's completely type checked. |
23:57:21 | Araq | and hey, if you generic 'sum' algorithm by chance works for strings. that's a feature. |
23:57:24 | Araq | *your |
23:57:39 | Araq | iirc 'sum' indeed works for strings in Python. |
23:57:46 | Araq | and the world still turns. |
23:58:29 | gmpreussner | i'd like to control that though, OCD as i am |
23:58:40 | ldlework | Hmm it seems strange to me that we would need something like concepts just to avoid resolution ambiguities |
23:58:52 | gmpreussner | summing strings might work (as in 'compiles') but may not meet the semantic expectations |
23:58:54 | ldlework | Since you get all the information that is inside the concept from the proc that uses the generic type automatically |
23:59:13 | ldlework | The only thing that the concept supplies that the automatic implementation derrived typeclass does not, is a name. |
23:59:22 | gmpreussner | just because i can sum strings by accident doesn't mean i also get meaningful results... by accident |
23:59:38 | ldlework | So it seems like a waste of work to respecify all the expressions for constraint |
23:59:47 | ldlework | when that same information exists in the impleentation of procs you use the value in |