[00:00:20] kernelj: Looks like you've discovered all the things I haven't gotten around to fixing in Kitten :P [00:00:41] The limited docs are for the old compiler [00:01:05] The common vocab is super-incomplete [00:01:15] Pattern-matching is limited to ADT constructors [00:01:30] [1 2] -> 1 [2] looks like a bug [00:02:01] And yeah, type signatures are required; could be relaxed in some circumstances but not all [00:04:34] I appreciate you trying it out, though, it's motivating [00:20:34] I think lack of File I/O is the biggest killer, I've found ways to work around everything else so far [00:21:08] The common vocab being small isn't actually a terrible thing [00:21:15] (less to learn) [00:23:22] evincar: I'll paste you a copy of my program when it's done [00:23:46] I've written a vocab for priority queues so far [00:24:29] it's efficiency depends on 'set' being efficient though, which I doubt [00:25:00] I saw you had mutations with lvalue array indices and variables in your issues list [00:38:01] How do you find out what the status filed in a process object means? ` { status 251 }' [00:42:46] kernelj: It's inefficient in the interpreter; the old backend was fast(ish), the new backend doesn't exist [00:43:56] I have way more ambition than motivation or sense :/ [00:47:13] define bi2 (Xs..., V, W, (Xs..., V, W -> Ys...), [00:47:16] (Ys..., V, W -> Zs...) -> Zs...) -> v, w, f, g: v w f call v w g call [00:47:27] wrote that right first time (translating from my own prelude) [00:48:21] in my language you can get rid of most of the foralls by binding the unification variables inline as parameters [00:50:01] you can see why having to write all that for a fairly basic combinator annoys me though [00:52:11] why have head_tail and not init_last lol [00:54:00] I guess I should add the permissions into bi2 instead of cheating and leaving them out [00:55:40] hmmmm only one permission required per function [00:56:44] I'm a bit confused by that [00:59:13] define bi2 (Xs..., V, W, [00:59:13] (Xs..., V, W -> Ys... +P), (Ys..., V, W -> Zs... +P) [00:59:13] -> Zs... +P) -> v, w, f, g: v w f call v w g call [00:59:28] doesn't look right to me but maybe it is [01:10:46] my own prelude is surprisingly accurate at getting these right [01:14:16] assuming that type checking makes them right of course :P [01:17:29] at the same time though I'm finding bugs in my prelude [01:26:00] ah crap [01:26:02] kitten: I can't find an instantiation of '_::=': '_::=::' [01:26:14] could that error message be any more useless? [01:35:35] so yeah it indeed has something to do with the = I use in the predicate [01:36:32] evincar: what's an alternative to writing {(= c)} [01:37:44] it should know c is a T from the type [01:38:22] but I suppose it doesn't know what the other argument is [01:48:20] I am stuck... [01:53:19] evincar: if I do [01:53:21] define equalpred (T -> (T -> Bool)) -> c: {(= c)} [01:53:29] 50: 3 2 equalpred call [01:53:30] I can't find an instantiation of '_::=': '_::=::' [01:54:14] what am I doing wrong here? [01:59:18] define equals (T, T -> Bool) -> c d: {(c = d)} call [01:59:24] 53: 1 2 equals [01:59:25] I can't find an instantiation of '_::=': '_::=::' [02:10:46] kernelj: Generic instances of traits don't work right [02:10:54] It doesn't generate the instantiation, so it fails to find it [02:11:53] evincar: so is this a bug? is there a workaround? [02:12:17] Yeah, it's a bug, or rather an incomplete feature [02:12:42] This seems like a showstopper imho [02:12:56] I don't think it's possible to write any useful generic code if it behaves like this [02:12:58] The workaround would be to make it non-generic I guess [02:13:16] I guess I know what I'm working on tonight :P [02:13:31] Also you can only have one permission *variable* per function, since it represents a set of permissions [02:13:45] I appreciate that it can be somewhat unintuitive [02:14:24] People try writing things like compose : ((A -> B +P1), (B -> C +P2) -> (A -> C +P1 +P2)) [02:14:52] When in reality you need +P for all of them [02:15:10] so that is the correct way to write it? [02:15:19] btw @compose?[~f\[xs.. =>$ ys..] ~g\[ys.. =>$ zs..] => [xs.. =>$[f g] zs..]]: #f#g [f# g#] [02:15:31] (A -> B +P), (B -> C +P) -> (A -> C +P) [02:16:01] The idea is that the set of permissions inferred for the resulting function must unify with (be a superset of) the permissions of both input functions [02:16:39] it doesn't really make sense [02:17:05] I mean yes it should be a superset [02:17:06] Specific example: f uses +IO, g uses +Fail, therefore { f call g call } uses +IO +Fail [02:17:20] well that's why you'd write it with +P1 +P2 [02:17:22] Then +P = +IO +Fail [02:17:36] I get the intent, sure [02:17:47] but then it makes it look like f uses +Fail and g use +IO [02:18:04] Yeah [02:18:07] The problem is that inference can't deal with combining multiple sets of permissions [02:19:19] The thing is, even if f doesn't use +Fail, it is called in a context that allows +Fail [02:19:46] For *specific* permissions you could disable that using "with (-Fail)" [02:19:55] But it doesn't work generically [02:21:57] I could maybe figure out a way to make the intuitive thing work [02:22:16] Last time I looked into it, it seemed more involved than I liked [02:30:09] anyway yeah, generic instances of traits and file I/O [02:31:15] guess I'll ungeneric my code [02:37:55] man even getting rid of most of it it still doesn't work [02:38:23] still generic at the point where it gets called [02:43:51] I expected '((T207348..., _::List<_::Char>, _::Char -> T207348..., _::List<_::List<_::Char>> +T206446))' to be at least as polymorphic as '((T206445..., _::List, T206444 -> T206445..., _::List<_::List> +T206446))' but it isn't [02:49:14] well g'night this isn't going anywhere [03:20:31] * evincar [evincar!~jon@173-228-12-107.dsl.dynamic.fusionbroadband.com] has quit (Ping timeout: 240 seconds). [04:37:09] * evincar [evincar!~jon@173-228-12-107.dsl.dynamic.fusionbroadband.com] has joined the channel. [04:37:33] kernelj: Thanks for trying things out; sorry you didn't have a great time, but it really is a big help to me [04:37:36] I can also be more responsive in the future :P [04:37:57] (Tried to send those earlier and they didn't show up in the logs so I guess my connection was down?) [05:59:11] * FreeFull [FreeFull!~freefull@defocus/sausage-lover] has quit. [06:14:06] * jtimon [jtimon!~quassel@117.29.134.37.dynamic.jazztel.es] has quit (Ping timeout: 240 seconds). [06:18:40] * Sgeo_ [Sgeo_!~Sgeo@ool-18e4354b.dyn.optonline.net] has joined the channel. [06:22:32] * Sgeo [Sgeo!~Sgeo@ool-18e4354b.dyn.optonline.net] has quit (Ping timeout: 268 seconds). [08:05:25] * proteusguy [proteusguy!~proteus-g@180.183.131.206] has joined the channel. [12:51:43] * proteusguy [proteusguy!~proteus-g@180.183.131.206] has quit (Remote host closed the connection). [13:37:58] * jtimon [jtimon!~quassel@117.29.134.37.dynamic.jazztel.es] has joined the channel. [15:20:34] silly me, I put [15:51:27] evincar: definitely put init_last in the prelude [15:51:42] you need it for processing lists in reverse [15:54:14] kernelj: why not just reverse the list first? [15:54:54] that's slow [15:55:03] and reverse isn't in the prelude neither :S [15:55:51] also missing is something for parsing ints from strings... [15:56:15] that shouold really be provided as intrinsics [15:56:21] Not really, the reversal is O(n), but then subsequent accesses would be O(1), where both init and last are O(n). [15:56:52] reversing the whole list to remove a few entries from the end isn't efficient [15:57:44] So traversing a list backwards would be O(n^2) with init and last. [15:58:10] I don't know how it's implemennted [16:00:44] Lists are typically singly linked lists, because doubly linked lists are not recursively defined, so they are harder to use in a functional language. [16:01:16] Or something like that [16:02:07] let xs' = Vector.init xs [16:02:29] Vector is Data.Vector [16:02:33] At any rate, reverse + traverse + reverse is still O(n), the same as just traversal. [16:02:49] yeah but I only need to traverse O(1) elements [16:03:14] ok well O(n) in this case but it could be O(1) [16:05:45] init "O(1) Yield all but the last element without copying. The vector may not be empty." [16:05:49] https://hackage.haskell.org/package/vector-0.12.0.1/docs/Data-Vector.html [16:06:00] it's doing the right thing [16:07:55] do I seriously need to write my own int parser [16:22:54] let me guess, I can't cast from Char to Int32 [16:25:05] if elif elif elif elif elif elif elif time [16:28:35] optionals are kinda painful without monads [16:34:33] lift_optional_2 is pretty useful though [16:44:05] evincar: you should be able to write '\0' for null char [16:45:05] also there should be a zero instance for char.... [16:49:07] * tgunr [tgunr!~davec@cpe-76-173-83-160.hawaii.res.rr.com] has quit (Read error: Connection reset by peer). [17:04:06] not sure why it's // TODO: map Optional [17:13:29] * tgunr [tgunr!~davec@2605:e000:1128:48:70ad:55d5:4015:e05b] has joined the channel. [17:13:47] * FreeFull [FreeFull!~freefull@defocus/sausage-lover] has joined the channel. [17:19:03] * tgunr [tgunr!~davec@2605:e000:1128:48:70ad:55d5:4015:e05b] has quit (Read error: Connection reset by peer). [17:20:05] * tgunr [tgunr!~davec@cpe-76-173-83-160.hawaii.res.rr.com] has joined the channel. [17:22:11] aargh I need bind [17:25:14] which is amusingly easier to write than lift_optional and is actually exactly the same minus one word [17:50:07] this seriously needs better error messages [17:53:48] here's my error message http://lpaste.net/356183 [17:54:24] * jtimon [jtimon!~quassel@117.29.134.37.dynamic.jazztel.es] has quit (Ping timeout: 260 seconds). [17:54:25] * tgunr [tgunr!~davec@cpe-76-173-83-160.hawaii.res.rr.com] has quit (Read error: Connection reset by peer). [17:54:34] I'm pretty sure these messages get less and less relevant the further down you go [17:57:54] noooo not another can't find an instantiation error [17:59:36] evincar: is there a reason you use == for lists and = otherwise because it doesn't seem very sensible [18:00:34] e.g. if you want to test two strings are equal [18:01:39] oh I see the Partial instances comment [18:01:58] and yeah this would need the generic instances of traits thing to work [18:03:17] specifically I'm trying to use 'elem' on a list of strings [18:04:18] still I think it ought to work with just = not == so you can use them in the same contexts [18:08:39] it didn't have any problem with me defining instance = (List, List -> Bool) -> xs, ys: [18:18:32] damn I have 5 variables [18:18:47] as in things that have to be on the stack [18:24:06] evincar: it would maybe be better if stuff like from_some took the error message for fail as an argument because the one it gives is very uninformative [18:25:55] even better would be if the default could somehow be made useful by looking up the code that generated the none value [18:26:29] but I guess it's very non-local potentially hmm [18:27:22] I suppose it's bad practice to output one of your arguments if it didn't change [18:30:12] dup -> over -> pick... what comes next guys? [18:32:03] * tgunr [tgunr!~davec@2605:e000:1128:48:70ad:55d5:4015:e05b] has joined the channel. [18:32:26] grab -> reach -> stretch? [18:34:14] swap, swap2, swap3, ... [18:34:36] Oh, wait, that's different. [18:35:27] what does swap2 do? [18:35:32] I guess I haven't need those yet. I'd probably call it over, over2, ... [18:35:56] I had that originally then I realised Factor defines 2over as x y z -> x y z x y [18:36:41] I replaced overn with nget [18:36:49] * jeaye [jeaye!~jeaye@unaffiliated/jeaye] has quit (Quit: WeeChat 1.7.1). [18:37:08] but I can't write 4get 5get since it starts with a digit [18:37:26] in starpial I'm relying on my dependent types [18:37:40] Um, it swaps further. A B C swap2 -> B C A, A B C D swap3 -> B C D A [18:38:00] swap2 looks like Factor's -rot [18:38:18] which for some reason it doesn't recommend for use [18:38:47] I know, but going swap, rot, rot4, isn't very intuitive. [18:38:56] I might expect swap2 to do A B C D -> C D A B [18:39:00] I like to define families of functions [18:39:36] same [18:40:00] but by the looks of it the index is supposed to be the number of elements done something to [18:40:34] I could call it swap_0_with_N, but that's too wordy. The thing is, I' [18:40:35] 2dup is X Y -> X Y X Y not X Y -> X Y Y Y [18:40:59] d rather just learn short mnemonics. [18:41:17] Like assembly. You just have to learn what they mean. [18:42:01] dependent types helps a lot since I have "3 4 ngetn" to do A B C W X Y Z -> A B C W X Y Z A B C [18:42:29] @ngetn?[@ts{m times:`@} @vs{n times:`@} ts.. vs.. #m?uint #n?uint => ts.. vs.. ts..]:#m list dip[n list] over apply3[..] [18:42:43] Maybe I'll use assembly-like dot modifiers: swap.N [18:43:05] I don't think it's worth the extra character, though. [18:43:50] well if you need two indices and want to make your compiler handle the parsing you could have ap.10.2 and stuff like that [18:44:04] with what you've got currently you can't go above ap99 [18:44:25] That is complicated, and "4 nget" is longer than "get4". [18:44:50] I don't want anyone to use anything above ap99. If they must, they can define it. [18:45:18] * jtimon [jtimon!~quassel@117.29.134.37.dynamic.jazztel.es] has joined the channel. [18:45:26] I don't want to have to define get4 get5 get6 get7... [18:45:36] my current intuition is not to go above 3 [18:45:53] It's not that bad. You only have to do it once. [18:46:04] wrong, I have to type them [18:46:16] the type system keeps changing and I have to rewrite several times [18:46:43] with the dependently typed version I only have one line to change, which is indeed a more complicated line [18:47:14] Usually such things have very regular structure. They could be implemented with macros, but it's not that bad to cut and paste, add a word, repeat a few times. [18:47:19] my language has no keywords and the prelude is just a program [18:47:47] hackerfoo: it's taking me forever to get through my Prelude and convert to the new type system and that's without a load of unnecessary words [18:47:58] now macros... that could be interesting [18:48:41] I haven't really thought about what could be done with macros and they seem kinda unnecessary in a concatenative language [18:49:29] but when you can do token pasting things get interesting [18:49:44] not sure it's something I want to think about just yet [18:55:19] didn't factor used to have a 'tuck' to go with 'nip' [18:55:25] X Y -> Y X Y [18:56:09] * tgunr [tgunr!~davec@2605:e000:1128:48:70ad:55d5:4015:e05b] has quit (Read error: Connection reset by peer). [18:57:11] * tgunr [tgunr!~davec@cpe-76-173-83-160.hawaii.res.rr.com] has joined the channel. [18:59:40] hm it's from Forth [19:00:40] Yeah, I have that too. I think I implemented every common stack manipulation word from Forth. [19:02:11] apparently in Forth it goes DUP -> OVER -> 2 PICK -> 3 PICK ... [19:02:12] * tgunr [tgunr!~davec@cpe-76-173-83-160.hawaii.res.rr.com] has quit (Read error: Connection reset by peer). [19:02:25] There's only 4 stack operations implemented as primitives, though. [19:02:27] I should probably just copy Forth in this regard [19:03:31] then there's ROLL [19:03:54] * tgunr [tgunr!~davec@2605:e000:1128:48:70ad:55d5:4015:e05b] has joined the channel. [19:04:39] ID -> SWAP -> ROT -> 3 ROLL -> 4 ROLL... [19:11:27] 2SWAP [19:11:29] ( x1 x2 x3 x4 -- x3 x4 x1 x2 ) [19:11:39] I was right on that one [19:15:57] I've found that using of quotes helps keep things organized when using more than the top 3 items on the stack. [19:16:06] * tgunr [tgunr!~davec@2605:e000:1128:48:70ad:55d5:4015:e05b] has quit (Read error: Connection reset by peer). [19:16:07] s/of// [19:16:46] * tgunr [tgunr!~davec@cpe-76-173-83-160.hawaii.res.rr.com] has joined the channel. [19:17:25] not sure what you mean... example? [19:22:58] I'm gonna rename my drop to init like in Kitten so I can get the Forth meaning of drop back [19:22:58] * tgunr [tgunr!~davec@cpe-76-173-83-160.hawaii.res.rr.com] has quit (Read error: Connection reset by peer). [19:24:02] * tgunr [tgunr!~davec@cpe-76-173-83-160.hawaii.res.rr.com] has joined the channel. [19:26:12] * tgunr [tgunr!~davec@cpe-76-173-83-160.hawaii.res.rr.com] has quit (Read error: Connection reset by peer). [19:26:47] hackerfoo: you mean keep the values inside quotes? [19:27:52] * tgunr [tgunr!~davec@cpe-76-173-83-160.hawaii.res.rr.com] has joined the channel. [19:29:55] 2OVER ( x1 x2 x3 x4 -- x1 x2 x3 x4 x1 x2 ) [19:30:07] hm not sure I agree with that one [19:30:58] Yeah. Most operations use one or two values, so if you have more than one extra, you are just juggling values. [19:31:27] The extra values can be packaged into a quote, and moved around much more easily. [19:33:57] but yeah in the code I'm writing I definitely have 5 variables and there's only a couple that make sense to group together [19:35:17] I've renamed ngetn to pickn [19:35:47] I was looking for a specific example, but it's more of a pattern that you can see throughout my library. [19:36:42] what code do you use for packaging? stuff1 stuff2 [] papply papply ? [19:37:07] [] ap20 [19:37:46] But the interesting thing is that you can put some code in there, rather than computing everything on the outside. [19:39:26] is there a way in your language to execute a quotation without leaving [] lying around [19:39:35] So, [reduce_stuff] ap20 swap do_stuff swap head reduce_further [19:40:16] head, or pullN swapN drop [19:41:44] I considered defining a function family for this, but I only define stuff that I've found a use for. [19:42:29] what does your language have a use for? :P [19:42:35] Or found that it's inconvenient. [19:43:17] Well, it makes for interesting conversations :) [19:44:05] I still don't understand how you get use out of the alternation thing [19:44:18] how do you get 2^n alternatives [19:44:27] instead of just 16 [19:45:29] erm well 17 you can use the operator 16 times [19:45:46] Use a balanced tree [19:46:09] 1 2 | 3 4 | | [19:46:47] 0 4 | 0 2 | + 0 1 | + [19:46:52] I will probably add balancing as an optimization. [19:47:08] seems you need to combine them somehow to get useful alternatives [19:49:06] hackerfoo: how do I make a branch fail I can't remember? [19:51:10] oh it's 1 [19:51:20] ! rather, but why does it take 2 values and not just one? [19:53:23] It's like drop if the second value (the one on the top) is True. [19:54:20] Drop is like const in Haskell [19:55:05] how do I define a function in the interpreter again? [19:55:16] you should put something in the docs [19:55:37] :def f: expr [19:55:42] Yeah [19:55:52] and you should have :help [19:56:14] :list, but there aren't descriptions yet [19:58:00] what about something to show the currently defined words? [19:59:55] :module, I think, but it will only work for words that haven't been compiled. [20:02:44] how does if work? [20:07:07] : [True] [True] [True] if [20:07:07] True [20:07:10] : [False] [False] [False] if [20:07:22] [20:17:17] True A B ifte -> A [20:17:51] It's more like C's ternary operator. [20:18:13] so what does if do? [20:22:40] Does the comment explain it well enough? https://github.com/HackerFoo/poprc/blob/master/lib.ppr [20:23:37] a [cond] [f] -> fa [20:24:07] As long as: a cond -> True [21:15:40] : :def num_to_letter: dup [0 == A] dip12 dup [1 == B] dip12 dup [2 == C] dip12 dup [3 == D] dip12 dup [4 == E] dip12 dup [5 == F] dip12 dup [6 == G] dip12 dup [7 == H] dip12 dup [8 == I] dip12 dup [9 == J] dip12 dup [10 == K] dip12 dup [11 == L] dip12 dup [12 == M] dip12 dup [13 == N] dip12 dup [14 == O] dip12 dup [15 == P] dip12 dup [16 == Q] dip12 dup [17 == R] dip12 dup [18 == S] dip12 dup [19 [21:15:46] == T] dip12 dup [20 == U] dip12 dup [21 == V] dip12 dup [22 == W] dip12 dup [23 == X] dip12 24 == Y Z ifte ifte ifte ifte ifte ifte ifte ifte ifte ifte ifte ifte ifte ifte ifte ifte ifte ifte ifte ifte ifte ifte ifte ifte ifte [21:15:50] cells.c:380: as_single: Assertion `k < (sizeof(alt_set_t) * 4)' failed. [21:16:02] hackerfoo: what's this got to do with alt_sets? [21:18:40] Wow. Each branch consumes a bit in the alt_set. [21:19:45] I don't understand why it should consume any [21:20:06] or if so how long it consumes it for [21:20:19] So this is like if(x == 0) { return A; if(x == 1) { return B; if(x == 2) .... [21:20:28] Nested 26 levels deep. [21:20:44] arg, my emacs process keeps returning with status = 1 [21:20:46] Well, sort of. [21:21:26] The thing is, it currently doesn't analyze alts to see if they are mutually exclusive. [21:21:59] I guess it's not nested, it's just like a lot of if's that could all return something. [21:23:20] Alts are consumed for an entire definition, there isn't really a way to recollect them once consumed. [21:25:47] so once the definition has finished running you get the alts back? [21:26:11] A better way to achieve what you're trying to do might be to build a quote [... D C B A], and then index into that with, similar to length: https://github.com/HackerFoo/poprc/blob/master/staging.ppr#L31-L32 [21:26:37] * xkapastel [xkapastel!uid17782@gateway/web/irccloud.com/x-vbjfgxthipaovpcg] has joined the channel. [21:26:51] what does the . do by the way? [21:27:03] Yeah. So breaking the definition may also help. That said, invoking it could consume them again. [21:27:29] . is composition of quotes: [1] [2+] . head -> 3 [21:28:03] I guess it was too obvious [21:42:26] yeah... I'm going back to my Kitten thing [21:43:05] actually nah looking at the forth woreds [21:45:46] 2ROT ( x1 x2 x3 x4 x5 x6 -- x3 x4 x5 x6 x1 x2 ) :S [21:58:12] y'know what I think I might use your definition of swap2 etc. along with roll for the other direction [22:03:55] I think it's good not to get carried away defining stuff. One crazy thing I could define is a three parameter dipMNO, which applies a M -> N quote O items down the stack. [22:04:17] It makes sense to define it, but I haven't needed anything like that. [22:04:47] I think that the library needs to be defined lazily, essentially. [22:05:39] I'm just trying to get some sort of Forth completeness (which isn't too hard) [22:05:40] If I try to sit and think about what I will need in advance, it just doesn't work. I don't know what I'll need, so it's a waste of time, other than for finding more bugs in the compiler. [22:06:02] That's reasonable. [22:06:22] really the interesting combinators are the ones that take quotations [22:06:33] I have a bunch of those already though [22:06:43] mainly Factor inspired [22:07:05] normally those ones are more useful [22:07:31] but yeah I think you have a problem with dip and you'll need the 3 digit version you just described [22:08:02] I'd maybe call it something longer like dip3.ap11 [22:10:02] hackerfoo: what about for the arity stuff you always put it at the end after a dot [22:10:12] so ap.11 and dip.11 vs dip2.11 [22:10:29] * jeaye [jeaye!~jeaye@unaffiliated/jeaye] has joined the channel. [22:10:31] then you can have more conventional names and the arity stuff is easier to read [22:12:52] also for "f dip.11 f ap.11" you could call that ap2.11 [22:12:58] I don't really plan on writing the three parameter dip. It's easy enough to nest them. [22:13:49] [[+] dip21] dip32 [22:14:13] It's just slightly annoying, but not that common. [22:17:19] do you have much intuition for what order variables should go on the stack because I don't.. =/ [22:18:09] I'm guessing ones you need after the loop should go deeper [22:18:46] and the loop condition should be the top most? [22:18:51] Whatever minimizes shuffling, so needed sooner => higher in the stack [22:19:12] oh so it's a time thing [22:19:29] Things that aren't modified, such as the function in a map, I tend to keep lower. [22:19:48] they're all modified, that's why I called them variables :P [22:20:08] maybe ones that you modify more often go higher [22:20:26] Conceptually. There has to be some way to talk about the values in English. [22:21:41] They don't have to be modified by the callee to be variables. Maybe parameter is a clearer description for these. [22:22:08] I know what you mean, in Kitten I can bind those to identifiers so they aren't even relevant [22:22:23] The reason I keep them lower is that I can use something like 'over', and I don't have to put it back. [22:22:54] I'm guessing your swap2 etc. is used to put stuff back [22:23:21] so yeah I think it should be ordered by time to access [22:23:42] then the next ones bubble up as you swap stuff out of the way [22:25:59] Right [22:26:36] But it doesn't really matter for Popr. The compiler eliminates it all in the end. [22:27:15] So I guess it's just a style question. [22:27:40] it matters for writing the code and understanding the code [22:27:44] and making the code shorter [22:28:01] so it's still an optimization [22:36:57] If you have a consistent style, it's also more likely that the same sequence will occur in multiple definitions, which then can be defined as a separate function. [22:36:57] * flogbot [flogbot!~flogbot@2001:4800:7814:0:2804:b05a:ff04:4ba7] has quit (Ping timeout: 240 seconds). [22:37:09] * flogbot [flogbot!~flogbot@2001:4800:7814:0:2804:b05a:ff04:4ba7] has joined the channel. [22:37:09] :leguin.freenode.net 353 flogbot = #concatenative :flogbot jeaye xkapastel tgunr jtimon FreeFull Sgeo_ evincar lonjil groovy2shoes mollerse dustinm` MDude kernelj rotty rgrinberg flout carvite earl_ shachaf erg koisoke merry rjungemann ephe_meral doublec diginet m_hackerfoo hackerfoo strmpnk kanzure jeremyheiler bmp PiDelport shmibs otoburb puckipedia [22:37:09] :leguin.freenode.net 366 flogbot #concatenative :End of /NAMES list. [22:37:13] yeah something like dup swap5 should have a better name [22:38:26] y'know what if you only read the variable I'm not sure it really qualifies for going higher in the stack [22:38:41] that's maybe related to what you were saying before about parameters [22:38:51] Yeah [22:39:06] you'd rather copy it from wherever it is and then use it [22:39:28] Dup'ing out is easier than swapping out and back in. [22:41:43] if you need to modify it at some point it kinda HAS to be at the top [22:42:45] maybe you need to consider the easiest execution paths as top priority [22:43:01] then you can have one super simple branch and a complicated one [22:43:21] optimize for the branch that does nothing [22:44:05] everything the complicated branch needs can remain buried [23:01:11] Just discovered Factor.app is not picjing up environment from .MasOSX file, why? [23:03:24] * evincar [evincar!~jon@173-228-12-107.dsl.dynamic.fusionbroadband.com] has quit (Ping timeout: 268 seconds). [23:05:44] hmm I've discovered a problem [23:05:58] I have an operator called .. which spills the contents of a list onto the stack [23:06:12] the arity of the output is therefore unknown... [23:08:45] This is driving me batty, not being able to use my emacs, I keep getting status = 1 https://www.dropbox.com/s/wsz9qkduhc0rpts/Screenshot%202017-06-12%2013.04.30.png?dl=0 [23:08:47] @spill?[~{xs..} => xs..]: [#{x xs..} x spill(xs)]`[#_#_]# [23:09:19] Yet, if I execute the commands manually in a terminal emacs works as expected [23:10:25] some weird sort of polymorphism where the arity of the input determines the output arity [23:10:49] what language is that? [23:15:07] kernelj: you would want to have a list whose length was part of its type [23:15:26] honestly if you're doing stuff like that it's not even worth it though, imo [23:15:29] xkapastel: I already have that [23:15:38] all lists are treated as tuples [23:15:41] it's really easy to do things that make the type theory blow up in complexity [23:15:52] so am i missing something? what's the problem [23:16:08] I was getting to that... the problem is when I use a combinator such as apply2 [23:16:19] which is "f dip f apply" [23:16:35] inside the combinators type I have fixed f to some stack effect [23:17:14] it won't unify between the two invokations [23:17:39] maybe my language isn't concatenative any more [23:17:42] i don't know how "stack effects" work, but in a traditional type theory if you have like `List n`, i imagine apply's type would just quantify over that `n [23:17:54] ` [23:18:24] you don't know how stack effects work and you're in #concatenative? [23:18:39] right, there's at least two ways to do type theory for concatenative languages [23:18:44] stack effects are the bad way imo [23:18:59] in that they're nothing like traditional type theory [23:19:03] you don't need to do it like that [23:19:21] you can just model stacks as a product type [23:19:26] it seems like stack effects are the perfect thing I was looking for and ignoring for too long [23:19:32] (a * (b * (c * ...))) [23:21:32] maybe you can give me an example [23:21:53] what's the type of #v#l l each[#f v f#] [23:22:19] guess I should explain my syntax [23:22:22] lol [23:22:23] #v and #l are locals [23:22:30] [] is a quotation [23:22:37] [#f ] is like a lambda taking f [23:22:41] # is call [23:23:05] each is defined as [23:23:06] [#{x xs..}#f x f# each(xs,f)]`[#_#_]# [23:23:31] #{x xs..} is a pattern match creating two locals x and xs [23:23:40] x is the head and xs.. is the tail [23:24:06] maybe you could just describe what you're trying to do [23:24:20] but anyway there's not much to explain, a "stack" is just a left leaning product type [23:24:28] a product type is the type of pairs [23:24:35] why is it left leaning rather than right leaning? [23:24:35] so like, (a * b) is a pair of an a and a b [23:24:46] I know what product types are [23:24:56] I'm just not sure how they apply to stacks [23:25:11] so you have a stack of an integer, a string, and a symbol [23:25:18] Integer String Symbol [23:25:36] you can model it as a pair of an integer and a (pair of a string and a (pair of a symbol and the default value))) [23:26:04] default value being what? [23:26:08] the same way lisp does lists [23:26:13] just some inert value [23:26:18] like lisp's nil [23:26:20] * evincar [evincar!~jonathanp@173-228-12-107.dsl.dynamic.fusionbroadband.com] has joined the channel. [23:26:24] for product types it's the identity type 1 [23:26:25] ok [23:27:24] anyway you're just describing the type representation of the stack, what about a quotation? [23:27:50] a quotation is a function [23:28:09] but I thought quotations weren't functions since you have to call them [23:28:16] you don't call functions? [23:28:25] you apply functions [23:28:40] maybe there's some terminology issue there because i thought these were synonyms [23:28:57] yeah, anyway I think there's some subtle distinction between normal functions and quotations [23:29:10] [3] is a function [23:29:21] forall e: e -> (Num * e) [23:30:29] so [+] is forall e: (Num * (Num * e)) -> (Num * e)? [23:30:34] yep [23:30:40] well [23:30:40] no [23:30:43] lol [23:30:45] + has that type [23:31:11] [+] is forall e. e -> (forall f. (Num * (Num * f)) -> (Num * f) * e) [23:31:32] kernelj: I'm taking down all the issues you've mentioned over the past few days and I'll get to them as soon as I can [23:31:42] thanks evincar [23:31:55] Gotta do stuff for my job tonight because I need to ship a thing [23:32:07] I'm hopefully starting a new job soon [23:32:21] Cool, from what to what? [23:32:35] from nothing to financial tech [23:33:06] I get to do some sort of quant stuff because the guy who was meant to be doing it quit [23:33:23] lots of numerical algorithms involved [23:33:31] gonna be working in F#, which I don't even know lol [23:33:37] Neat, not my cup of tea, but it seems like there are some interesting challenges in that field [23:34:12] F# is pretty nice, feels more or less like "OCaml.NET" [23:34:22] I miss Haskell when using it, though [23:34:27] yeah I know a bit of OCaml but only a little [23:34:52] using Haskell might be an option but I think we're aiming for .NET for the systems we're supposed to be developing [23:35:36] needs access to DB technologies and such [23:36:31] ok xkapastel what's the type of 'apply' or 'call' or whatever you want to call it [23:38:07] forall a b e. (((a -> b) * (a * e)) -> (b * e)) for non-dependent [23:39:33] isn't that the wrong way round? [23:39:54] hm? i'm assuming the stack has a function at the top, then the value [23:40:01] i mean you could do it the other way if you want [23:40:13] oh so the top of the stack is on the left? [23:40:16] yes [23:40:25] you're breaking all the traditions of #concatenative [23:40:36] rules were made to be broken [23:41:35] anyway this definition of apply is boring because it only takes one argument and outputs one thing [23:41:50] I want a definition that takes M arguments and outputs N [23:42:01] otherwise we're comparing apples and oranges [23:42:15] I made a prefix version of my language to try it, but it didn't work out. I wonder if people with a right-to-left native language might prefer prefix, or if that would even be called prefix. [23:42:15] that definition does that [23:42:24] a product type is "one thing" [23:42:50] that was the whole point of using products [23:43:01] yeah I think I misread it [23:43:10] it would be a pretty shitty concatenative language if you couldn't write functions that did M->N :P [23:43:27] indeed [23:43:47] hackerfoo's language requires you to write M and N explicitly [23:44:08] anyhow I don't see how this is much different from stack effects [23:44:22] you've just replaced the row variable with a product [23:44:38] the goal was to look like the standard body of programming language theory [23:44:41] That's what I do in Kitten [23:44:58] ok so what we're saying is that actually they're the same thing [23:45:05] well i don't know that they're the same [23:45:12] they can probably model the same phenomena [23:45:13] It's not really a "row", that usually refers to a certain formulation of extensible records [23:45:30] (Which is used in Kitten for sets of permissions) [23:45:34] that was the word hackerfoo used, I've seen 'sequence' in literature [23:45:42] it's like saying two languages are turing complete so "they're the same thing" [23:45:47] I've been calling it "stack polymorphism", "stack variables", etc. [23:46:24] I need a way to distinguish one way from the other otherwise they just seem equivalent [23:46:55] the advantage to stack effects for me is that I can build them up like a data structure [23:47:11] in basically the native value level langauge but with types instead [23:47:34] and I also introduce dependent variables into the mix [23:48:06] which I can do by just placing it within the stack effect somewhere [23:48:07] I got "row" from this, I think: https://github.com/leonidas/codeblog/blob/master/2012/2012-02-17-concatenative-haskell.md [23:48:18] I've seen it elsewhere, though.