--- Log opened Tue Jul 26 00:00:05 2016 |
00:10 | | Kindamoody is now known as Kindamoody[zZz] |
01:16 | | himi [sjjf@Nightstar-dm0.2ni.203.150.IP] has joined #code |
01:16 | | mode/#code [+o himi] by ChanServ |
02:19 | | catadroid` [catadroid@Nightstar-k6cq59.dab.02.net] has joined #code |
02:21 | | catadroid [catadroid@Nightstar-1o014u.dab.02.net] has quit [Ping timeout: 121 seconds] |
02:33 | | Turaiel[Offline] is now known as Turaiel |
03:00 | | macdjord|slep [macdjord@Nightstar-r9vt2h.mc.videotron.ca] has quit [Connection closed] |
03:01 | | macdjord|slep [macdjord@Nightstar-r9vt2h.mc.videotron.ca] has joined #code |
03:01 | | mode/#code [+o macdjord|slep] by ChanServ |
03:18 | | macdjord|slep [macdjord@Nightstar-r9vt2h.mc.videotron.ca] has quit [Connection closed] |
03:19 | | macdjord|slep [macdjord@Nightstar-r9vt2h.mc.videotron.ca] has joined #code |
03:19 | | mode/#code [+o macdjord|slep] by ChanServ |
03:29 | | macdjord|slep [macdjord@Nightstar-r9vt2h.mc.videotron.ca] has quit [Ping timeout: 121 seconds] |
03:32 | | macdjord [macdjord@Nightstar-r9vt2h.mc.videotron.ca] has joined #code |
03:32 | | mode/#code [+o macdjord] by ChanServ |
04:12 | | macdjord [macdjord@Nightstar-r9vt2h.mc.videotron.ca] has quit [Connection closed] |
04:13 | | macdjord [macdjord@Nightstar-r9vt2h.mc.videotron.ca] has joined #code |
04:13 | | mode/#code [+o macdjord] by ChanServ |
04:19 | | mac [macdjord@Nightstar-r9vt2h.mc.videotron.ca] has joined #code |
04:19 | | mode/#code [+o mac] by ChanServ |
04:23 | | macdjord [macdjord@Nightstar-r9vt2h.mc.videotron.ca] has quit [Ping timeout: 121 seconds] |
05:05 | | Derakon is now known as Derakon[AFK] |
05:08 | | * Alek just sat down and did the recursive isEven exercise. |
05:08 | <@Alek> | I.... think I did good? |
05:08 | <@Alek> | function isEven(number) { |
05:08 | <@Alek> | if (number == 0) |
05:08 | <@Alek> | return true; |
05:08 | <@Alek> | else if (number == 1) |
05:08 | <@Alek> | return false; |
05:08 | <@Alek> | else if (number < 0) |
05:08 | <@Alek> | return isEven(number + 2); |
05:08 | <@Alek> | else |
05:08 | <@Alek> | return isEven(number - 2); |
05:08 | <@Alek> | } |
05:08 | <@Syloq> | pastebin... |
05:09 | <@Alek> | sorry. |
05:11 | <&McMartin> | Looks like you should be able to make some easy testcases for that to make sure it works out |
05:12 | <&McMartin> | Don't make them too big, JS doesn't do the optimization that makes code like this safe~ |
05:16 | <@Syloq> | I'll never understand the need/use of recursive functions. If something goes wrong it eats up so much time trying to debug. Not to mention readability is horrible. |
05:18 | <&McMartin> | Then you're doing it wrong, basically~ |
05:18 | <&McMartin> | You can read the past execution up to the failure point out of the stack trace, normally |
05:19 | | JustLurk [justbob@ServerAdministrator.Nightstar.Net] has joined #code |
05:19 | | JustBob [justbob@Nightstar.Customer.Dissatisfaction.Administrator] has quit [NickServ (RECOVER command used by JustLurk)] |
05:19 | | JustLurk is now known as JustBob |
05:19 | | mode/#code [+o JustBob] by ChanServ |
05:20 | <@Syloq> | Depending on your language. sure. |
05:20 | <&McMartin> | C++, here |
05:20 | <&McMartin> | Cases where it gets stickier are things like DFS, where you can do it recursively but you usually wouldn't so that you can swap out search strats... |
05:21 | <&McMartin> | ... but at that point you have an extra stack you're dicking around with that really might as well be the call stack, too |
05:21 | <@Syloq> | I've just found that no matter what language you're using it just becomes a burden to someone at some point. |
05:23 | <&McMartin> | So does iteration |
05:23 | <&McMartin> | That said, unless your langauge has tailcall elimination, the usual clue that you should be doing it recursively is that you find yourself re-implementing function call mechanics. |
05:23 | <&McMartin> | (Usually while marshalling/demarshalling/parsing/etc recursive data structures) |
05:28 | <@Syloq> | heh I suppose so. |
05:29 | <@Syloq> | I just know that I wouldn't ever do it with a scripting language like JS. Unless you're trying to prove that you can....not that you should. |
05:29 | <&McMartin> | Which this one is, since it's teaching recursive problems |
05:29 | <&McMartin> | (That said: parsing JSON without use of eval) |
05:29 | <&McMartin> | (You want the recursive calls for the elements of arrays and objects) |
05:32 | <@Syloq> | Well I suppose, but why reinvent the wheel? I get the learning aspect of "Yes you can create recursive functions and this is how..." The real world has tons of libraries and have been battle tested..much more than anything you could write alone. |
05:36 | <@Pi> | Syloq: As another perspective, recursion and iteration are ultimately different syntaxes for the same thing. |
05:37 | <@Pi> | Or alternatively, iteration is the special case of tail recursion. |
05:37 | <@Syloq> | Sure. I can see that. |
05:38 | <@celticminstrel> | Still haven't solved that SDL_ttf+OpenGL issue... I should get back to it, but I'm really not sure how to approach the problem... |
05:42 | <@Alek> | McM: the example boxes provide testcases. |
05:42 | <&McMartin> | Pi: Disagree: recursion is strictly more poewrful than iteration |
05:42 | <&McMartin> | Iteration + Cons is as powerful, though :D |
05:44 | <@Pi> | McMartin: That's what I meant with iteration being the special case of tail recursion, yeah. |
05:55 | | * Vornicus <3 recursion |
06:10 | | Turaiel is now known as Turaiel[Offline] |
06:26 | | Vornicus [Vorn@ServerAdministrator.Nightstar.Net] has quit [Connection closed] |
07:05 | | Kindamoody[zZz] is now known as Kindamoody |
07:25 | <@Alek> | gah. why am I getting an unexpected identifier from what seems to be a straightforward if boolean check? |
07:25 | < catadroid`> | Check spelling and case? |
07:26 | < catadroid`> | Missing and /or accidental semi colons? |
07:30 | <@Alek> | that didn't seem to be the case. |
07:31 | <@Alek> | but replacing the if with a ternary with a null-effect else worked. -_- |
07:31 | | * Alek glares. |
07:31 | <@Alek> | http://eloquentjavascript.net/03_functions.html#h_3rsiDgC2do |
07:31 | <@Alek> | this exercise. |
07:32 | <@Alek> | and yeah, I know my code won't show up there. >_> |
07:35 | < catadroid`> | What's the full error message? |
07:37 | <@Alek> | Uncaught SyntaxError: Unexpected identifier (line 8) |
07:37 | < catadroid`> | Ah, that's not overly helpful |
07:38 | | Kindamoody is now known as Kindamoody|afk |
07:38 | <@Alek> | ... |
07:38 | <@Alek> | well damn. |
07:38 | <@Alek> | so apparently the sample code using if I looked at earlier did not use parens around the comparison. |
07:38 | <@Alek> | but it was supposed to. |
07:38 | <@Alek> | and that's what the problem was. |
07:38 | | * Alek headdesks. |
07:39 | | * catadroid` nods |
07:40 | <@Alek> | that solved, if works. ternary works too, but there really is no need since there isn't anything to do on false. |
07:40 | <@Alek> | so I just had it set the count to itself, which is really wasteful. >_> |
07:40 | <@Alek> | so if is the better way to go here. |
07:41 | <@Alek> | and that's the chapter done. off to bed with me. |
07:41 | < catadroid`> | Night! |
07:42 | <@Alek> | I swear, I'm gonna have to put huge posters around me, for each language, showing example usage of every single basic command. |
07:42 | <@Alek> | because I can NOT trust my memory. |
07:44 | <@Alek> | there also needs to be some kind of guide on when to use semicolons and when not to. <_< |
07:45 | < catadroid`> | In javascript it's worse because it automatically inserts them at the end of every line regardless |
07:53 | | catadroid` [catadroid@Nightstar-k6cq59.dab.02.net] has quit [[NS] Quit: Bye] |
07:54 | <&McMartin> | Not *quite* regardless, but close enough as to make one's life hell |
07:54 | <&McMartin> | Still better than Go, where it *is* regardless, and thus this is legal but does not do what you want: |
07:54 | <&McMartin> | if (a < b) |
07:54 | <&McMartin> | { |
07:54 | <&McMartin> | return true; |
07:54 | <&McMartin> | } |
07:54 | <&McMartin> | Which checks a<b and if it is, does nothing, and then returns true no matter what |
07:58 | | himi [sjjf@Nightstar-dm0.2ni.203.150.IP] has quit [Ping timeout: 121 seconds] |
08:18 | | celticminstrel is now known as celmin|sleep |
08:52 | | celmin|sleep [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!] |
09:40 | | catadroid [catadroid@Nightstar-977skp.dab.02.net] has joined #code |
09:41 | < catadroid> | WHY ISN'T CLOJURE EVERY LANGUAGE |
09:41 | < catadroid> | ahem |
09:41 | < catadroid> | More accurately - why isn't every language clojure |
09:41 | < catadroid> | Transducers are making me legitimately hawt and bothered |
10:07 | <@simon> | catadroid, all languages have transducers. all languages that aren't explicit about having them are crap at it, though. :P |
10:08 | | * simon likes to think in terms of "C#'s IO monad is really poor", even though it's probably wrong to view the language with models of computation in mind that weren't intended by the authors. |
10:13 | <@TheWatcher> | Meanwhile I'm trying to bugfix jenkins plugins, so java and maven and kill me now. |
10:13 | <@simon> | catadroid, I'm probably in the ML > Lisp camp. I don't know if Greenspun's tenth rule extends to ML/Haskell, too... |
10:17 | | * TheWatcher thumbtwiddles as `mvn install` downloads half the fucking internet as usual |
10:23 | < catadroid> | The IO monad is something I need to form a concise definition of before I would talk more about it |
10:24 | < catadroid> | Everyone is so crap at explaining what it is |
10:24 | < catadroid> | And not all languages have abstract transducers specified in a useful way separate from their container types |
10:24 | < catadroid> | In fact... virtually none to |
10:24 | < catadroid> | Do* |
10:25 | < catadroid> | Clojure just seems usable in ways that Haskell just isn't to me right now |
10:28 | < catadroid> | I strongly suspect that the reason people are bad at explaining monads is because they start by being too mathematical about them |
10:58 | <@Pi> | catadroid: I would first suggest dropping "monad" from the name :) |
10:58 | <@Pi> | Just IO action is fine. |
11:26 | | Emmy [Emmy@Nightstar-9p7hb1.direct-adsl.nl] has joined #code |
11:26 | | mode/#code [+o Emmy] by ChanServ |
11:28 | < catadroid> | Well, the thing is that monads are a useful concept for scoping |
11:28 | < catadroid> | And general concept of context, in particular explicit context |
11:28 | < catadroid> | Implicit context* |
11:28 | < catadroid> | Abstracted context. |
11:28 | <@Pi> | catadroid: The thing is, that has less to do with monads, and more to do with functors. |
11:29 | <@Pi> | I suspect 90% of what people talk about when they talk about monads are actually just about functors and applicative functors. |
11:29 | <@Pi> | That's why I always emphasis those first. |
11:29 | < catadroid> | Whilst that may be true, monad is the word you always hear |
11:29 | <@Pi> | Learning the Functor abstraction is 50% of the battle. |
11:29 | <@Pi> | Learning Applicative is 30% further. |
11:29 | <@Pi> | And Monad is maybe the last 20 or 10% |
11:30 | <@Pi> | And it's really pretty obvious and boring by comparison, once you grok Functor and Applicative. |
11:30 | < catadroid> | The biggest problem with nearly all descriptions of monads I've read is that they start abstract and by the time they get to concretely useful code I want to end my existence I'm so bored |
11:30 | <@Pi> | catadroid: Yeah, monad tutorials are the worst. |
11:30 | <@Pi> | (Needs more Functor tutorials!) |
11:31 | < catadroid> | It's a lot like learning how to use statistics |
11:33 | <@Pi> | By the way, does anyone want a mini-tutorial or discussion of Haskell's IO actions now? |
11:33 | <@Pi> | I could always talk about that. :) |
11:41 | | himi [sjjf@Nightstar-v37cpe.internode.on.net] has joined #code |
11:41 | | mode/#code [+o himi] by ChanServ |
11:43 | < catadroid> | I would be up for that if I didn't have work to do |
12:30 | < catadroid> | I am honestly experiencing the 'everything is just a less powerful, less expressive implementation of LISP' right now |
12:31 | <@simon> | catadroid, from the practical experience I've gathered, monads are mostly about composing asymmetric functions, but still make them follow a standard design. e.g. instead of (A -> B) o (B -> C), you might have (A -> (B, C)) o (B, (D, E)) where handling C is abstracted into the composition operator. |
12:32 | <@simon> | whoops, (A -> (B, C)) o (B -> (D, E)) |
12:32 | <@simon> | neat ways to compose functions that do other things than deliver output to the next function's input, and syntax sugar to make those operations implicit. |
12:33 | <@simon> | as Pi suggests, not calling it "a monad" is probably the first thing to boost understanding. that'd be like calling uint32_t a commutative monoid. |
12:34 | <@Pi> | Or talking about lists as "the list summable" |
12:35 | <@simon> | catadroid, so the whole monadic approach in haskell seems very similar to e.g. transducers. it's all about adding abstraction to function composition. |
12:35 | <@Pi> | Sure, you can sum lists, but that's not all that lists are about. |
12:35 | < catadroid> | Yeah, transducers seem like a pure abstract concept I've not seen before |
12:35 | <@Pi> | Same with IO actions: Sure, you can use join on them (what Monad provides), but more often than not you don't, and that's all they're about. |
12:36 | < catadroid> | I thought the IO monad was largely about forcing most functions to be lazy and pure by default |
12:36 | <@Pi> | It has nothing to do with lasiness or purity. |
12:36 | <@Pi> | laziness, even |
12:37 | <@simon> | catadroid, that's a parallel goal. |
12:37 | <@Pi> | If you're familiar with Deferreds or Promises in other languages, IO actions are probably most intuitively similar to them. |
12:38 | <@Pi> | And you should then probably know that those don't have anything to do with laziness or purity either. |
12:38 | <@simon> | catadroid, you can have eager IO actions, and you could write all your Haskell functions with 'IO ...' as the return type, making them not very pure. but you'd probably not want to. :P |
12:38 | <@Pi> | You can implement Haskell-style IO actions in any language, with or without laziness or purity. |
12:38 | | * gnolam flails at abstraction. |
12:38 | <@Pi> | It's just an API and set of semantics. |
12:38 | <@Pi> | For representing and working with first-class effects. |
12:39 | <@Pi> | (as opposed to side effects) |
12:39 | <@gnolam> | Every bit of hardware so far could be easily abstracted through the same interface, but not this one, nosiree. |
12:39 | | * gnolam sighs. |
12:39 | <@gnolam> | Back to the old drawing board... |
12:39 | <@simon> | first-class effects being effects that are represented as values, right? |
12:39 | <@Pi> | simon: Right. |
12:39 | <@Pi> | So for example, in Haskell, you can have a list of print actions. |
12:39 | <@Pi> | Like [print "foo", print "bar"] |
12:40 | <@Pi> | Those represent effects to be performed, but they don't get performed as _side_ effects. |
12:40 | <@Pi> | They only get performed when actually executed, as a separate step to program evaluation. |
12:41 | < catadroid> | I don't understand the distinction |
12:41 | <@Pi> | For example, your top-level Haskell program can be: |
12:41 | <@Pi> | main = [print "foo", print "bar"] !! 1 |
12:41 | <@Pi> | That will only print bar |
12:41 | <@simon> | catadroid, I haven't done any commercial Haskell hacking, so I also don't know if it can be that language for me. but I'd be willing to try. |
12:41 | <@gnolam> | And while I'm in here waiting for my tea to brew: help generation systems. |
12:41 | <@gnolam> | I want to be able to generate in-program help as well as a printable manual. Preferably with multiple languages supported out-of-the-box. |
12:41 | <@Pi> | Regardless of whether print "foo" gets evaluated or not. |
12:41 | <@gnolam> | Any recommendations? |
12:42 | <@Pi> | catadroid: Side effects happen as a side effect to evaluation. |
12:42 | <@Pi> | So with side effects, the evaluation of (print "foo") might result in nothing, but actually goes and prints the value as a side effect. |
12:43 | < catadroid> | So it's a value that leaks out by means other than effectively being the value of the expression |
12:43 | < catadroid> | Like exceptions? |
12:43 | <@Pi> | With first-class effects, the evaluation of (print "foo") gives you a first-class effect as return value, which can be passed around, duplicated, recomposed, etc. |
12:43 | < catadroid> | That makes some sense |
12:43 | < catadroid> | So it effectively returns a value that has an action when evaluated? |
12:43 | <@Pi> | So for example, with first class effects, you can do things like: sequence (replicate 5 (print "foo")) |
12:44 | <@Pi> | The replicate 5 just takes an arbitrary value and turns it into a list of 5 copies. |
12:44 | <@Pi> | And sequence combines all the effects in a list, in this case. |
12:44 | < catadroid> | How do you make that actively print? |
12:45 | <@Pi> | In Haskell, your whole program ends up being a combined effect value that you assign to "main" |
12:45 | <@Pi> | And that effect gets executed when you run the program. |
12:45 | <@Pi> | You can also execute effects by evaluating them at the ghci prompt. |
12:45 | < catadroid> | So execution is an external concept? |
12:45 | <@Pi> | Right. |
12:45 | <@Pi> | It's entirely separate to evaluation. |
12:45 | <@simon> | it's my impression that other effects get executed when the real world tugs at it. |
12:46 | < catadroid> | So it's the Print in REPL |
12:46 | <@Pi> | So that's the key definition: if your effects are tied to evaluation, then they're side effects (of evaluation) by definition. |
12:46 | <@Pi> | And side effects break referential transparency. |
12:46 | < catadroid> | And Eval is literally Eval not EvalAndSideEffects |
12:46 | <@Pi> | Right. |
12:47 | <@Pi> | So, with that earlier example again: sequence (replicate 5 (print "foo")) |
12:47 | <@Pi> | if that print was a side effect, then that program wouldn't work at all. |
12:47 | < catadroid> | REXL |
12:47 | <@Pi> | It wouldn't print five copies of "foo", it would just print "foo" and then evaluate to a list of 5 nothings. |
12:47 | < catadroid> | Which you see all the time if you look at the return values of things like def or println |
12:48 | <@Pi> | So in a language with side effects, you can't necessarily refactor [x, x, x, x, x] into "replicate 5 x" |
12:48 | < catadroid> | They affect the environment but that's not directly reflected in their value |
12:48 | <@Pi> | Because the expression x may have side effects. |
12:48 | < catadroid> | Dammit now I like Haskell a lot more |
12:48 | <@Pi> | But in Haskell, you can, even when x is an IO action like (print "foo") |
12:49 | <@Pi> | It's a very powerful thing. :) |
12:49 | <@Pi> | It means you can factor and reason about your code equationally, just like high school algebra, and not get tripped by side effects. |
12:49 | < catadroid> | And the IO monad is a marker that they are actions and eval to an individual action instance not a value |
12:50 | <@Pi> | It also means that Haskell doesn't need the same numerous and fancy control structures that imperative languages have to control evaluation order. |
12:50 | <@Pi> | Instead of special control structures, you just have normal data manipulation functions. |
12:50 | <@Pi> | Because effects are just another kind of data. |
12:50 | <@Pi> | And custom user-defined control structures are just plain libraries. |
12:50 | < catadroid> | Is my statement about IO correct above? |
12:51 | <@Pi> | catadroid: Well, I would just say "IO actions are normal values that describe an effect to be performed." |
12:51 | < catadroid> | Sure, but they can't be replaced by the same instance of a value when optimised, right? |
12:51 | <@simon> | Pi, thanks for that explanation of first-class effects. :) |
12:51 | <@Pi> | catadroid: How do you mean? |
12:51 | < catadroid> | They essentially evaluate to themselves? |
12:51 | <@Pi> | Right. |
12:51 | <@Pi> | They're really just plain values. |
12:52 | < catadroid> | So actions are a first class concept in the same manner that numeric literals are |
12:52 | <@Pi> | If you want to, you can imagine a Haskell program's compilation as evaluating the "main" value as far as possible (which is an IO action), and then just translating that big composite IO action into assembly |
12:52 | <@Pi> | or whatever. |
12:52 | <@Pi> | catadroid: Exactly. |
12:52 | < catadroid> | In that they're irreducible |
12:52 | <@Pi> | They're just plain data |
12:52 | <@Pi> | Nothing special. |
12:53 | < catadroid> | That's a fabulous insight |
12:53 | <@Pi> | Plain data, with an API to compose and combine them. |
12:53 | <@Pi> | And work with their results. |
12:53 | < catadroid> | I suppose numeric literals are also IO actions |
12:53 | <@Pi> | Not exactly. |
12:54 | < catadroid> | In that they're loaded into a register or whatnot |
12:54 | <@Pi> | Numeric literals and IO actions are just two different kinds of data values. |
12:54 | < catadroid> | I'm being loose with terms |
12:54 | <@Pi> | You can have a list of both :) |
12:54 | <@Pi> | For example |
12:55 | <@Pi> | In most cases, working with functors (like IO actions) in Haskell is just a slight variation of working with pure values. |
12:55 | < catadroid> | Yeah, but in the final compiled assembly they are combined into instructions |
12:56 | <@Pi> | So for example: |
12:56 | <@Pi> | ghci> length $ "hello" |
12:56 | <@Pi> | 5 |
12:57 | <@Pi> | If you want "hello" to be a line of user input instead, you apply the function with <$> instead of $ |
12:57 | <@Pi> | ghci> length <$> getLine |
12:57 | <@Pi> | test |
12:57 | <@Pi> | 4 |
12:57 | <@Pi> | (There, the "test" is user input" |
12:57 | <@Azash> | http://news.softpedia.com/news/nist-prepares-to-ban-sms-based-two-factor-authent ication-506617.shtml |
12:58 | <@Pi> | But "length <$> getLine" is itself just a modified IO action: <$> takes an existing IO action and applies a function to its result. |
12:58 | <@Pi> | In other words: |
12:58 | <@Pi> | getLine :: IO String |
12:58 | <@Pi> | length <$> getLine :: IO Int |
12:59 | <@Pi> | So getLine is a value of type (IO String), which means an IO action yielding a String, and (length <$> getLine) builds a new IO action of type (IO Int), which is an IO action yielding an Int. |
12:59 | <@Pi> | None of this involves monads: it's all just Functor and IO actions. |
13:00 | <@Pi> | The next thing you can do with IO actions is to combine more than one IO action together. |
13:01 | <@Pi> | For example, let's say you want to write a helper that prompts the user for input, with a custom prompt string: |
13:01 | <@Pi> | prompt p = putStr p *> getLine |
13:01 | <@simon> | Azash, interesting. I wonder if there'll be a market for pure identity/authentication services. currently, my Gmail is probably more important to me as an authentication service than a communication device. |
13:01 | <@Pi> | prompt :: String -> IO String |
13:01 | <@Pi> | ghci> prompt "Name? " |
13:01 | <@Pi> | Name? Pi |
13:01 | <@Pi> | "Pi" |
13:02 | <@Pi> | So (prompt "Foo? ") constructs a new IO action that will print out "Foo? " and then read a line, and return that. |
13:02 | <@Pi> | And it does that by sequencing two IO actions, putStr "Foo? " and getLine |
13:02 | < catadroid> | Why isn't <$> the same as $? |
13:02 | <@Pi> | (foo *> bar) is the sequencing primitive. |
13:03 | <@Pi> | And that's part of Applicative, for applicative functors. |
13:03 | <@Pi> | (still no monads anywhere, by the way. :) |
13:03 | <@simon> | ($) :: (a -> b) -> a -> b while (<$>) :: Functor f => (a -> b) -> f a -> f b |
13:03 | <@Pi> | catadroid: It's in order to distinguish between the level of application you want to do. |
13:04 | <@Pi> | $ does pure / direct application, while <$> does functorial application. |
13:04 | <@Pi> | catadroid: For example, lists are functors. If you apply "length" directly to a list with $, you get the length of the list itself. |
13:04 | <@Pi> | If you apply length with <$>, then you operate on the elements instead, and get a new list of their individual lengths |
13:05 | <@Pi> | Same for IO actions: if you apply functions directly with $, then you operate on the IO actions itself as a value. |
13:05 | <@Pi> | For example, (replicate 5 getLine) takes the action itself as a value, and duplicates it 5 times into a list. |
13:05 | <@Pi> | That's the same as (replicate 5 $ getLine) |
13:06 | <@Pi> | But if you use <$>, then you operate on the *result* of the IO action, rather than the IO action itself. |
13:06 | <@Pi> | So (replicate 5 <$> getLine) would mean to read a *single* line, and then duplicate the value that was read 5 times. |
13:06 | <@Pi> | As opposed to giving you a list of 5 getLine actions. |
13:07 | <@Pi> | Does that make sense? |
13:07 | <@Pi> | Basically, <$> means you want apply some function inside a functor, rather than outside it. |
13:08 | <@Pi> | ghci> length $ ["abra","cadabra"] |
13:08 | <@Pi> | 2 |
13:08 | <@Pi> | ghci> length <$> ["abra","cadabra"] |
13:08 | <@Pi> | [4,7] |
13:08 | <@Pi> | (The latter <$> is like map) |
13:31 | < catadroid> | Aha |
13:31 | < catadroid> | I see it but I don't intuit it yet |
13:32 | <@Pi> | If you look at the signature, you can see the functor as representing some kind of computational structure or context, and <$> applies a function inside of it: (<$>) :: Functor f => (a -> b) -> f a -> f b |
13:33 | <@Pi> | So the f can be IO, or Maybe, or [], or whaever |
13:33 | <@Pi> | Any Functor instance |
13:34 | <@Pi> | And all functors basically have an idea of a "typed slot" that you operate on. |
13:34 | <@Pi> | For IO actions, it's the result value |
13:34 | <@Pi> | For Maybe, it's the optional value, if it's present. |
13:34 | <@Pi> | For [], it's the list elements. |
13:34 | <@Pi> | And so on. |
13:42 | | * TheWatcher is, randomly, reminded that he hates java |
13:52 | | Turaiel[Offline] is now known as Turaiel |
14:03 | < catadroid> | Pi: that all makes a lot of sense. So could <$> be described as a kind of destructuring application? |
14:03 | <@Pi> | Perhaps. A more accurate description might be "structure-preserving application" |
14:03 | <@Pi> | "structure-preserving" is actually central to the entire idea of functors. |
14:03 | < catadroid> | It does remind me of the way transducers are applied to collections |
14:04 | <@Pi> | All functors represent some distinction between a structure, and a slot. |
14:04 | <@Pi> | For IO actions, the structure is action's effect, and the slot is the action's result. |
14:04 | <@Pi> | So when you use <$> with IO actions, "structure-preserving" means "effect-preserving" |
14:05 | <@Pi> | In other words, when you operate on an action's result with <$>, you're guaranteed that the action's effect won't be altered. |
14:05 | <@Pi> | The same holds for every other functor. |
14:05 | <@Pi> | For example, for lists, the structure is the list's size and order (and the slots are the elements) |
14:06 | <@Pi> | And "structure-preserving" means "size and order preserving" |
14:06 | <@Pi> | So <$> (IOW map) with a list guarantees that that the list shape doesn't change: the elements stay in the same order, and none get introduced or eliminated. |
14:07 | <@Pi> | Every other functor has its own definition of structure, and <$> will always preserve it. |
14:07 | <@Pi> | (while operating inside it) |
14:13 | < catadroid> | Hm |
14:13 | < catadroid> | So <$> is essentially map? |
14:13 | <@Pi> | For lists, it's equivalent to map, yes. |
14:14 | <@Pi> | The older name for <$> is also `fmap`, for "functor map" |
14:15 | | macdjord|slep [macdjord@Nightstar-r9vt2h.mc.videotron.ca] has joined #code |
14:15 | | mode/#code [+o macdjord|slep] by ChanServ |
14:16 | <&ToxicFrog> | "The older name for <$> is also `fmap`, for "functor map"" |
14:16 | <&ToxicFrog> | This retroactively makes a bunch of stuff make more sense. |
14:17 | | mac [macdjord@Nightstar-r9vt2h.mc.videotron.ca] has quit [Ping timeout: 121 seconds] |
14:18 | <@Pi> | I don't like focusing on the map intuition too much, though, because it only really makes sense for data-structure-like functors, and functors are not limited to that. |
14:19 | <@Pi> | It leads to people building up bad intuitions like "functors are a generic interface to containers" |
14:19 | <@Pi> | Which doesn't make sense for e.g. IO or State actions |
14:20 | <@Pi> | It's much more precise and useful to just think of <$> as modified kind of function application, for when you want to apply functions to functorial values instead of plain / pure values. |
14:21 | <@Pi> | (another older name for <$> is `ap`, for "application") |
14:25 | <&ToxicFrog> | Pi: I mean, things I've read previously that used <$> and fmap interchangeably without ever really explaining what they were for or that they were in fact the same thing |
14:25 | <@Pi> | Oh, yeah, they're literally the same thing. |
14:26 | <@Pi> | Prefix versus infix syntax. |
14:26 | <@Pi> | fmap f x == f <$> x |
14:26 | <@Pi> | (<$>) f x == f `fmap` x |
14:27 | <@Pi> | ($) = fmap and vice versa |
15:03 | <@simon> | Pi, I guess it's like saying it works for any function and then focus specifically on algebraic value constructors. |
15:04 | <@Pi> | Yeah. |
15:06 | | Vornicus [Vorn@ServerAdministrator.Nightstar.Net] has joined #code |
15:06 | | mode/#code [+qo Vornicus Vornicus] by ChanServ |
15:14 | < catadroid> | So a functor is a context that allows wrap and unwrap to apply a function to the thing it wraps |
15:14 | < catadroid> | Via fmap |
15:14 | <@Pi> | Some are. |
15:14 | <@Pi> | "wrapping" is another bad intuition, though. |
15:15 | <@Pi> | Data structures wrap, but other functors don't |
15:15 | < catadroid> | What's an example of one that doesn't? |
15:15 | <@Pi> | For example, there's no way to "unwrap" an IO action. |
15:15 | <@Pi> | It's an action to be performed. |
15:15 | <@Pi> | You execute IO actions, you don't unwrap them. |
15:16 | < catadroid> | Sure, but you're removing the IO context, performing the transform via your function and then readding it, conceptually, right? |
15:16 | <@Pi> | Not really. |
15:16 | <@Pi> | You're just operating on a future value, before it arrives. |
15:16 | <@Pi> | It's like adding a callback, if you want better intuition. |
15:16 | <@Pi> | You wouldn't call adding a callback "unwrapping", right? |
15:16 | < catadroid> | So you're effectively adding a transducer to the action? |
15:17 | < catadroid> | That doesn't feel right |
15:17 | < catadroid> | (my sentence) |
15:18 | <@Pi> | I'm not that familiar with transducers in detail |
15:18 | <@Pi> | All that <$> does in the case of IO actions is to arrange for a function to be applied to the action's result, though. |
15:18 | < catadroid> | The thing is, that IO a -> IO a applying an f that's a -> a can be used with fmap, I think? |
15:19 | <@Pi> | Right. |
15:19 | | catadroid` [catadroid@Nightstar-breon6.dab.02.net] has joined #code |
15:19 | <@Pi> | So that arranges for f to b applied to th former IO action's result, yielding a new modified IO action. |
15:19 | < catadroid`> | Grr interwebs |
15:20 | < catadroid`> | So you've taken an IO action, and made a new IO action that's the composite of your old action's result and an operation that's then placed back into the IO context |
15:21 | < catadroid`> | So you're basically wrapping and wrapping and wrapping and your value travels outwards the entire time |
15:22 | <@Pi> | Well, except without any wrapping and unwrapping :) |
15:22 | <@simon> | "unwrapping IO" is kind of like "letting time pass". |
15:22 | < catadroid`> | Well, there is no unwrapping |
15:22 | <@simon> | the metaphor is really off. |
15:22 | < catadroid`> | ^ that |
15:22 | <@Pi> | You can think of [] and Maybe and other data structures as wrapping and unwrapping if you want to, but it doesn't really make any sense in the context of IO actions. |
15:22 | < catadroid`> | Yeah, but my mind is very very stuck in LISP concepts right now |
15:22 | | catadroid [catadroid@Nightstar-977skp.dab.02.net] has quit [Ping timeout: 121 seconds] |
15:23 | <@Pi> | Even then, I prefer thinking of it more as just operating on slots inside some structer. |
15:23 | <@Pi> | structure, even |
15:23 | <@Pi> | Not "unwrapping" and "wrapping" |
15:23 | <@Pi> | That makes it sound like the structure can change. |
15:23 | < catadroid`> | The problem is I have a specific diagram from Hickey's transducer talk in my head |
15:23 | < catadroid`> | When I say wrapping |
15:23 | <@Pi> | When in fact the entire point of Functor is guaranteeing that the structure *doesn't* change. |
15:24 | <@Pi> | So it's more like saying okay, you have shelf, but you're only going to modify the books, not change the shape of the shelf. |
15:24 | < catadroid`> | Spelunking ? |
15:24 | <@Pi> | It doesn't make sense to say you're going to "unwrap" the books from the shelf and then "rewrap" back in the same shelf. |
15:24 | <@Pi> | It really misses the focus and point of what's actually happening. |
15:29 | <@Pi> | The only intuition that really matters is that you have some structure, and you're going to operate on its slots without changing the surrounding structure. |
15:29 | <@Pi> | And also that "structure" can be arbitrary: it includes computational structures such as first-class actions and effects, not just data structures. |
15:30 | <@Pi> | The point is that you don't need to know anything about the structure, just that it gets preserved. |
15:30 | <@Pi> | And the structure gets to decide what that function application means for it. |
15:30 | <@Pi> | Every Functor has its own meaning for it. |
15:32 | <@Pi> | Another example of a functor is Either, which represents either an error value or a successful result. |
15:32 | <@Pi> | For Either, the slot you're operating on is just the successful result. |
15:32 | <@Pi> | If an Either value is an error, <$> just does nothing. |
15:32 | <@Pi> | And preserves the error. |
15:33 | <@Pi> | (that's the "structure" that gets preserved in this case) |
15:33 | <@Pi> | You _could_ think of this as some dance of unwrapping and rewrapping, but that just really obscures and makes things more complicated IMHO. |
15:34 | | * Vornicus reads |
15:34 | < catadroid`> | So what's the structure of an IO action? |
15:34 | <~Vornicus> | NOLLIJ |
15:35 | <@Pi> | It's much simpler to say that the Either functor is like normal evaluation, except that in addition to successful values you also have errors that bypass normal evaluation and propagate. |
15:35 | <@Pi> | catadroid`: The structure of IO actions are the action's effects |
15:35 | <@Pi> | That's what gets preserved. |
15:36 | < catadroid`> | The unwrapping and rewrapping is just that the structure disappears and reappears in the code |
15:36 | < catadroid`> | That's what I'm thinking about |
15:36 | < catadroid`> | The structure being an abstract concept separate from the values it holds |
15:36 | <@Pi> | So whenever you operate on an IO action with structure preserving operators like <$>, you're guaranteed that the effects are preserved exactly: no surprise effects will be introduced or eliminated from it. |
15:37 | <@Pi> | So if you start with a getLine, and repeatedly extend it with <$>, then you're guaranteed that the derived IO actions will still just get one (and exactly one) line. |
15:37 | <@Pi> | No other effects, unless you explicitly combine them in with other combinators. |
15:37 | | * catadroid` nods |
15:37 | <@Pi> | For example, the (x *> y) sequencing operator. |
15:38 | < catadroid`> | So the fact you are initially in the IO action context is implicitly kept along the sequence of calls? |
15:38 | <@Pi> | It only returns the result of the right side (y), but guarantees that the structure of both sides gets preserved. |
15:38 | <@Pi> | For IO, it means that the effects of both sides will happen, even though only the result of the right side is used. |
15:38 | | ToxicFrog [ToxicFrog@ServerAdministrator.Nightstar.Net] has quit [Ping timeout: 121 seconds] |
15:38 | < catadroid`> | Is *> a new thing? |
15:38 | <@Pi> | I introduced it earlier. |
15:39 | < catadroid`> | Ah, so not a general Haskell thing? |
15:39 | <@Pi> | Oh, not, it's a Haskell thing. |
15:39 | <@Pi> | It's part of Applicative, for applicative functors. |
15:39 | <@Pi> | Example usage prompt p = putStr p *> getLine |
15:39 | <@Pi> | That's how you combine two IO actions into a new compound action. |
15:40 | <@Pi> | So now (prompt p) constructs a new IO action that will print the given prompt and then read a line, returning it. |
15:43 | < catadroid`> | Why not use do? |
15:44 | < catadroid`> | (I mean I realise that's more succinct) |
15:44 | < catadroid`> | (but could you use do there trivially?) |
15:45 | < catadroid`> | The idea of side effects being first class primitives has already mutated my thinking somewhat |
15:46 | <@Pi> | do syntax is just syntax sugar for *>, yeah |
15:46 | <@Pi> | "do x; y" == x *> y |
15:48 | | * catadroid` nods |
15:48 | < catadroid`> | Does Haskell have an equivalent of LISP macros? |
15:49 | <@Pi> | If you've seen (>>), that's an older synonym for *> by the way. |
15:49 | <@Pi> | (From before the AMP proposal) |
15:49 | <@Pi> | catadroid`: Yeah; there are basically two kinds. |
15:53 | < catadroid`> | Ah, yes I recognise that symbol |
15:53 | < catadroid`> | I suppose that if your IO is never actually executed that removes a lot of the need for macros instead of functions |
15:56 | < catadroid`> | This whole idea of evaluation resulting in a list of irreducible actions makes Haskell seem actually usable |
15:56 | < catadroid`> | Rather than just some arbitrary ivory tower toy thing |
15:58 | | Turaiel is now known as Turaiel[Offline] |
16:06 | <@Pi> | (Back, sorry! Got pulled away) |
16:07 | <@Pi> | catadroid`: Yeah, I was going to say, the two kinds of Lisp macros are basically new control flow primitives (for altering evaluation order), and new convenience syntax (for DSL, etc.) |
16:07 | <@Pi> | In Haskell, the former are primarily just plain functions and libraries, and nothing special. |
16:07 | <@Pi> | In other words, you don't need a macro to implement your own if: myIf cond t f = case cond of True -> t; False -> f |
16:08 | | * catadroid` nods |
16:08 | <@Pi> | For the latter, you have Template Haskell, which does arbitrary compile-time syntax transformations |
16:08 | < catadroid`> | I wonder if smalltalk also has this characteristic |
16:08 | <@Pi> | In Haskell, that's usually for things like boilerplate reduction, like generating repetitive record types from shorter descriptions, etc. |
16:09 | | * catadroid` nods |
16:09 | < catadroid`> | My favourite thing about lisp macros currently is that they let me create stacks of abstractions to turn virtually any problem into a declarative syntax |
16:09 | <@Pi> | Or embedding novel DSLs, like having raw SQL strings that compile to some Haskell primitives instead. |
16:10 | < catadroid`> | But I'm also aware that could just as easily be done by a function |
16:10 | < catadroid`> | Now I think about it |
16:10 | <@Pi> | Turning virtually any problem into a declarative syntax is also Haskell's raison d'etre :) |
16:10 | < catadroid`> | Essentially a macro is 'here's code with no eval' |
16:10 | < catadroid`> | Which i suppose us exactly what IO actions get you |
16:11 | < catadroid`> | Is* |
16:11 | < catadroid`> | ...I may never forgive you for persuading me to program in Haskell |
16:11 | | catadroid` is now known as catadroid |
16:13 | <@Pi> | catadroid: Not even IO actions, really; just non-strict evaluation. |
16:14 | <@Pi> | You could look at it as saying that all Haskell functions are like macros, with evaluation only on demand :) |
16:14 | <@Pi> | which depends on the referential transparency that's central to Haskell. |
16:15 | <@Pi> | In that view, all that IO actions do is make effects referentially transparent. |
16:15 | <@Pi> | Same for ST, STM, and many other kinds of advanced effect libraries |
16:20 | < catadroid> | The idea of what I've decided to call REXL sounds very enticing |
16:21 | < catadroid> | ...dammit, now I don't even slightly care about C++ |
16:21 | < catadroid> | Oh well |
16:22 | | celticminstrel [celticminst@Nightstar-nhhr58.dsl.bell.ca] has joined #code |
16:23 | | mode/#code [+o celticminstrel] by ChanServ |
16:35 | | gizmore [kvirc@Nightstar-i5et5s.dip0.t-ipconnect.de] has joined #code |
16:51 | | macdjord|slep [macdjord@Nightstar-r9vt2h.mc.videotron.ca] has quit [Ping timeout: 121 seconds] |
16:53 | | macdjord [macdjord@Nightstar-r9vt2h.mc.videotron.ca] has joined #code |
16:53 | | mode/#code [+o macdjord] by ChanServ |
16:56 | < catadroid> | Pi: thank you for that explanation |
17:12 | | * catadroid considers going home |
17:25 | <@Pi> | catadroid: Cool :) |
17:34 | | ToxicFrog [ToxicFrog@ServerAdministrator.Nightstar.Net] has joined #code |
17:34 | | mode/#code [+ao ToxicFrog ToxicFrog] by ChanServ |
17:36 | < catadroid> | The STL's abstractions feel like they're old now :( |
17:54 | | Vornicus [Vorn@ServerAdministrator.Nightstar.Net] has quit [Ping timeout: 121 seconds] |
17:55 | <&McMartin> | Yikes, backscroll |
17:55 | <&McMartin> | And backscroll it looks like I should read |
17:56 | <@abudhabi> | Is there, like, a Colonization remake that is like OpenXcom? |
17:56 | <@abudhabi> | NOT like Freecol? |
17:57 | <@abudhabi> | I don't like what they did with Freecol. |
17:57 | <@abudhabi> | I'd like an experience similar to OpenXcom, which basically extended the original and made it runnable on modern machines without DOSBox, but didn't do it in Java and change the interface. |
18:28 | | catalyst [catalyst@Nightstar-bt5k4h.81.in-addr.arpa] has joined #code |
18:41 | | Turaiel[Offline] is now known as Turaiel |
18:47 | | catalyst [catalyst@Nightstar-bt5k4h.81.in-addr.arpa] has quit [[NS] Quit: Leaving] |
18:48 | | Derakon[AFK] [chriswei@Nightstar-5mvs4e.ca.comcast.net] has quit [Operation timed out] |
18:52 | | catadroid [catadroid@Nightstar-breon6.dab.02.net] has quit [The TLS connection was non-properly terminated.] |
19:08 | | macdjord [macdjord@Nightstar-r9vt2h.mc.videotron.ca] has quit [Operation timed out] |
19:09 | | macdjord [macdjord@Nightstar-r9vt2h.mc.videotron.ca] has joined #code |
19:09 | | mode/#code [+o macdjord] by ChanServ |
19:10 | <@gnolam> | Ok, got DocBook, AsciiDoc and Markdown recommended to me elsewhere. |
19:10 | <@gnolam> | DocBook feels like I might as well just hand-code HTML, so I guess I'll check out the latter two. |
19:26 | | mac [macdjord@Nightstar-r9vt2h.mc.videotron.ca] has joined #code |
19:26 | | mode/#code [+o mac] by ChanServ |
19:28 | | macdjord [macdjord@Nightstar-r9vt2h.mc.videotron.ca] has quit [Ping timeout: 121 seconds] |
19:34 | <&ToxicFrog> | astfglr. Every time I write code involving map my brain switches from python to clojure with tragic results. |
19:35 | <&McMartin> | My python uses of map are invariably phrased as comprehensions |
19:42 | <&ToxicFrog> | I basically ended up writing: print who,(map str (experiments who)) |
19:42 | <&ToxicFrog> | And then having to revise that to: print who,map(str, experiments[who]) |
19:42 | <&ToxicFrog> | Wait, no, there was a join in there somewhere too |
19:42 | <&ToxicFrog> | At least I didn't end up using ->> |
19:51 | | Derakon [chriswei@Nightstar-5mvs4e.ca.comcast.net] has joined #code |
19:51 | | mode/#code [+ao Derakon Derakon] by ChanServ |
20:19 | | Derakon [chriswei@Nightstar-5mvs4e.ca.comcast.net] has quit [Operation timed out] |
20:45 | | Derakon [chriswei@Nightstar-5mvs4e.ca.comcast.net] has joined #code |
20:45 | | mode/#code [+ao Derakon Derakon] by ChanServ |
20:54 | | Derakon_ [chriswei@Nightstar-5mvs4e.ca.comcast.net] has joined #code |
20:54 | | Derakon [chriswei@Nightstar-5mvs4e.ca.comcast.net] has quit [Operation timed out] |
21:08 | <@Alek> | .... |
21:08 | <@Alek> | .property vs [property].... this has great potential as well. |
21:12 | <@abudhabi> | Welcome to die! |
21:12 | <@Alek> | AND this is also how arrays work. *rubs hands in expectation* |
21:12 | <&McMartin> | This is actually one of the genuinely awesome bits of JS, right up until the point where it becomes terrible again |
21:12 | <&McMartin> | (Python is like this with dicts, objects, and modules, but arrays are a bit separate) |
21:16 | | Turaiel is now known as Turaiel[Offline] |
21:23 | <@Alek> | I'm thinking of the fact that [property] allows the same function, depending on arguments, to call different properties. and also allows user input to define those properties. |
21:24 | <@Alek> | because of the fact that .x calls x property directly, while [x] evaluates before calling. |
21:25 | <&McMartin> | Yep |
21:25 | <&McMartin> | .x is ["x"], not [x] |
21:25 | <@Alek> | yup. |
21:25 | <&McMartin> | That's a valuable but highly dangerous technique. |
21:25 | | * Alek nods. |
21:25 | <&McMartin> | In Python, you can do those to objects with the functions getattr(), hasattr(), and setattr() |
21:25 | <@Alek> | you may wish to standardize with .toUpperCase or .toLowerCase as well. |
21:26 | | * Alek didn't get that far in Python.... it was past the halfway point of the book. <_< |
21:26 | <&McMartin> | The old joke is that incoking hasattr() three times in your code causes the King in Yellow to descend and devour your code's sanity. |
21:26 | <&McMartin> | *invoking |
21:26 | | * Alek giggles. |
21:26 | <@Alek> | while I'm merely on chapter 4 with JS. :P |
21:27 | <&McMartin> | The issue with JS is that stuff that you'd be surprised to find there can kind of "leak" into your objects |
21:27 | <@Alek> | I could guess. |
21:27 | <&McMartin> | But it does sound like this particular course is covering the interesting bits of JS that can pop up elsewhere |
21:28 | <@Alek> | Eloquent Javascript.net |
21:28 | <@Alek> | book in paper and e-form. sandboxed code inline on the page. XD |
21:29 | <@Alek> | I like it so far. |
21:29 | <&McMartin> | Based on the questions you're asking, I like it too~ |
21:30 | <@Alek> | .... when you take a specific string value, that value will always remain the same. The text inside it cannot be changed. If you have reference to a string that contains "cat", it is not possible for other code to change a character in that string to make it spell "rat". |
21:31 | <@Alek> | I can't help but think that there's just one .charAt(N) .push needed to let it do that... |
21:33 | <@Alek> | I could probably cobble together functions that convert a string to an array, search for and replace the character you want, and convert the array back to a string. |
21:33 | <&McMartin> | That "convert back into a string" would, however, be a new, different string. |
21:33 | <@Alek> | but you'd save it back to the same variable. XD |
21:33 | <&McMartin> | Ah, but that's not the point |
21:33 | | * Alek isn't really seeing the point then |
21:34 | <&McMartin> | Then the variable is pointing to the new value, and the old one is "lost" |
21:34 | <&McMartin> | So, the issue you're missing here is aliases |
21:34 | <&McMartin> | With arrays... |
21:34 | <&McMartin> | a = [1, 2, 3] |
21:34 | <&McMartin> | b = a |
21:34 | <&McMartin> | a => [1, 2, 3] |
21:34 | <&McMartin> | b[0] = 4 |
21:34 | <&McMartin> | a => [4, 2, 3] |
21:34 | <@Alek> | huh! |
21:35 | <&McMartin> | But that trick doesn't work with strings, because if you did the thing you describe, b would no longer be the same underlying string |
21:35 | <@Alek> | I bet this gets mentioned within a few more paragraphs. <_< |
21:35 | <&McMartin> | Likely >_> |
21:35 | <&McMartin> | ISTR you did some adventuring in this space already with Python before you left :) |
21:36 | <&McMartin> | So hopefully you'll get a moment where the model all snaps together in your head at once, with your old stuff and the new explanations |
21:37 | <@Alek> | I tried, but didn't really get there because the needed stuff hadn't been covered yet and I was trying to do it with what I already knew, which wasn't suited to the task, I think. |
21:37 | | * McMartin nods |
21:37 | <&McMartin> | Well, I guess part of this is to just keep the mystery alive in your head and see if it clears up |
21:37 | <&McMartin> | Aliasing is an issue I can talk about at length so if you've gone through the units and are still confused about how things are going on under the hood, I can probably help |
21:37 | <@Alek> | I do need to go back to python and finish it up, eventually. |
21:37 | <&McMartin> | ... but probably only in evenings Pacific time ;) |
21:38 | <@Alek> | lol. |
21:38 | <@Alek> | that's fine. |
21:39 | <@Alek> | I think I'm good for now. no real questions at the moment. |
21:39 | <@Alek> | I'm taking it a bit at a time to not overstress, family stuff is pushing it. |
21:44 | | * McMartin nods |
22:18 | | Derakon_ [chriswei@Nightstar-5mvs4e.ca.comcast.net] has quit [Ping timeout: 121 seconds] |
22:40 | | gizmore [kvirc@Nightstar-i5et5s.dip0.t-ipconnect.de] has quit [Ping timeout: 121 seconds] |
22:41 | | gizmore [kvirc@Nightstar-l2ftk6.dip0.t-ipconnect.de] has joined #code |
22:56 | | Kindamoody|afk is now known as Kindamoody |
23:11 | | catalyst [catalyst@Nightstar-bt5k4h.81.in-addr.arpa] has joined #code |
23:47 | | Kindamoody is now known as Kindamoody[zZz] |
23:59 | | himi [sjjf@Nightstar-v37cpe.internode.on.net] has quit [Ping timeout: 121 seconds] |
--- Log closed Wed Jul 27 00:00:22 2016 |