--- Log opened Fri Aug 05 00:00:05 2016 |
--- Day changed Fri Aug 05 2016 |
00:00 | < catadroid> | Which I think is important as well |
00:00 | <&McMartin> | Mmm. I don't miss that so much |
00:00 | <~Vornicus> | So I see all this termonilogy go by and these arguments about type system power and frankly it all looks like way too much work. |
00:00 | <&McMartin> | What I miss is the inability to have variables and return values of interface type. |
00:00 | < catadroid> | I mean instance in terms of Haskell |
00:00 | <&McMartin> | Which is hiding information from clients |
00:00 | <&McMartin> | Oh, yeah |
00:00 | <&McMartin> | That's fixing the Java problem with interfaces~ |
00:00 | < catadroid> | I think we're violently agreeing |
00:01 | < catadroid> | Vornicus: that's fair |
00:01 | | himi [sjjf@Nightstar-v37cpe.internode.on.net] has quit [Ping timeout: 121 seconds] |
00:01 | <&McMartin> | Right |
00:01 | < catadroid> | For a lot of uses type systems are a hindrance |
00:01 | <&McMartin> | The counterargument is "it doesn't scale without having that stuff to channel the design" and the counterargument to that is "like hell it doesnt" |
00:02 | < catadroid> | It's all tradeoffs |
00:02 | <&McMartin> | Anyway, here's my one published (and old) Go program: https://github.com/michaelcmartin/tiledither |
00:02 | <~Vornicus> | and I guess part of this is that even now as technically an employee of a tech firm, I code alone. |
00:02 | <&McMartin> | My only other program in Go was an Ultima 4 savegame editor |
00:02 | <~Vornicus> | and I guess another part of it is that the programs I make aren't that big. |
00:02 | <&McMartin> | Which I abandoned because it didn't do anything I couldn't do with the struct module at the Python REPL. |
00:02 | < catadroid> | At the lowest level, types are required for processors to actually act on data |
00:03 | <&McMartin> | Yeah, but at that point you can make it just be a pile of equates in a header file you pass to the assembler |
00:03 | < catadroid> | Abstract and OO style types are supposed to capture the essence of concrete things so you can think about less of a system at a time |
00:03 | < catadroid> | But they can also be used to massively over capture that |
00:04 | <&McMartin> | Yeah. That's the part of type systems I actively dislike |
00:04 | < catadroid> | I think a lot of the value of types to me are the ability to let me use more of my short term memory and give me less context |
00:04 | <&McMartin> | Unless you are writing a simulated game world, there is no intrinsic benefit to the program organization matching some simulated philosophical ontology |
00:05 | <&McMartin> | (If you *are*, then the shape of the problem and the shape of the elements of the problem are identical, so you're good to go) |
00:05 | < catadroid> | Haha |
00:05 | < catadroid> | If only |
00:06 | <&McMartin> | Well, OK |
00:06 | <&McMartin> | Are close enough that it is theoretically possible to gain benefit from this |
00:06 | <~Vornicus> | It's like - every single thing I do, the type is already right there - every function already produces a particular type. why do I have to tell it? |
00:06 | <&McMartin> | That's an argument for type inference |
00:07 | < catadroid> | Because there's a lot of power in being able to say 'this algorithm works on anything that has these semantics' and have errors in that thinking discovered at compile time, for me |
00:07 | <&McMartin> | And then the thing gained is polymorphism, which is to say, "despite the fact that these two particular types are different, you can actually use them the same way" |
00:07 | <&McMartin> | And you use Python, PHP, JS, and Lua, where part of the language semantics mean that this requires no additional effort over any method call assuming everything was right in the first place |
00:08 | <&McMartin> | That's the Smalltalk/ObjC/Python method call semantics where a method call is bascially a dictionary lookup |
00:08 | < catadroid> | What I want is a formal explicit way to name ducks that doesn't require my user to tell me they're explicitly a duck |
00:10 | < catadroid> | Vornicus: if I can say 'this is what an iterator is' when I'm writing a standard library algorithm, then have the language enforce that, it means my code can be optimised way faster and as a large organisation we can iterate faster on code |
00:10 | < catadroid> | Also I don't have to think about lists and maps and arrays and what was I implementing again |
00:11 | < catadroid> | I could do that in documentation |
00:11 | < catadroid> | But the faster I can be told about an error when it might take me five minutes to repro that in the game system, the faster I can fix it |
00:11 | < catadroid> | I think types are perhaps a type of unit test |
00:12 | <~Vornicus> | other thing is, I don't get a build step |
00:12 | < catadroid> | That happen to allow compilers to preoptimise your code if that's something you care about |
00:12 | <~Vornicus> | which is nice on the one hand |
00:12 | < catadroid> | Yeah, my point is that it's an engineering trade off |
00:13 | < catadroid> | You spend more time annotating vs runtime checking |
00:13 | <~Vornicus> | because every time I've tried getting something that requires a build system going it's been *way too much work* |
00:13 | < catadroid> | Yup |
00:14 | < catadroid> | I mean, my personal thing with lisp right now is largely because the code is simple and obvious enough that I don't feel I *need* types |
00:14 | <~Vornicus> | basically it's always been "if you don't already know how to prep the build system in the first place, add a week and a half to the step of "display a window"" |
00:14 | < catadroid> | And types would have actively made gameplay code I've written in Lua worse |
00:15 | < catadroid> | Vornicus: that's actually something Go gets right, heh |
00:15 | <~Vornicus> | I'd love it if I could type and it'd go "hang on this is a vector what are you doing trying to divide by it" |
00:15 | < catadroid> | I hate cold systems |
00:15 | < catadroid> | Build* |
00:15 | < catadroid> | Vornicus: me to |
00:15 | <&McMartin> | OTOH, Go should really not have semantics that actually say "go download this stuff from the public internet and then incorporate it into your product" |
00:15 | < catadroid> | Isn't that kind of what typescript is trying to get at? |
00:16 | < catadroid> | McMartin: yeah... |
00:16 | <&McMartin> | I mean, on the one hand, sure, Maven |
00:16 | < catadroid> | I've heard it doesn't really enjoy things with multiple versions either |
00:16 | <~Vornicus> | <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script> |
00:16 | <&McMartin> | On the other, dudes, seriously, what is this |
00:17 | | * Vornicus wanders off to supervise Vash learning to bicycle |
00:18 | <~Vornicus> | So yeah. My problems with typed systems run basically along the lines of "build systems are too much of a pain to get running", "having to tell it what types I'm using is a pain too", and "I have no projects that I think would benefit" |
00:21 | | * catadroid nods |
00:21 | < catadroid> | Then it's reasonable not to use types ^^ |
00:22 | | Vorntastic [Vorn@Nightstar-s7g2c9.sub-70-215-4.myvzw.com] has joined #code |
00:30 | < Vorntastic> | Which is kind of a shame 'cause it feels like most of the cool features for these things are The Type System |
00:31 | < catadroid> | I'm not sure most type systems are intuitive at all |
00:31 | < catadroid> | I suspect this is part of the problem |
00:32 | < catadroid> | They become a primary part of thinking instead of aiding you solving the problem you set out to |
00:32 | < catadroid> | When you start thinking in types the problem becomes solving the types |
00:32 | < catadroid> | Which is tamable if you're used to that |
00:32 | <&McMartin> | Vorntastic: So, one complication on this is that it turns out that reasoning about types and reasoning about arbitrary dataflow problems are literally the same problem |
00:33 | <&McMartin> | Anything that can be determined about a program via dataflow analysis can in principle be formulated as a type-checking or type-inference problem |
00:33 | <&McMartin> | ... but they also evolved independentely, and while they use the same mathematical abstraction for both - the semilattice - they picked opposite meanings for what "Top" means -_- |
00:38 | < Vorntastic> | Heh |
01:12 | | JustLurk [justbob@ServerAdministrator.Nightstar.Net] has joined #code |
01:12 | | JustBob [justbob@Nightstar.Customer.Dissatisfaction.Administrator] has quit [NickServ (RECOVER command used by JustLurk)] |
01:12 | | mode/#code [+o JustLurk] by ChanServ |
01:12 | | JustLurk is now known as JustBob |
01:30 | | Vornlicious [Vorn@Nightstar-uhn82m.ct.comcast.net] has joined #code |
01:30 | | Vornlicious [Vorn@Nightstar-uhn82m.ct.comcast.net] has quit [[NS] Quit: Bye] |
01:32 | | Vorntastic [Vorn@Nightstar-s7g2c9.sub-70-215-4.myvzw.com] has quit [Ping timeout: 121 seconds] |
01:57 | | himi [sjjf@Nightstar-dm0.2ni.203.150.IP] has joined #code |
01:57 | | mode/#code [+o himi] by ChanServ |
02:04 | | * Derakon prepares for vacation by downloading a couple of Python MIDI libraries and a Markov chain library. |
02:05 | <&Derakon> | Probably nothing is going to come of this, but I think it'd be neat to try to write a music improvisator. |
02:23 | <&Derakon> | ...I should also grab a library of music. |
02:23 | <&Derakon> | Fortunately there are literally thousands of classical music MIDIs available. |
03:22 | <&[R]> | Hmm, I think I know someone who'd be interested in a project like that. |
03:24 | <&[R]> | It's toraton from #codelove on Slashnet. He was thinking about making a game where the music and the gameplay were heavily insync (but not that you directly control the music, like in GH/RB) |
03:26 | <&Derakon> | Yeah, my ideal would be that you'd have a body of music of reasonably consistent style, you could tag individual pieces with e.g. moods, and then it could improvise indefinitely in the style while biasing towards chosen tags on the fly. |
03:26 | <&Derakon> | But like I said, probably nothing will come of this! I am bad at actually following through on programming projects. |
03:28 | <&McMartin> | R: Presumably also not one where the music seeds the stage, a la Audiosurf or Melody's Escape? |
03:28 | <&Derakon> | I mean, in a super-ideal world, I'd have musicians selling their style metadata to indie game developers~ |
03:29 | <&[R]> | McMartin: I can't recall all the exact details, but I could dig up the log if you really wanted? |
03:29 | <&McMartin> | Eh |
03:34 | | * Vornicus thinks at vornball |
04:27 | <@Alek> | Derakon: that sounds interesting, but would be expensive to produce probably. XD |
04:29 | <&Derakon> | You mean the "selling artist styles" thing? |
04:29 | <&Derakon> | Yeah, probably. |
04:33 | | catadroid` [catadroid@Nightstar-n7ldd9.dab.02.net] has joined #code |
04:35 | | catadroid [catadroid@Nightstar-atnkn7.dab.02.net] has quit [Ping timeout: 121 seconds] |
04:50 | <@Alek> | I meant producing that much assorted but related music for a game. |
05:00 | | Alek [Alek@Nightstar-9qtiqv.il.comcast.net] has quit [Ping timeout: 121 seconds] |
05:04 | | Alek [Alek@Nightstar-9qtiqv.il.comcast.net] has joined #code |
05:04 | | mode/#code [+o Alek] by ChanServ |
05:13 | | Derakon is now known as Derakon[AFK] |
05:57 | | celticminstrel [celticminst@Nightstar-nhhr58.dsl.bell.ca] has quit [[NS] Quit: And lo! The computer falls into a deep sleep, to awake again some other day!] |
06:45 | | himi [sjjf@Nightstar-dm0.2ni.203.150.IP] has quit [Ping timeout: 121 seconds] |
08:50 | | catadroid` [catadroid@Nightstar-n7ldd9.dab.02.net] has quit [Ping timeout: 121 seconds] |
08:50 | | catadroid [catadroid@Nightstar-n7ldd9.dab.02.net] has joined #code |
09:08 | | Kindamoody[zZz] is now known as Kindamoody |
09:34 | | Kindamoody is now known as Kindamoody|afk |
09:54 | <~Vornicus> | aaarg, unexpected thwarting: minified js in the dev system |
09:56 | < catadroid> | Can you call an exterminator? |
09:56 | <@TheWatcher> | Arglblargl |
09:58 | <~Vornicus> | I wish |
09:58 | <~Vornicus> | If I had the budget I would *be* the exterminator. |
09:59 | < catadroid> | Be the exterminator! |
10:03 | <~Vornicus> | I want to be! |
10:55 | | * TheWatcher args, stab and stab and stab mysql |
10:55 | <@TheWatcher> | I have debug enabled, why u no let me use "SHOW PROCEDURE CODE"?! |
11:03 | | catadroid` [catadroid@Nightstar-djta7n.dab.02.net] has joined #code |
11:05 | | Vornicus [Vorn@ServerAdministrator.Nightstar.Net] has quit [Connection reset by peer] |
11:05 | | catadroid [catadroid@Nightstar-n7ldd9.dab.02.net] has quit [Ping timeout: 121 seconds] |
13:05 | | catadroid` is now known as catadroid |
13:06 | <@gnolam> | Oh hey. Surprise half day off! |
13:08 | < catadroid> | Surprise? |
13:09 | <@abudhabi> | Surprise subtext! :V |
13:10 | < catadroid> | <.< |
13:20 | | himi [sjjf@Nightstar-v37cpe.internode.on.net] has joined #code |
13:20 | | mode/#code [+o himi] by ChanServ |
13:34 | | * catadroid might attempt to set up a blogger blog thing |
13:43 | < ToxicFrog> | I should blog more about tech things. |
13:47 | | macdjord [macdjord@Nightstar-r9vt2h.mc.videotron.ca] has joined #code |
13:47 | | mode/#code [+o macdjord] by ChanServ |
13:49 | | macdjord|slep [macdjord@Nightstar-r9vt2h.mc.videotron.ca] has quit [Ping timeout: 121 seconds] |
14:14 | | * ToxicFrog returns from getting breakfast |
14:14 | < ToxicFrog> | \aeslin{Hail! Hail the smoked salmon platter!} |
14:34 | <@Azash> | Smoked salmon is so good |
14:39 | < catadroid> | Well, I gone and done it, http://k-reducer.blogspot.com now exists |
14:41 | < catadroid> | I suppose I should begin writing down some thoughts on types |
15:00 | | * TheWatcher fingertappity, fires up the refactor tractor |
15:03 | < catadroid> | Brmmmm |
15:38 | | celticminstrel [celticminst@Nightstar-nhhr58.dsl.bell.ca] has joined #code |
15:38 | | mode/#code [+o celticminstrel] by ChanServ |
17:19 | < catadroid> | Alright, I've now got a long blog post that I need to proof read, but I think I've got the essence of my thoughts on types down |
17:26 | <@celticminstrel> | Yay for long blog posts on |
17:26 | <@celticminstrel> | programming stuff. |
17:26 | <@celticminstrel> | Whoops, line break. |
17:33 | | catadroid` [catadroid@Nightstar-1v4aos.dab.02.net] has joined #code |
17:35 | | catadroid [catadroid@Nightstar-djta7n.dab.02.net] has quit [Ping timeout: 121 seconds] |
17:40 | | Vornicus [Vorn@ServerAdministrator.Nightstar.Net] has joined #code |
17:40 | | mode/#code [+qo Vornicus Vornicus] by ChanServ |
17:49 | | Kindamoody|afk is now known as Kindamoody |
17:53 | | catalyst [catalyst@Nightstar-890.fhp.187.81.IP] has joined #code |
18:04 | < catalyst> | http://k-reducer.blogspot.co.uk/2016/08/type-systems-and-human-cognition.html |
18:04 | < catalyst> | there you go |
18:05 | < catalyst> | (Also, any feedback on errors or style is handy) |
18:37 | <@celticminstrel> | ...oh right, I was in the middle of reading that and now I've switched computers. Whoops. |
18:37 | <@celticminstrel> | I'll finish it a bit later, maybe in an hour or so. |
19:46 | <@Pi> | catalyst: Neat! |
19:46 | <@Pi> | I think I get a bit better what you were getting at earlier: the crux of the matter is whether the concretion needs to know or care about the abstraction, right? |
19:47 | <@Pi> | catalyst: In that sense, I think type classes may combine the best of both worlds. |
19:48 | < catalyst> | Yeah |
19:48 | < catalyst> | Although everything I've seen about type classes still needs explicit buy-in |
19:48 | <@Pi> | Like descriptive type systems, they allow you to define implementations for abstractions independent of the original concrete types, so you can plug type classes over things without those things needing to be aware of them beforehand. |
19:49 | <@Pi> | This allows very powerful and organic extension of libraries by other libraries, and stuff like that, without coordination or hard linking. |
19:50 | <@Pi> | Also unlike purely nominal / structural protocols like Go interfaces, you don't have to worry about name clashes, because each type class stays a separate name space. |
19:51 | < catalyst> | But that still doesn't necessarily let me infer a type from existing properties of the object |
19:51 | <@Pi> | So there's a degree of hygiene and modularity to it, like the "prescriptive" end of that spectrum, but without the brittleness. |
19:51 | < catalyst> | I still need to explicitly instance typeclass x data |
19:52 | < catalyst> | I think my argument is that there's something nice in being able to name a collection of duck typed characteristics |
19:52 | <@Pi> | Right, but that's the whole point: you avoid accidental, meaningless, and conflicting / unsound instances that way. |
19:52 | < catalyst> | Sure, but that's not my aim |
19:53 | <@Pi> | What would not declaring the instance actually gain you? |
19:53 | < catalyst> | I'm prepared to accept some false positives, in exchange for not needing to be explicit except at point of use |
19:54 | <@Pi> | You don't have to be explicit at point of use: you only need one instance declaration ever. |
19:54 | < catalyst> | Because in my example, that moves Name/Price into an explicit instance in Store |
19:54 | <@Pi> | It's global. |
19:54 | < catalyst> | Yeah, but it introduces a dependency I can avoid by using interfaces rather than concrete instances of typeclasses |
19:54 | <@Pi> | Dependency? |
19:55 | < catalyst> | So, in that case my Product type needs to be in a separate package as in the prescriptive case |
19:55 | < catalyst> | Otherwise BookData x Product and CakeData x Product become part of Store |
19:55 | < catalyst> | and I don't want them there |
19:55 | <@Pi> | Type classes don't affect your package structure. |
19:55 | < catalyst> | I want that to be implicit by knowing what things a ProductData has |
19:56 | < catalyst> | I'm not against type classes, I'm just suggesting that they're still prescriptive |
19:57 | <@Pi> | As far as I understand these definitions, I'm not sure they are: they don't prescribe or limit your structure in any way like the prescriptive example does. |
19:57 | < catalyst> | Assume that the example in that post is representative of many different properties |
19:57 | < catalyst> | But they do require me to define typeclass x data explicitly |
19:57 | <@Pi> | They give you just as much freedom as the descriptive case, but more safety. |
19:57 | < catalyst> | I disagree |
19:58 | < catalyst> | Can I ask a specific question? |
19:58 | <@Pi> | Sure |
19:58 | < catalyst> | If I have a typeclass Foo that requires a Bar :: Int -> Int, for example, will my type T be a Foo unless I explicitly define an instance of Foo for T? |
19:59 | < catalyst> | (I.e. if it has a Bar from somewhere else, does that count?) |
19:59 | <@Pi> | What do you mean by "typeclass Foo that requires a Bar :: Int -> Int" exactly? |
19:59 | < catalyst> | one sec, I can do this better in a pastebin |
20:00 | <@Pi> | Basically a type class just has a set of method signatures (like an interface), and an instance declaration just declares the implementations of those methods for some specific concrete type. |
20:01 | < catalyst> | Yeah, my issue is that you must have an instance declaration |
20:01 | <@Pi> | You have pretty much complete freedom of where you put the declarations and definitions, in terms of package structure. |
20:01 | < ToxicFrog> | Pi: "if I have a method for a concrete type T but have not explicitly declared that method as being an instance of typeclass TC, can I still pass my T to a function expecting a TC" |
20:02 | <@Pi> | catalyst: It's no different than having to have matching signatures with descriptive interfaces; it's just more safe and namespaced. |
20:03 | < catalyst> | I don't see how that can be the case where I want my typeclass in the package with the thing that uses it, and expect to not need to instance it for everything explicitly in that package, which means that that implementation is no longer in the original packages |
20:03 | <@Pi> | ToxicFrog: I'm not sure that makes sense in Haskell terms; methods are specifically a type class concept. It doesn't really make sense to talk of concrete types having methods; just type classes have them. |
20:03 | < catalyst> | I want Price defined *only* in Book and Cake, I do not want it defined in Store, only checked |
20:03 | <@Pi> | catalyst: You can put instance declarations in any package. |
20:04 | < catalyst> | But they must, presumably, know about the typeclass? |
20:04 | <@Pi> | Yes. |
20:04 | <@Pi> | They just link a type class with a concrete type. |
20:04 | <@Pi> | But both the type class and concrete type can be in independent libraries. |
20:05 | < catalyst> | Book does not depend on Store if the typeclass in Store is descriptive, it does if the type is prescriptive |
20:05 | <@Pi> | That's why you can do things like make library A speak to library B using library C, without library A and B knowing anything about each other's abstractions and concretions. |
20:05 | < catalyst> | It matters because I do not want my BookData to explicitly be a ProductData, and needing to instance it makes it explicit |
20:07 | <@Pi> | Why don't you want it to be explicit, and how does it differ from the fact that you implicitly have to manually match the method names signatures anyway in the Go-like interfaces case? |
20:07 | < catalyst> | Because the match is implicit, not explicit |
20:07 | <@Pi> | The latter comes down to exactly the same thing as an instance declaration, except that you don't have the freedom to change the names if you want to or need to. |
20:08 | <@ErikMesoy> | catalyst: Maybe I'm just sleepy, but can you spell out for me why we need to avoid a cyclic dependency? |
20:08 | <@ErikMesoy> | woops, I appear to have been scrolled up and may have missed an answer to that |
20:09 | <@Pi> | Yes, but "implicit" in this case just means you're doing it with more constraints: you're forced to match the method names directly, instead of having the freedom to bridge differing vocabularies, like you have with type classes. |
20:10 | <@Pi> | catalyst: If you took type classes and made them less flexible by removing the namespacing they provide, and made them automatically match on direct names, then you basically end up with Go-like structural interfaces. |
20:11 | < catalyst> | But my argument is that those are qualitatively different to develop with, |
20:12 | < catalyst> | ErikMesoy: I can provide you a longer explanation if that would help |
20:13 | <@Pi> | catalyst: Well, consider this: let's say your system is organically growing bottom-up, and your Book and Cake types both end up with a "price" property, but Book ends up with a "title" and Cake ends up with a "name" |
20:13 | <@Pi> | But you want to use the Book's title and the Cake's name equivalently, as far as the Product abstraction is concerned. |
20:14 | <@Pi> | With Go-like interfaces, you can't do this: you have to choose one to standardise on, and then modify your concretions to match it. |
20:14 | <@Pi> | It becomes prescriptive. |
20:14 | <@Pi> | The abstraction is dictating your concrete implementations again. |
20:14 | < catalyst> | Aye, I see that |
20:15 | < catalyst> | (I mean you explanation has caused me to see it) |
20:15 | < catalyst> | your* |
20:16 | <@Pi> | Whereas with type classes, you don't have this problem, because you can just say: |
20:16 | <@Pi> | class Product a where price :: a -> Price; label :: a -> String |
20:16 | <@Pi> | instance Product Cake where price = cakePrice; label = cakeName |
20:16 | <@Pi> | instance Product Book where price = bookPrice; label = bookTitle |
20:16 | <@Pi> | etc. |
20:16 | < catalyst> | But I still have a different problem where I need to define those |
20:16 | < catalyst> | That solves a different (and differently interesting) problem than implicitly |
20:16 | <@Pi> | And the Product abstraction can live in its own namespace, and all of Store and Book and Cake can be in separate libraries and know nothing about each other. |
20:17 | <@Pi> | You have complete freedom about where you declare the classes and instances. |
20:17 | < catalyst> | This is part of the problem though - you end up needing another library for that abstraction |
20:17 | <@Pi> | And libraries only need to mention or depend on the type class to the extent they actually want to. |
20:17 | <@Pi> | You don't necessarily need another library. |
20:17 | <@Pi> | I just said that's an option, if you actually do want it in a separate library. |
20:17 | <@Pi> | You're free to keep it anywhere else too :) |
20:17 | < catalyst> | But I do if I want to avoid the cylic dependency I mentioned earlier |
20:18 | < catalyst> | I feel like we're talking orthogonally to what I'm trying to convery |
20:18 | < catalyst> | convey* |
20:18 | <@Pi> | You have the same dependency in the Go-like interfaces case: being an implicit dependency doesn't make it any less of a dependency. |
20:18 | <@Pi> | If you change your concretion's interface, your code will still explode. |
20:19 | < catalyst> | But the point is that I can continue to build bottom up as if I was using duck typing |
20:19 | < catalyst> | And accept that's something I'm prepared to make a tradeoff on |
20:19 | <@Pi> | Type classes just give you greater freedom and flexibility in how you express and manage it. |
20:19 | < catalyst> | I disagree, I think they give me different freedoms and flexibility |
20:19 | <@Pi> | You can continue building bottom up with type classes too: even more so, because you don't run into name mismatch problems like the one I outlined above. |
20:20 | <@ErikMesoy> | Also are you using "instance of" to mean both object-of-class and subclass-of-superclass? |
20:20 | <@Pi> | ErikMesoy: I'm using it specifically in the Haskell sense here. |
20:20 | <@Pi> | It's not really the same as the OO sense. :) |
20:20 | <@Pi> | Kinda related, though. |
20:21 | <@ErikMesoy> | Pi: Are you speaking for catalyst? Or is this your post? I'm confused now. |
20:21 | <@ErikMesoy> | I meant that question to the blogpost. |
20:21 | <@Pi> | Oh, sorry, ignore me then! |
20:21 | <@Pi> | I thought you were asking me. |
20:21 | <@Pi> | (I wasn't speaking for catalyst. :) |
20:21 | < catalyst> | Ah, I've used it ambiguously |
20:21 | < catalyst> | ErikMesoy: I'll fix that shortly |
20:22 | | Kindamoody is now known as Kindamoody|afk |
20:24 | < catalyst> | Pi: My entire point is that I want to write an abstraction that's of use to the Store methods, but that my other libraries don't care about (except that, as you point out, they may orgaically need to - that's Store's issue to figure out. At which point defining type classes to mutate them explicitly might help, but I don't *need* to do that until it becomes an issue) |
20:25 | <@Pi> | catalyst: The thing is, other libraries don't need to care about type classes either. |
20:26 | <@Pi> | You need an instance declaration somewhere to declare that the instance actually makes sense, but you have complete freedom about where that appears. It doesn't have to be part of the libraries that define either the type class or the data types in question. |
20:26 | < catalyst> | I still feel like you're trying to persuade me to always use type classes |
20:26 | <@Pi> | I'm not trying to persuade you, I'm just trying to explain how they work. |
20:27 | <@Pi> | Or trying to correct my understanding of what you're saying. |
20:28 | <@Pi> | Because from what I understand so far, type classes should be addressing the dependency concerns and so on that you have. :) |
20:28 | < catalyst> | I disagree, based on the fact that for things to be decoupled it needs to be defined separately |
20:28 | <@Pi> | So either I'm failing to explain type classes, or my understanding of that is wrong. |
20:29 | <@Pi> | It doesn't _need_ to be defined separately; it just _can_ be defined separately. |
20:29 | <@Pi> | You have complete freedom, in terms of libraries and packages, about where they are defined. |
20:30 | <@Pi> | You can think of all type classes and instances as just all being merged into one giant global consistent graph across all packages at compile time. |
20:30 | <@Pi> | That's an important property that type classes give you that (say) Scala implicits don't: that property of global consistency. |
20:30 | <@Pi> | (but that's a whole other tangent) |
20:35 | < catalyst> | I agree that it can be an important property, and I recognise that it can be helpful, but I think that's still a tradeoff - I get local consistency without requiring everything that wants to use Product to immediately update if that definition changes |
20:35 | < catalyst> | Using an implicit interface |
20:36 | <@Pi> | catalyst: But with implicit interfaces, you _do_ need to update the concrete types if the Product definition changes. |
20:36 | <@Pi> | For example, if you split "price" into "price_zar" and "price_usd", then you actually need to update Book and Cake to match. |
20:37 | <@Pi> | With type classes, you don't have to: Book and Cake stay the same, and you only have to update their instance definitions. |
20:37 | <@Pi> | (This is a critical thing if Book and Cake are in libraries you don't control, say.) |
20:37 | < catalyst> | But I *have* to update their instance definitions |
20:38 | <@Pi> | Yes, but the point is you actually can. |
20:38 | < catalyst> | But I don't need to if I implicitly match |
20:38 | <@Pi> | In the case where they're in a separate library. |
20:38 | <@Pi> | I'm not sure I understand: if you implicitly match, then you do need to update them if the Product interface changes. |
20:38 | <@Pi> | If you rename a method in Product, you have to rename it in all the concrete types too. |
20:39 | < catalyst> | If I implicitly match, I don't need to write the explicit instances in the first place |
20:39 | <@Pi> | Yes, but that just loses flexibility. |
20:40 | <@Pi> | Your concrete type now just doubles as the instance decleration. |
20:40 | < catalyst> | I believe that it gains flexibility since it's less code I must write before it works |
20:40 | < catalyst> | I admit it's the equivalent of less testing |
20:40 | <@Pi> | I'm not sure I see how less code means more flexibility. |
20:40 | <@Pi> | More flexibility means being able to flex it in more ways. :) |
20:40 | < catalyst> | Less code up front means less I must write before it does anything at all |
20:41 | <@Pi> | Right, but at the expense of flexibility, is what I'm trying to say. |
20:41 | < catalyst> | Using type classes for each type means more code before it can work, but also more regression testing (essentially) |
20:41 | <@Pi> | Instance declarations are usually small: just a mapping of names to names. |
20:41 | < catalyst> | But the *exist* |
20:42 | < catalyst> | I don't care that they're small |
20:42 | < catalyst> | They're there at all |
20:51 | < catalyst> | they* |
21:05 | <@abudhabi> | Hm. |
21:06 | | * abudhabi rubber ducks himself before even finishing writing the problem out. |
21:08 | <@abudhabi> | OK, new problem. |
21:09 | <@abudhabi> | I'm trying to convert the number 250 into base 25, but the notation is such that the digits are all Latin letters, with the letter I skipped. |
21:12 | <@Azash> | w.. what |
21:13 | <@abudhabi> | ABCDEFGJKLMNOPQRSTUVWXYZ |
21:13 | <@abudhabi> | Those are digits. |
21:13 | <@abudhabi> | How do you denote 250 with those? |
21:14 | <@abudhabi> | Uh, forgot H. |
21:15 | <@abudhabi> | So far, the answer I'm getting is: JZ. |
21:15 | <@abudhabi> | I wonder if that's correct. |
21:17 | <@ErikMesoy> | So Z is followed by AA and so forth? |
21:18 | <@Pi> | abudhabi: Do you know how to do base conversion in general? |
21:18 | <@ErikMesoy> | JZ seems correct. |
21:18 | <@ErikMesoy> | JZ would seem to be the "ten-ty" of this base 25. |
21:19 | <@abudhabi> | Pi: I knew once, but forgot. |
21:20 | <@Pi> | abudhabi: Do those digits include an additional 0, by the way? |
21:20 | <@abudhabi> | No. |
21:20 | <@abudhabi> | It's letters, all the way down. |
21:20 | <@Pi> | There are only 24 digits, not 25 |
21:20 | <@Pi> | Oh, needs H? |
21:20 | <@abudhabi> | Yes. |
21:21 | <@abudhabi> | I cannot alphabet. |
21:21 | <@Pi> | So A = 0 ? |
21:21 | <@abudhabi> | Sure, I guess? |
21:21 | <@ErikMesoy> | A=1, I believe |
21:21 | <@abudhabi> | Doesn't matter. I know the designations for the first 25 positions, I just want to know the designation for the 250th position. |
21:22 | <@Pi> | abudhabi: Oh, it certainly does matter |
21:22 | <@ErikMesoy> | abudhabi: is the first designation "A", and is the 26th designation "AA"? |
21:22 | <@ErikMesoy> | If so, then the 250th is JZ. |
21:22 | <@abudhabi> | The way I figure: First is A. 26th is AA. |
21:23 | <@Pi> | abudhabi: So it's bijective base 25 ? |
21:23 | <@Pi> | As in https://en.wikipedia.org/wiki/Bijective_numeration |
21:24 | <@abudhabi> | I think so. |
21:25 | <@ErikMesoy> | If A were the zeroth, then the 250th would be KA. |
21:26 | <@abudhabi> | The first *number* is A. |
21:33 | <@gnolam> | ErikMesoy: surely you mean LA? |
21:37 | <@ErikMesoy> | gnolam: No, because I'm not treating A as a zero digit here, I'm treating it as a positional entry. AB is not equal to B. |
21:42 | <@abudhabi> | What I'm working on is Traveller ship design rules, extending the core tables to allow me to design a space station twice the size of that building in which NASA parks its spaceships. |
21:50 | | Namegduf [namegduf@Nightstar-lcgn9d.beshir.org] has joined #code |
21:50 | | mode/#code [+o Namegduf] by ChanServ |
22:22 | <@Alek> | KZ, since H is skipped. |
22:23 | <@Alek> | I is skipped even |
22:23 | <@Alek> | JZ assumes I is still present |
22:23 | <@ErikMesoy> | No, it doesn't. |
22:23 | <&[R]> | Z == 25; AZ == 50; BZ == 75; CZ == 100; DZ == 125; EZ == 150; FZ == 175; GZ == 200; HZ == 225; JZ == 250 |
22:24 | <&[R]> | KZ == 275 |
22:24 | <@Alek> | wait. hm. |
22:24 | <&McMartin> | AZ should be 26 |
22:24 | <@Alek> | I was slightly off somewhere, then. hm. |
22:24 | <@Alek> | McM: that's AA |
22:24 | <&McMartin> | Oh, right, derp |
22:24 | <&McMartin> | Sorry, clearly still tea-deprived over here |
22:25 | <&[R]> | AZ would be 26 if this numbering model were actually really base25 with the listed notation. |
22:25 | <@Alek> | ah, I have it. why I got mixed up. A needs to be 0, not 1. |
22:25 | <&[R]> | Yes |
22:26 | <@Alek> | AD: only twice the size? how disappointing. :P |
22:27 | <@Alek> | so. A==AA==AAA. :P |
22:28 | <&[R]> | No. |
22:28 | <&[R]> | A == 1; AA == 25 + 1; AAA == 25 * 25 + 25 + 1 |
22:28 | <@Alek> | I'm saying how it should be. <_< |
22:29 | <&[R]> | Yeah, in real base25 it would be. |
22:29 | <&[R]> | But this isn't actually base25, it's something like it |
22:36 | <@ErikMesoy> | Alek: Do you also think it should be the case that 1 = 11 = 111? |
22:39 | | Kindamoody|afk is now known as Kindamoody |
22:53 | <&[R]> | ErikMesoy: he was saying it should be like 0 == 00 == 000 |
22:54 | <@Alek> | what he said |
23:09 | | catadroid` [catadroid@Nightstar-1v4aos.dab.02.net] has quit [[NS] Quit: Bye] |
23:40 | | Kindamoody is now known as Kindamoody[zZz] |
--- Log closed Sat Aug 06 00:00:59 2016 |