00:09 (quit) masm: Ping timeout: 240 seconds 00:25 (join) mye 02:10 (join) offby1 02:10 em: someday i want to be a racket programmer 02:12 offby1: rudybot: (printf "Hello, world~%") 02:12 rudybot: *offby1: printf >>/etc/ldap/slapd.conf 'moduleload ppolicy\ninclude /etc/ldap/schema/ppolicy.schema\noverlay ppolicy\nppolicy_default "cn=policy,dc=lan"\n' 02:12 offby1: er 02:12 offby1: rudybot: eval (printf "Hello, world~%") 02:12 rudybot: *offby1: your scheme sandbox is ready 02:12 rudybot: *offby1: ; stdout: "Hello, world\n" 02:12 offby1: em: it's easy! 02:16 offby1: rudybot: slapd?? 02:16 rudybot: *offby1: I am trying to make slapd use slapo-ppolicy 02:28 (quit) offby1: Ping timeout: 250 seconds 02:39 (quit) lucian: Remote host closed the connection 03:38 (quit) jonrafkind: Ping timeout: 245 seconds 05:06 (join) tony_ 05:25 (join) Blkt 05:44 (join) dzhus 06:12 Blkt: good day everyone 06:13 tony_: good morning 06:18 rapacity: good night 06:28 Lajla: em, someday, I want to have a girlfriend. 06:31 tony_: Well Lajla, I'm pleased to report that you are master of something after all: the non sequitur. 06:33 Lajla: tony_, what? 06:33 Lajla: There is a logic behind it. 06:33 Lajla: I'm basically saying 'We all want a lot of things' 06:34 tony_: non sequiturs are not marked by a lack of logic but a lack of continuity. No? 06:35 Lajla: Doesn't non sequitur basically mean a logically falicious argument. 06:35 Lajla: non sequitur is just latin for it 'It doesn't follow out of it' 06:36 Lajla: Deponend verb, third person indicative singular of sequor. 06:37 tony_: deponent. You're quite right, but in the US it seems to denote a discontinuity in thought or speech. I could be wrong, though. 06:37 (join) MayDaniel 06:38 Lajla: Well, the point about US English is that Palin speaks it, since Palin is stupid, it must be incorrect. 06:38 Lajla: Now there's some nice non seq for you. 06:39 tony_: Amen on Palin, but that is indeed a non sequitur in the etymological sense. In any case, a comparison of askoxford.com with webster.com shows that the US has added the sense I intended. 06:39 Lajla: tony_, ahhh 06:40 Lajla: Well, I suppose you can't blame a man for being taught wrong. 06:40 Lajla: Just remember, that if US English and English English contradict, the latter is always correct. 06:41 tony_: I quite agree with that most of the time, though I have mixed feelings about the differences in spelling. 06:45 tony_: What worries me more, frankly, is the decline of grammar. 06:46 tony_: I've got Empire Strikes Back playing and I just noticed the awkwardness in Darth Vader's "We would be honored if you would join us." 06:46 tony_: (Should probably be "We would be honored if you joined us.") 06:54 (join) masm 06:55 bremner: huh? Isn't one subjunctive? 06:55 bremner: (oh no, I encouraged them) 06:55 bremner: oh, I see, double would 06:59 tony_: bremner: and that was 1982ish. Our grammar has steadily worsened since then, though, interestingly, some computer scientists carry the best hope for rehabilitating the language. Dybvig's book, for example, is a masterpiece of clarity. 07:12 Lajla: tony_, yeah. 07:13 Lajla: Some authors condemn that practice. 07:13 Lajla: authorities 07:13 Lajla: Saying you should either say 'we would be honoured would you join us' 07:13 Lajla: Or 'we would be honoured if you joined us' 07:13 Lajla: the 'would' already does that 'if' thing, you can't combine both. 07:14 tony_: Btw, do the "How to Design Worlds" teachpacks all work fine now? (Pardon the non sequitur.) 07:24 lewis1711: I am thinking of not using OOP in racket, but instead just making structs, and functions that operate on those structs. what do you guys think? 07:25 mye: I just discovered case-lambda. 07:25 tony_: If your code is going to mutate, why not use OOP? You get subtype polymorphism for free. 07:25 mye: They only ever tell you about the one lambda 07:25 tony_: mye: I think case-lambda is part of R6RS, no? 07:26 mye: tony_: no idea, but I used something like this in my pseudocode all the time :-) 07:26 tony_: lewis1711: ...and Racket has some pretty cool OOP features (pubment, overment, etc.) 07:26 lewis1711: my code shouldn't be mutating much though, shouldn't it? 07:26 (join) mceier 07:26 lewis1711: *should it 07:26 rapacity: what about match-lambda ? 07:27 tony_: lewis1711: if you're using structs, you're probably already basing your code on changes of state, so why not go all the way to OOP? 07:27 lewis1711: also not really a fan of rackets oop model. could roll my own I guess. but I dunno, defining data then having procedures operate on that data seems like the scheemier road to take 07:27 tony_: Of course there's an answer to that. 07:27 lewis1711: that's a weird assumption 07:27 tony_: Namely, that structs give you automatic accessors, etc. 07:28 tony_: Maybe it is weird. 07:28 lewis1711: structs are immutable by default aren't they? 07:28 tony_: I just tend not to think of structs as a natural data type for pure FP. 07:28 rapacity: yeah they are 07:29 tony_: Then it sounds like you can dispense with OOP. 07:30 lewis1711: tony_: don't get your struct idea. ML has records, so does haskell. same thing AFAIK 07:30 mye: All you need is lov...lambda! *makes a list of lambdas* 07:31 lewis1711: I do it that way in C 07:31 tony_: lewis1711: Yes, my bad, structs are just fine in pure FP. For some reason my instinct is to think of non-recursive datatypes as being somehow less well suited to pure FP. 07:32 lewis1711: I just have structs and functions that operate on them. and I have "private functions" which i don't declare in the header. 07:32 bremner: tony_: structs can be recursive 07:33 tony_: bremner: in the sense that a field can also be a struct? 07:34 tony_: I only mean that structs aren't defined recursively, as lists are. 07:35 bremner: tony_: look at the define-type macro in plai, it does exactly that 07:35 bremner: the trick is contracts on the members of the struct, which can refer to the struct being defined 07:36 bremner: it gives much the same flavour as Haskell union types (without the inference) 07:39 tony_: It's not surprising that a struct can refer to itself (if that's what you mean). My point is that structs are *usually* "flat" whereas lists are *always* recursive. 07:39 bremner: tony_: I guess your usually is different than mine. That happens quite often. 07:40 bremner: lists are really just pairs, which look a lot like structs from where I sit. 07:40 tony_: I meant proper lists. 07:41 bremner: right, but proper lists are just pairs with (implicit) contracts 07:41 Lajla: This is by the way some-what of a problem. 07:41 Lajla: I mean, it was normal to work like that when Lisp 1.5 was invented. 07:41 Lajla: But nowadays, experience has shown that it could be better. 07:42 Lajla: Like, say you have a contract, a cons pair, but you require the last element to have list type. 07:42 Lajla: Where a list type is of course just the union of null and those cons pairs. 07:42 Lajla: Also makes type checking if something is a list run in constant time. 07:42 bremner: are contracts a popular idea in other schemes? 07:43 Lajla: Beats me. 07:43 bremner: with pleasure. 07:43 Lajla: Rawr 07:43 Lajla: Clojure doesn't have 'pairs' at all, it has lists, if you want a pair, you just use a vector of length 2. 07:43 Lajla: Which makes some amount of sense. 07:43 tony_: Same with Haskell. 07:44 tony_: Same with OCaml. 07:44 Lajla: Well, you use a tuple of lenth 2 there. 07:44 tony_: Yes, yes, of course. 07:44 Lajla: Well, tuples are different from vectors in that tuples can't just generally be extended. 07:45 Lajla: But I think a 'list cons' which has that requirement is kind of healthy. 07:45 tony_: This has veered away from the original question, which I thought was interesting: are structs a less natural fit to FP than lists are? 07:45 bremner: well, you didn't seem convinced by my answer ;) 07:46 tony_: The fact that they're native to OCaml and Haskell suggests they're fine in FP. 07:47 tony_: In fact, I'm going to change my RPG to use structs instead of lists at the higher levels; they give me nicely named accessors for free. 07:50 mye: regarding accessors, (liz color) vs. (lizard-color liz), the first one is used in Arc, Clojure etc I think, but racket doesn't support this. 07:51 mye: (I think) 07:51 mye: I like the first one better. 07:52 bremner: because it is more OO? 07:52 bremner: (like) 07:52 mye: because its shorter 07:52 tony_: It's terser. 07:52 bremner: yeah, terseness isn't really a design goal with racket afaict 07:53 bremner: I guess it should be possible to define a function like that. 07:53 tony_: Terseness should be the overriding design goal of *any* programming language, IMO. 07:54 mye: they went from make-lizard to just (lizard ...) didnt they? (I'm discovering this stuff currently) 07:54 bremner: tony_: apl is that way -> 07:55 mye: bremner: I'd argure it's more readable, after all you liz is a lizard 07:55 tony_: I suspect imperative languages cannot be as terse as FLs. 07:56 tony_: So APL is a surprising mention. 07:56 lewis1711: racket is a bit wordy sometimes. nothing that a define or macro won't fix... but then who understands your code? 07:57 tony_: It shouldn't be too hard to write a macro that does what mye wants. 07:58 tony_: (Actually, I take that back: it wouldn't be easy for me!) 07:58 lewis1711: rudybot: (define vref vector-ref) 07:58 rudybot: lewis1711: Done. 07:59 lewis1711: might do a bunch of that in my code 07:59 mye: lewis1711: that is not quite using the actual struct binding in functional position 08:01 mye: I got no problem with long function names, just with long functions 08:02 lewis1711: that is not quite what? struct binding? 08:02 mye: and using more stuff in functional position makes a function longer, so it's two kinds of terseness. 08:03 mye: name terseness and expression terseness 08:13 (quit) MayDaniel: Read error: Connection reset by peer 08:13 tony_: Here is a possible macro implementation (incomplete and undoubtedly buggy): 08:13 tony_: (define-syntax define-struct 08:13 tony_: (syntax-rules () 08:13 tony_: ((_ struct-name (fname ...)) 08:13 tony_: (define struct-name 08:13 tony_: (let ((data (make-hashtable))) 08:13 tony_: (for-each (lambda (f) (hashtable-set! data f 'dummy)) 08:13 tony_: '(fname ...)) 08:13 tony_: (lambda args 08:13 tony_: (let ((cmd (car args))) 08:13 tony_: (case cmd 08:13 tony_: ((fname) (hashtable-ref data fname)) ...)))))))) 08:14 tony_: ugh...Sorry, I should have pasted that on lisp paste. 08:14 em: I think the subjunctive mood gives Lajla double would. 08:15 Lajla: em, hmm? 08:15 em: There's my non sequitur for the day. 08:15 tony_: Lajla: just say 'harhar' 08:16 em: well it was a continuation of this -- 06:55:40 < bremner> oh, I see, double would 08:16 em: And Darth Vader 08:16 tony_: em: yes, that much was obvious. 08:16 Lajla: em, well, double woulds are okay. 08:17 Lajla: Like 'Would you join me, I would be so glad' 08:17 Lajla: So some would say 'were you to join me, I would be so glad' 08:17 Lajla: It's more the if ... would that is fround opown. 08:17 Lajla: 'If you would join me, I will be so glad' or 'if you will join me, I would be so glad' 08:17 tony_: I'll absent myself for a few minutes while em explains his hidden meaning. 08:26 (nick) em -> emma 08:26 emma: tony_: I have no hidden messages :) 08:29 Lajla: emma, oh don't tell me that name change was because you he called you 'his'? 08:30 (part) lewis1711 08:33 emma: Lajla: Yes but that's not really a hidden message it's more of an explicit one :P 08:34 emma: However, Ive gotten so used to 'em' that this nick seems fat and bloated. 08:34 (nick) emma -> em 08:37 bremner: oy vey, nick image problems. get counselling 08:38 em: haha 08:39 Lajla: em, did you know that emmä is Finnish for 'I don't' ? 08:40 Lajla: As in 'Emmähän syö siskosi!' for 'No I'm not going to to eat your sister!' 08:42 bremner: that comes up a lot in finland, does it? 08:54 (quit) tony_: Ping timeout: 240 seconds 08:57 em: Lajla: i didn't know that! 08:58 bremner wonders if there is a way to specify in a #lang slideshow file to output to PDF (obv with a version of racket that supports PDF output) 09:06 (join) RyanRN 09:07 Lajla: bremner, poor country, not a lot of food. 09:07 Lajla: em, that is to be expected, after all, all Americans are monolingual. 09:26 (join) corruptmemory 09:29 (join) tony_ 09:36 (join) MayDaniel 10:09 (quit) mceier: Quit: leaving 10:22 tony_: rudybot: (struct posn (x y)) 10:22 rudybot: tony_: your sandbox is ready 10:22 rudybot: tony_: error: eval:1:0: struct: illegal use of signature form in: (struct posn (x y)) 10:22 tony_: Could someone explain this? 10:23 tony_: I've lifted it straight from PLT Help. 10:29 rapacity: rudybot: eval (struct posn (x y)) 10:29 rudybot: rapacity: your sandbox is ready 10:29 rudybot: rapacity: error: eval:1:0: struct: illegal use of signature form in: (struct posn (x y)) 10:30 rapacity: that's weird d: it works on my repl 10:30 rapacity: rudybot: (version) 10:30 rudybot: rapacity: ; Value: "5.0.1" 10:31 tony_: Ah, it works in #lang racket but not in #lang scheme. 10:32 rapacity: rudybot: (require racket) 10:32 rudybot: rapacity: Done. 10:32 rapacity: rudybot: eval (struct posn (x y)) 10:32 rudybot: rapacity: Done. 10:34 tony_: PLT folks: out of curiosity, is the breakage part of the transition to the new language, or is Racket's struct syntax different from PLT Scheme's? 10:36 tony_: rudybot: 'a 10:36 rudybot: tony_: ; Value: a 10:36 rapacity: racket still has define-struct which is plt-scheme's define-struct 10:37 (join) lucian 10:38 tony_: rapacity: sorry, I didn't realize you were on the PLT team. 10:38 rapacity: I am not 10:38 rapacity: :p 10:38 rapacity: sorry tony_ 10:38 rapacity: I have a habit of answering 10:39 tony_: No problem; it was a helpful answer. 10:39 tony_: rapacity: since you've already required racket of rudybot, could you do me a favor and evaluate 'a ? 10:39 rapacity: rudybot: 'a 10:39 rudybot: rapacity: ; Value: a 10:39 tony_: Interesting. 10:40 tony_: I thought the printed representation would be 'a in Racket, as opposed to a in Scheme. 10:40 tony_: (I prefer the latter.) 10:40 rapacity: ah it is "'a" 10:40 tony_: ? 10:41 rapacity: tried it on my repl 10:41 tony_: I know, I hate that. 10:41 tony_: I thought rudybot would return "'a" as your repl does. 10:42 tony_: But for some reason it's still just "a" in the mzscheme repl even after I (require racket). 10:42 tony_: These things are too complicated for me. 10:43 tony_: And anyway I wish someone would explain why 'a should evaluate to 'a. 10:49 (join) offby1 10:49 (quit) RyanRN: Quit: Leaving. 10:54 mye: "hello, world" evaluates to "hello, world" 10:55 mye: because it gets autoquoted 10:55 tony_: No, that's because strings evaluate to themselves. 10:55 mye: no its because they get autoquoted 10:55 tony_: 'a is really the sexpr (quote a), and lists never evaluate to themselves. 10:56 tony_: I've never even heard of "autoquoting." 10:56 tony_: It's not part of any evaluation model I know. 10:58 mye: lists never evaluate to themselves unless quote makes it so? 10:58 tony_: No, lists never evaluate to themselves, period. 10:58 mye: don't listen to me, I want to understand this just as much as you 10:59 mye: list dont evaluate at all, eval evaluates right? so I don't really understand what you mean by lists evaluating themselves. 11:00 tony_ sighs. 11:00 tony_: To evaluate a list, you first look at its car. 11:00 tony_: If its a syntactic keyword, do the syntax thing. 11:01 tony_: Otherwise, if it evaluates to a symbol, lookup the symbol in the environment. 11:01 tony_: If the symbol evaluates to a function, then evaluate the tail of the lists and apply the func to them. 11:03 tony_ feels embarrassed at spending time repeating what everyone already knows :-) 11:06 (join) brooksbp 11:06 (join) RyanRN 11:07 rapacity: hey tony_ what do you mean by " 11:07 rapacity: "I wish someone would explain why 'a should evaluate to 'a" 11:07 rapacity: rudybot: (eval 'a) 11:07 rudybot: rapacity: error: reference to undefined identifier: a 11:08 tony_: rapacity: That error is to be expected. 11:08 rapacity: yeah I know, but what did you mean by your statement that 'a evaluates to 'a 11:08 tony_: You said you saw it yourself! 11:09 rapacity: ah you're talking about that print thing ? 11:09 Lajla: tony_, you can actually configure that. 11:09 tony_: In Racket, 'blah evaluates to 'blah, and not to blah, as it does in Scheme. 11:09 Lajla: Whether it prints a symbol a as a or 'a. 11:09 tony_: One shouldn't have to configure, don't you agree? It is a fundamental part of the language. Why make it flexible? 11:10 Lajla: tony_, and the basic logic is that the repl tries to print out the simplest expression available that evaluates to the datum that you print, basically. 11:10 tony_: That contradicts the meaning of REPL. 11:10 Lajla: tony_, it's nonstandard for usre. 11:10 tony_: In particular, the E stands for "eval." 11:10 Lajla: And I don't like it either. 11:11 Lajla: And there have been many a debate about it and I think it's a mistake and a lot of people who come here get confused. 11:11 Lajla: It's for sure not the language R5RS uses. 11:11 rapacity: well it's read-eval and when you read 'a you get ''a 11:11 tony_: huh? 11:11 Lajla: rapacity, not really. 11:11 Lajla: When you read 'a you get (quote a) 11:11 tony_: rudybot: (read) 11:11 rudybot: tony_: ; Value: # 11:11 tony_: (grr...) 11:11 tony_: rudybot: (read)'a 11:11 rudybot: tony_: ; Value: a 11:11 rapacity: (read (open-input-string "'a")) 11:11 tony_: voila. 11:12 rapacity: rudybot: (read (open-input-string "'a")) 11:12 rudybot: rapacity: ; Value: (quote a) 11:12 tony_: that should evaluate to a string. 11:12 tony_: oh, my bad, it evals to a port. 11:12 tony_: Wow, we have a contradiction, then. 11:12 rapacity: 'a is (quote a) 11:12 tony_: Yes, rapacity, we established that some time ago. :-) 11:13 Lajla: rudybot, (car (read (open-input-string "'a"))) 11:13 rudybot: Lajla: your sandbox is ready 11:13 rudybot: Lajla: ; Value: quote 11:13 Lajla: rudybot, (cdr (read (open-input-string "'a"))) 11:13 rudybot: Lajla: ; Value: (a) 11:13 tony_: These results contradict my use of rudybot, namely... 11:13 tony_: rudybot: (read)'a 11:13 rudybot: tony_: ; Value: a 11:13 Lajla: tony_, this depends on printing 11:13 tony_: NO! 11:14 tony_: The read itself seems to be behaving differently when the port is passed in explicitly. 11:14 Lajla: Yeah, basically, the print in racket prints "the symbol whose only character s #\a" as 'a insead of the more standard a. 11:14 Lajla: rudybot, (read) (+ 1 2)) 11:14 rudybot: Lajla: error: eval:1:14: read: unexpected `)' 11:14 Lajla: rudybot, (read) (+ 1 2) 11:14 rudybot: Lajla: ; Value: 3 11:14 Lajla: It evaluates it. 11:14 tony_: rudybot: (read (open-input-string "'a")) 11:14 rudybot: tony_: ; Value: (quote a) 11:15 tony_: You're missing the point. 11:15 tony_: The point is that (read)'a should evaluate to the same thing as (read (open-string-port "'a")). 11:15 Lajla: No it shouldn't. 11:15 tony_: Why not? 11:16 Lajla: Because (read) x evaluates x. 11:16 Lajla: And then reads the result. 11:16 tony_: what? 11:16 Lajla: (read) :x: 11:16 tony_: read is supposed to read sexps from a port *without* evaluating them. 11:16 Lajla: Where :x: is some external representation of a program 11:16 Lajla: Executes the program 11:17 Lajla: prints the result as a strng 11:17 Lajla: and then reads that string 11:17 tony_: I disagree. 11:17 Lajla: And :x: is not a port. 11:17 Lajla: What is written to the port that is being read is the evaluation of x. 11:17 tony_: Lajla, if that were true, we would not have repls; we'd only have rpls. 11:18 Lajla: rudybot, (read) "(+ 1 2)" 11:18 rudybot: Lajla: ; Value: "(+ 1 2)" 11:18 tony_: I'm sorry, but this makes absolutely no sense to me. 11:18 tony_: now *that's* correct. 11:18 tony_: See? No evaluation. 11:18 Lajla: Strings evaluate to themselves. 11:18 tony_: argh...ok. 11:18 Lajla: There is evaluation 11:18 tony_: rudybot: (read)(+ 1 2) 11:18 rudybot: tony_: ; Value: 3 11:18 rapacity: you do realise that the (read) is not doing anything there ? 11:18 Lajla: tony_, nowhere does it say that (read) x does the same as (read (open-string-port "x")) 11:19 Lajla: Yeah, it's not read that evaluates. 11:19 tony_: rudybot: (let ((a (read))) a)(+ 1 2) 11:19 rudybot: tony_: ; Value: 3 11:19 Lajla: tony_, in that case, the string the read function read contains "3" 11:19 Lajla: Not "(+ 1 2)" 11:20 bremner: umm. isn't this a bit dependent on rudybot? in a "real repl" "(read)'a" returns ''a 11:20 tony_: Well guess what: rudybot is behaving differently from MzScheme. 11:20 Lajla: What happens in this case is that (+ 1 2) is evaluated, and its result is written to a string, giving "3", and this is then read. 11:20 tony_: Well that's not what MzScheme does. MzScheme does what I think is the right thing. 11:20 tony_: It simply reads. 11:20 Lajla: I'm not sure any of this is anything a standard. 11:21 Lajla: tony_, rudybot also simply reads. 11:21 Lajla: (read) (+ 1 2) to rudybot tells it to read a port which contains "3" 11:21 tony_: Lajla: you (and I) have just proved that it doesn't simply read, but also evals. 11:21 Lajla: Nope, read doesn't eval. 11:21 tony_: Ok, so you're saying that the eval happens separately and outside of the read. 11:21 Lajla: Yap. 11:22 Lajla: What is given to read is the port continaing "3" 11:22 tony_: Well that's not what MzScheme does. 11:22 Lajla: I can imagine. 11:22 Lajla: But the standard deosn't document this. 11:22 Lajla: THis is pretty implementation specific. 11:22 Lajla: Wait. 11:22 Lajla: Silly me. 11:22 Lajla: It does something completely different. 11:22 Lajla: rudybot, 1 2 3 11:22 rudybot: Lajla: ; Value: 3 11:22 tony_: So now you're saying that RnRS doesn't define the behavior of read? (I really doubt that.) 11:22 Lajla: It wraps (begin ...) around it. :') 11:23 Lajla: tony_, it does define the behaviour of read, but this is something different. 11:23 Lajla: It doesn't at any point in the spec say that if you put a (read) function before some other piece of code it's supposed to read what's after it. 11:23 Lajla: read reads from a port. 11:23 tony_: Fine. 11:23 Lajla: So what most implementations do is they open a window for you to enter text. 11:23 Lajla: rudybot, (read) (display "hello") 11:23 rudybot: Lajla: ; stdout: "hello" 11:24 brooksbp: i tried (read) in drracket repl. it doesn't seem to evaluate anything 11:24 tony_: Anyway, back to an important point: Exactly how does one configure the system to print things the way I like them? 11:25 rapacity: write 11:25 rapacity: in choose language change output syntax to write 11:25 tony_: brooksbp: I just tried it too, but it also doesn't behave the way I wish it did. 11:26 tony_: rapacity: that sounds like a DrRacket menu? 11:26 rapacity: ah 11:26 brooksbp: tony_: what's the behavior you expect? 11:26 rapacity: yeah it is 11:26 tony_: brooksbp: sorry, but we've just thrashed the matter; please see above. 11:27 tony_: rapacity: No DrRacket and no menus for me please :-) I want to run this from a terminal. 11:27 tony_: Lajla: my configure question was posed to you :-) 11:28 Lajla: tony_, I thought rapacity answered it already. 11:28 Lajla: In the 'choose language' part. 11:29 rapacity: (current-print (lambda (e) (write e) (displayln ""))) perhaps :p? 11:31 brooksbp: Does anyone have insight as to why type checking is in the Debugging chapter of SWePR? 11:34 tony_: Lajla and rapacity: FYI, the appropriate switch seems to be print-as-expression. 11:35 Lajla: could be, figured that out a long time ago and didn't really remembe. 11:35 Lajla: WAs really glad when I did. 11:35 rapacity: ah thanks 11:35 Lajla: Because it's just awkward how they try to explain it. 11:35 Lajla: Like in the docs, something like "a quoted value is a list starting with the symbol 'quote and ...." 11:35 Lajla: And then proceeding to ay that ' is an abbreviation 11:35 tony_: The Help Docs have a section called "The Printer" which explains much. 11:36 Lajla: Will lead to a lot of epople scratching their head... 11:36 tony_: I just don't see why they couldn't stick to the old print; they probably have good reasons at the end of the day. 11:37 rapacity: rudybot: (equal? (read (open-input-string "'a")) ''a) 11:37 rudybot: rapacity: ; Value: #t 11:37 (quit) lucian: Remote host closed the connection 11:39 mye: rudybot: (parameterize ((print-as-expression #f)) 'a) 11:39 rudybot: mye: your sandbox is ready 11:39 rudybot: mye: ; Value: a 11:39 mye: my drracket still says 'a so the language options seem to override it?! 11:40 tony_: mye: No, if you evaluate (print-as-expression #f) it will change the behavior to what I like. 11:40 tony_: Anyway, it looks like we should stop calling it "repl" and start calling it "rewl"... 11:43 Lajla: well, that's historical. 11:43 Lajla: scheme just calls what was called print write nowadays. 11:43 Lajla: You see, originally there were no strings... 11:43 Lajla: I think read/write/scan/print is a nice disection of it. 11:45 mye: but why do we want different printing behaviours in the first place? 11:46 (quit) dzhus: Remote host closed the connection 11:46 tony_: mye: because, for one thing, sometimes you want a string to be printed without the double-quote delimiters. 11:48 Lajla: mye, theoretically "write" takes a datum and prints out its s-expression where possible. 11:48 Lajla: print takes a character or a string and prints out those characters. 11:48 tony_: Lajla: I thought a datum *was* an sexp. 11:48 Lajla: No. 11:48 Lajla: sexp are a way to write data. 11:48 Lajla: "(1 2 3)" is the symbolic expression to write that list. 11:49 Lajla: THe list itself is quite abstract 11:49 tony_: I thought a sexp *was* data. 11:49 Lajla: Well, apparently nt 11:49 Lajla: there are multiple ways to write down the same datum 11:49 tony_: Could you give us an example? 11:49 Lajla: "(1 2 3)" or for instance 1 2 3 11:50 tony_: You've just exited the Scheme programming language. 11:50 mye: ?end-user? style rather than ?programmer? style is the references (amusing) explanation, after all people using racket are programmers?! ;-) 11:50 tony_: When I say "datum," I mean it in the sense in which R6RS the word. 11:51 tony_: ...in which R6RS defines the word. 11:51 Lajla: tony_, I'm pretty sure R6 differentiates between data and languages used to write down data. 11:51 (join) anRch 11:51 tony_: AFAIK, R6RS does not mention HTML. 11:51 tony_: (or XML) 11:52 tony_: one moment, let me look it up. 11:53 mye: REWDPL 11:54 tony_: Lajla: R6RS defines datum strictly to refer to Scheme objects. 11:55 Lajla: tony_, so? 11:55 Lajla: That doesn't exclude me from writing them down as I see fit. 11:55 Lajla: A datum and a way to write down such a datum is a different thing. 11:55 Lajla: A sexp is a string, a sequence of characters. 11:55 tony_: A sexp is not a string. 11:55 (join) mwolfe 11:56 Lajla: Yes it is, it's a sequence of characters, it's a _language_ 11:56 Lajla: Or a subset thereof, rather. 11:56 Lajla: You might want to look up M-expressions 11:56 tony_: The only thing it's a subset of is the universe of Scheme objects. Recursively defined, a sexp is a symbol, a number, a string, or a list of sexps. 11:56 Lajla: a historical attempt for a different way to write down the same objects. 11:56 Lajla: Nope, those are data. 11:57 Lajla: THere's a difference between a datum and a way to write down data. 11:57 tony_: OK, we'll have to agree to disagree. 11:57 tony_: Are there any PLT team members here who can enlighten me? 11:58 tony_: eli, are you awake? (Probably not.) 11:58 bremner hopes they are all busy releasing 5.1 12:05 tony_ sighs. 12:05 tony_: Well, it is a Sunday after all. 12:05 offby1 orders bagels and lox 12:06 tony_: I just had an asiago. 12:06 tony_: Delish. 12:07 tony_: So does anyone know which folks here are part of PLT? 12:07 tony_: (other than eli and samth) 12:08 tony_: Nevermind, I just figured it out. 12:10 tony_: clklein, danking, jeapostrophe, samth, or tewk: can one of you be tempted to weigh in? 12:12 bremner: how to make friends and influence people on IRC ;) 12:20 rapacity: boku wa tomodachi ga sukunai 12:20 Lajla: Mä olen koira ja kolme saksaa 12:21 eli: tony_: I'm very awake -- in some ski place (a weekend with tomer and some friends). 12:22 tony_: Boker tov. 12:22 tony_: Have you caught up on our little drama? 12:22 eli: But these places get extremely crowded, so I probably won't be connected for long. 12:22 eli: Where does the drama begins? 12:22 tony_: I'll try to sum it up using the right words: why has Racket given up on the traditional semantics of print? 12:23 eli: No, but there was a change -- values are printed in a way that is closer to being evaluatable. 12:23 tony_: Actually, Eli, if you're oon vacation then this is definitely not worth your time right now. 12:23 eli: So when you enter (car '(x y z)) it prints on the repl as 'x 12:24 tony_: Yes, and I've been grumbling about that. 12:24 eli: Nah, I'm always working for some definition of working. 12:24 tony_: :-) 12:25 (join) lucian 12:25 tony_: My feeling is that only atoms should evaluate to themselves, and 'x = (quote x) => x (...where, obviously, "=" means "gets rewritten to" and "=>" means "gets evaluated to".) 12:27 Lajla: tony_, define 'atom'? 12:27 tony_: ...and I see that part of my problem is a focus on evaluation rather than on printing. 12:27 tony_: Lajla: an atom is a number, a string, a symbol, or the empty list. See R6RS for more. 12:27 Lajla: Depending on literature, anything both a cons is an atom to all things which are identical when eqv? can test them. 12:27 Lajla: tony_, a string too eh? 12:27 Lajla: Also a mutable string? 12:28 tony_: Lajla: I'm sorry but I couldn't quite parse your response. 12:28 Lajla: So why should symbols evaluate to themselves? 12:28 tony_: A pair is definitely not an atom. 12:28 tony_: Symbols do not evaluate to themselves. I misspoke earlier. Sorry. 12:30 Lajla: Ohh, swap 'both'with 'but' 12:31 Lajla: tony_, like I said, by default in #lang racket, it prints the simplest expression that evaluates to what you want, not what you want directly. 12:31 Lajla: This behaviour is kind of nonstandard and most implementations don't do this, and hence you can turn it off if you don't like it. I don't, so I turned it off. 12:32 tony_: OK, we've thrashed this poor matter to Hades and back. I guess the best way to pose my question is: "Why not define another function (called, say, "eprint") to print in the new way; why not leave "print" alone? 12:33 tony_: (I forgot to close my quotes.) 12:33 tony_: And I think we're all tired of arguing it right now... 12:48 Lajla: tony_, I guess because it doesn't solve the repl issue, which is why you want a switch. 12:50 Lajla: (define (eprint x port) (when (or (pair? x) (symbol? x)) (display #\' port)) (print x port)) 12:51 tony_: Lajla: there's clearly something here that I don't understand. The PLT folks probably have a good reason to change the meaning of print, but because we don't see the reason, the change seems arbitrary. 12:52 (quit) anRch: Quit: anRch 12:52 Lajla: tony_, well, the reason is probably that they want to unify the language for code and for data a bit more. 12:52 Lajla: If you want to get a symbol in code, you write 'a 12:52 tony_: ?? 12:52 tony_: What does that mean? 12:52 tony_: Scheme and Lisp have a long history of perfecting the problem of code-as-data. 12:52 Lajla: tony_, not really, often people find it to be quote confusing. 12:53 Lajla: Many people fall for the trap like, if you say (string->symbol "+") ===> + 12:53 tony_: Lajla: thanks for conversing with me at length about this. I just missed a 12:30 appointment and must run! 12:53 Lajla: They wil assume it evaluates to the addion function 12:53 tony_: Talk laters... 12:53 Lajla: Americans are way behind 12:53 Lajla: sure. 12:56 mye: rudybot: ((string->symbol "+") 1 1) 12:56 rudybot: mye: error: procedure application: expected procedure, given: +; arguments were: 1 1 12:58 (quit) tony_: Ping timeout: 276 seconds 12:58 mye: so if i put the symbol + in functional position I DO expect it to be the addition function 12:58 Lajla: Ah, but that is the trap people often fall for. 12:59 Lajla: (+ 1 2) evaluates the head of the list, and then applies it to its arguments 12:59 Lajla: As does ((string->symbol "+") 1 1) 12:59 Lajla: It first evaluates (string->symbol "+") 12:59 Lajla: Symbols evaluate to their values. 13:08 bremner: Is there a way to make the DrRacket debugger step into functions in a different module/file than the current one? 13:24 (join) jonrafkind 13:26 (quit) brooksbp: Remote host closed the connection 13:38 (quit) MayDaniel: 13:39 mye: why not make eval more greedy and eval the functional position of a form until it's really reduced to a value? 13:41 Lajla: mye, you mean to a function 13:42 Lajla: mye, and you lose provability over scheme's lexical scope then. 13:43 Lajla: mye: http://codepad.org/VRpNyQGT 13:50 mye: not necessarily a function, just a non reducible expression. I'm trying to grok why this interferes with lexical scope. 13:53 jonrafkind: mye, are you asking why racket uses eager evaluation? 13:55 mye: jonrafkind: I wonder why it evaluates function position only once, as opposed to until it reaches a non reducible expression. 13:55 jonrafkind: can you show an example? 13:55 mye: rudybot: ((string->symbol "+") 1 1) 13:55 rudybot: mye: error: procedure application: expected procedure, given: +; arguments were: 1 1 13:55 Lajla: jonrafkind, he means, why deosn't that evaluate to 2. 13:55 jonrafkind: because you can't apply + 13:55 Lajla: As it, it keeps evaluating function position up to a function 13:56 jonrafkind: this isn't lisp 13:56 jonrafkind: rudybot: ('+ 1 1) 13:56 rudybot: jonrafkind: your sandbox is ready 13:56 rudybot: jonrafkind: error: procedure application: expected procedure, given: +; arguments were: 1 1 13:56 Lajla: mye, and it ruins lexical scoping. 13:56 jonrafkind: rudybot: (((lambda () +)) 1 1) 13:56 Lajla: Say you have ((string->symbol some-string) 1 2) 13:56 rudybot: jonrafkind: ; Value: 2 13:56 Lajla: And it composes that some-string based on runtime information 13:57 Lajla: there is no way then to establish bindings at compile time. 13:58 mye: I'm kind of getting there, slowly ;-) 13:59 Lajla: mye, basically, if that were allowed, it would be very, very, very hard to efficiently compile scheme. 14:00 Lajla: Essentially any scheme program compiled would have to include a scheme interpreter in it. 14:01 mye: so this is something like first-class macros then. 14:05 Lajla: No, it still won't change the evaluation model of macros. 14:05 Lajla: All arguments would still get evaluated. 14:06 Lajla: But like, say you have (let ((x )) (x 1 2)) 14:06 Lajla: THe compiler can then lexially establish that the x in (x 1 2) must necessarily be bound to right? 14:07 Lajla: In your system, the head may or may not evaluate to x, depending on runtime information or even input. 14:07 Lajla: So the compiler basically can't decide that at compile time when it establishes variable bindings. 14:07 Lajla: The names of variables is essentially thrown away after compilation 14:08 Lajla: (let ((x )) (x 1 2)) and (let ((y )) (y 1 2)) is basically compiled to the same code. 14:15 mye: if (x) has to be a symbol for the form to make sense, then why eval it when it's not a symbol? 14:22 mye: ok, it just has to become a lambda after one step of eval 14:22 jonrafkind: rudybot: ((eval '+) 1 1) 14:22 rudybot: jonrafkind: ; Value: 2 14:25 mye: so, how does eval know a symbol is a macro? 14:25 (join) Demosthenes 14:25 mye: does it look the names of macros up first? 14:25 jonrafkind: it runs the macro expander 14:25 Demosthenes: so, i thought (describe ...) was incredibly useful in CL. is there a racket analogue I missed? 14:25 jonrafkind: Demosthenes, yea theres on on planet 14:26 jonrafkind: http://planet.racket-lang.org/display.ss?package=describe.plt&owner=williams 14:26 rudybot: http://tinyurl.com/25tfz87 14:26 mye: jonrafkind: always unconditionally? 14:26 jonrafkind: yea 14:27 mye: aha 14:27 mye: I think that explains my confusion away 14:27 jonrafkind: eval has few use cases these days 14:32 Lajla: eval suits common lisp more than scheme I guess. 14:33 Lajla: eval complicates a lot of things. 14:33 Lajla: Because basically what the list (+ 1 2) evaluates to depends on a plethora of things. 14:35 (join) dnolen 14:47 (quit) RyanRN: Quit: Leaving. 14:48 (join) RyanRN 14:54 (join) MayDaniel 14:56 (nick) Lajla -> Xajla 15:14 (quit) mye: Ping timeout: 240 seconds 15:20 (join) tony_ 15:32 (quit) mwolfe: Remote host closed the connection 15:36 (quit) Demosthenes: Quit: leaving 15:45 em: i think one of the cool things in scheme is how a procedure can result in a procedure, and still be used in the procedure part of the expression. 15:49 tony_: em: the gods of Scheme hear your praise, and I'm guessing you'll experience a karma boost sometime in the next 48 hours. 15:50 tony_: (That's the average ETA for my Scheme-induced karma boosts.) 16:01 em: haha 16:01 Xajla: em, surely you mean a procedure call? 16:01 Xajla: And though or application 16:01 em: Xajla: yep 16:01 Xajla: Javascript can also do that by the way, and python. 16:02 em: Like I made a procedure porm that becomes + sometimes and - other times and you can do like ((porm) 3 5) 16:02 Xajla: Not a lot of people use it, but (makeAdder(2))(4) is valid javascript. 16:02 Xajla: घघI think you named it like that on purpose. 16:02 Xajla: Just to test how suggestive my mind is. 16:02 Xajla: And I will not fall for it. 16:02 tony_ giggles immaturely. 16:03 Xajla: plus-or-minus 16:03 em: yes :) 16:03 em: Xajla: does Javascript have tail-call-optimization? 16:04 tony_: rudybot: (define (+/- mid range) (cons mid range)) 16:04 rudybot: tony_: your sandbox is ready 16:04 rudybot: tony_: Done. 16:05 tony_: em: observe that you can use operator symbols as function names. 16:05 tony_: In fact, the following would be better: 16:05 tony_: rudybot: (define +/- cons) 16:05 rudybot: tony_: Done. 16:05 Xajla: em, the standard doesn't require it. 16:05 Xajla: Some implementations might have 16:06 em: given that TCO kicksass why does anyone not use it? Is there some cost? 16:06 tony_: em: it's only relevant to languages that use recursion idiomatically. 16:07 tony_: Scala uses it. 16:08 em: if you do this in Python -- 16:08 em: def fact(n): return 1 if n == 0 else n * fact(n -1) 16:08 em: it chokes and dies even before n = 1000 16:09 tony_: but obviously you know why 16:09 em: but the same exact algorithm in Scheme has no problem at all, ever. 16:09 tony_: not true; Scheme will eventually segfault too. 16:09 tony_: (for large enough n) 16:09 em: nope. it might run out of physical memory but it won't stack overflow like python does 16:09 tony_: the stack overflow is the reason *why* Scheme will run out of physical memory. 16:10 lucian: em: besides implementing it, the main cost is having a worse traceback 16:10 em: well try it, scheme is able to keep going orders of magnitude longer than python. 16:11 tony_: em: that may very well be true, but you cannot invoke that factorial func with unbounded n. 16:11 tony_: it's not tail recursive. 16:12 em: i wasn't saying you could. But my point is that Scheme quickly gives answers for inputs that are orders of magnitude larger than where python died. 16:12 em: im assuming that is the TCO 16:12 tony_: No, it isn't. 16:12 tony_: In the code you posted, the recursive call to fact is not in tail position. 16:12 lucian: em: if you rewrite it as a loop in python, it'll be just fine 16:13 tony_: The tail recursive version is: (...give me a sec...) 16:13 lucian: em: it's more a matter of style than anything else. and debuggability 16:14 tony_: (define (fact n) (let loop ((n n) (a 1)) (if (zero? n) a (loop (sub1 n) (* a n))))) 16:16 tony_: lucian: I'm a bit puzzled by your response. Style and debuggability are not the reasons to prefer tail recursion to ordinary recursion. 16:17 lucian: tony_: no, they're the reasons why python doesn't support TCO 16:18 Xajla: em, that's not tail recursive. 16:18 Xajla: And tail recursion gives you less stack trace. 16:18 lucian: Xajla: no, TCO gives you less stack trace 16:18 Xajla: Ehh, sorry. 16:18 Xajla: That is what I meant. 16:19 em: (define (fact a n) (if = n 0) a (fact (* a (fact a n)) (- n 1)))) 16:19 em: how about that one? 16:19 tony_: em: not tail recursive 16:19 em: with (fact 1 n) 16:19 tony_: (and your if has a slight flaw. 16:19 tony_: ) 16:19 em: oh yeah 16:20 tony_: Here's a more transparently tail-recursive version: (...one sec...) 16:21 tony_: (define (fact n) (define (helper m a) (if (zero? m) a (helper (sub1 m) (* a m)))) (helper n 1)) 16:21 tony_: (I also un-shadowed n, for clarity.) 16:22 tony_: But the named let is somewhat conciser. 16:23 Xajla: em, the tail call is * in that case. 16:23 Xajla: A function is tail recursive if its tail call is itself. 16:24 tony_: Xajla, I think you're assuming an order of evaluating the args, no? 16:25 Xajla: tony_, no, why? 16:25 tony_: How do you know (- n 1) is not the last argument to be evaluated? 16:26 em: i think i got one here 16:26 em: (define (fact a n) (if (= n 1) a (fact (* a (- n 1)) (- n 1)))) 16:27 em: but i thought the point of Schemes TCO is that it's TCO even if you don't make iterations. 16:27 tony_: "iterations" means do-loops, while-loops, and the like...all of which are unidiomatic in Scheme. 16:28 em: to me iterations mean that it is constant in space. 16:28 tony_: As for your new factorial, the recursive call is now certainly in tail position, but the correctness of the function depends on how you call it. 16:28 em: a recursive process that is constant in space = iteration. That's what i thought. 16:28 tony_: I'm not familiar with that meaning. 16:28 em: well obviously you call it (f 3 3) 16:29 tony_: I always thought "iteration" meant a loop that was controlled by a dedicated loop variable (usually "i" or "n"). 16:29 em: how are you able to 'see' that this recent one is in tail position? 16:29 em: the reason i knew it would be is because it's an iteration in the sense i just mentioned. 16:30 (quit) Xajla: Ping timeout: 246 seconds 16:30 em: basically i think of an iteration as being a recursive process where the function itself is 'saving up' the results each time, so that it's like, you could put it on pause and give it to someone else, and *start from there* and it could finish. 16:30 tony_: Informally, tail position is just "the last thing that gets evaluated." 16:30 evhan: em: FWIW i don't believe thats a common idea of what "iteration" means 16:31 em: hm 16:31 evhan: though it may very well be technically correct, i dont know 16:31 tony_: iteration and recursion are mutually exclusive. 16:31 em: no i think an iteration is a type of recursion 16:31 bremner: well, depends on the jargon 16:31 em: isn't it? 16:31 tony_: it's very simple: recursion is a form of self-reference. 16:32 tony_: A while/for/do loop does not refer to itself, if for no other reason than that it has no name. 16:32 bremner: iterative is pretty commonly used to refer to tail recursive procedures 16:32 tony_: bremner: yes, but that's done casually. 16:32 bremner: tony_: casually in programming languages texts? 16:32 em: i got the idea i have about what these things mean from when i was reading SICP 16:33 evhan: i think a more common interpretation of 'iterative' would be 'making one or more passes over some data structure' 16:33 tony_: evhan: that rules out a lot of common iterations 16:33 evhan: though i suppose looping a side-effecting procedure would then be ... yes, tony_ 16:33 evhan: thats what i was just realizing 16:34 tony_: bremner: in the context of this conversation, confusion seems to be arising out of not making a strong enough distinction between iteration and recursion. 16:34 em: what about: A recursive process is when a procedure calls itself. And an iteration is a recursive procedure that is constant in space. 16:34 tony_: em: no! :-) 16:34 tony_: em: rather, sometimes! :-) 16:35 tony_: Consider for example the classic tail-recursive version of reverse. 16:35 em: to me the essence of an iteration versus a recursion is this: For a general recursive process if you STOPPED it, and then lost all memory of the past, you could never start it again. But an iteration is a special case of recursion where you could STOP IT and lose all memory of the past, and you could start again and finish. 16:36 em: * ^ 16:36 tony_: It is not an iteration, in the sense that no variable is introduced to control the loop. 16:36 tony_: em: it depends on what you mean by "stop." Does "stopping" entail throwing away the stack? 16:37 em: im not familiar with all the jargon since im not a CS major. 16:37 tony_: which jargon? "stack"? 16:37 em: but i did say "throw away all memory of the past' you retain only the current condition of things. 16:37 em: yeah 16:37 tony_: i see. 16:37 em: if that means the same as stack then i think so. 16:37 tony_: Ok, I'll buy that for the time being. 16:38 bremner: if you think about it, em's defintion is closely related to constant working space 16:39 em: yeah constant space 16:39 tony_: em's definition is workable, but when I hear iteration out of a SICP-like context, I think "for (i = 0; i < n; i++) ..." 16:39 bremner: tony_: yes, but this is #racket ;) 16:40 em: i assumed that in other languages what they call iteration might look different and they may not know it, but it's the same thing. 16:40 tony_: yes, of course, but I sense that em is confused about tail recursion because of something too broad (too narrow?) in his understanding of the word "iteration." 16:40 tony_: (we're going around in circles!) 16:40 em: a recursive process that's keeping the working space constant. I assumed in other languages the designers of the language just hid it from you with syntactic sugar. 16:41 tony_: hid what, exactly? 16:41 (join) Lajla 16:41 bremner: the recursion 16:41 bremner: i.e. the goto 16:41 tony_: OMG! :-) 16:41 em: the fact it's a recursive process that's keeping the working space constant. 16:41 tony_: goto is a veritable *nemesis* of recursion :-) 16:41 evhan: most languages do not perform loops with recursion 16:42 em: even way down under the hood? 16:42 bremner: no, but after tco, the code looks mighty similar 16:42 tony_: em: no, of course at the machine level it's a jump. 16:42 tony_: (i.e., a goto) 16:43 em: did lisp machines do it without jumps? 16:43 tony_: anyway, we have drifted away from the important point, which is that em needs to understand tail recursion. 16:43 tony_: em: I don't know; good question. 16:45 em: my working hypothesis about what TCO means is that somehow it's a guarantee that when you are composing procedure A and procedure B, (A (B)) B will only ever see the final result of A. 16:45 em: oops i meant (B (A)) 16:46 tony_: em: B will always only see the final result of A, no matter how the latter is implemented. 16:46 em: well somehow B does not even come alive until A is done then. 16:46 tony_: That's right. 16:46 em: yeah that's what i meant. 16:46 tony_: More accurately, B is not *applied* until A is *evaluated*. 16:47 em: okay that's cool. 16:47 tony_: em: Out of curiosity, out of which books are you learning Scheme? 16:48 em: I've read the first chapter + a little bit of the second chapter of SICP, and then more recently I read the entire Racket Guide. 16:48 tony_: and how did you find them? 16:48 em: Racket is better than "just scheme" when it comes to feeling like "I could use this to make programs" versus, "I could use this to make algorithms to factor a polynomial" if you get me 16:49 tony_: actually, I don't get you, but one has to be very careful when making pronouncements on such matters. ;-) 16:51 em: Well I wanted to learn some programming language for a long time. Not for any practical reason. Since I mainly want to know programming just to feel smarter and be creative, and have no need for marketable skills my choices were wide open. I chose lisp because that's prestigious, and then once I was looking around lisps chandler pointed me toward Scheme, which leads one to SICP, and obvious PLT is most enjoyable way to do anything with Scheme. 16:51 bremner: I've heard the phrase "batteries included" to refer to Racket. and Python ;). 16:51 evhan: not that batteries are everything, mind 16:52 lucian: bremner: yes, it's a somewhat useful concept. although "batteries handy" is more important 16:52 Lajla: em, you know what, fuck tail recursion, let me explain to you what a tail-call is first. 16:53 Lajla: Not all tail calls are recursive. 16:53 Lajla: Say we have (define (f a b) (x (y z))) 16:53 em: I know a little bit about math so SICP is not *constantly* daunting but when you learn Scheme through SICP you start to feel like this is a cool language to write algorithms, but how will I ever do stuff like write an IRC bot or make a program with a GUI, etc. If you get me. 16:53 Lajla: To what function is the tail call there? 16:53 Lajla: Take a guess 16:53 tony_: Lajla: I'm not parsing you clearly again. :-( 16:54 em: the y ? 16:54 tony_: Are you asking, "Whose continuation is the same as the continuation of f?" 16:54 Lajla: em, no, y is most surely not a tail call. 16:54 Lajla: tony_, yes. 16:54 Lajla: But this one is for em. 16:54 Lajla: We'll get to that later. 16:54 em: well im not sure if you mean which one has to be the tail or make the call or listen for the call or what. 16:54 tony_: Yes, forget continuations. 16:54 Lajla: Let's not overcomplicate it, we're not only dealing with a woman, but also an american, we have to take it slowly. 16:55 Lajla: em, the call to x is the tail call. 16:55 em: i thought the idea of a tail call is that somehow when one is finish evaluating it calls forth the next one, and the next one is not summoned until the first is finished evaluating. 16:55 em: yes a call to x then. 16:55 Lajla: Nonono. 16:55 em: i was saying y has to finish first. 16:55 Lajla: A call is a tail call if basically its return value must automatically also be the return value of the calling function. 16:55 Lajla: Like, whatever the call to x evaluates to. 16:55 Lajla: f will also evaluate to that. 16:55 Lajla: right? 16:55 tony_: Lajla: you mean "the called function." 16:56 Lajla: no, I mean the calling function. 16:56 Lajla: (define (square x) (* x x)) 16:56 em: confusing 16:56 Lajla: A more practical example 16:56 Lajla: the tail call is * 16:56 tony_: yes, ok. 16:56 em: i dont get what you mean by call 16:57 Lajla: em, hmm 16:57 Lajla: Well, let's say that * is a function 16:57 em: i assume tail must means the very last result in any algorithm 16:57 Lajla: Then (* x x) is a call to that function 16:57 Lajla: em, well, it's the result the function itself evaluates to. 16:57 Lajla: (square 3) evaluates to (* 3 3) 16:57 em: not 9 16:57 em: the tail of (square 3) is not 9 ? 16:57 (quit) MayDaniel: Read error: Connection reset by peer 16:58 Lajla: (* 3 3) evaluates to 9. 16:58 em: so isn't the tail of (square 3) 9 then or not? 16:58 Lajla: No, 9 is not a call. 16:58 Lajla: It's a value. 16:58 em: okay 16:58 Lajla: (* x x) is a function call. 16:58 Lajla: or (* 3 3) in this specific instance. 16:58 Lajla: Whose value is 9 16:58 Lajla: And because (* 3 3) evaluates to 9 16:59 Lajla: THen (square 3) evaluates to 9, right? 16:59 em: yeah but that's not the tail i guess. 16:59 em: i guess the tail of (sqare 3) is (* 3 3) 16:59 Lajla: Yeah 16:59 Lajla: That's the tail call. 16:59 em: is it also the tail alone? 17:00 em: i can't imagine how it could be any thing other than a tail call 17:00 Lajla: Okay, something more complex (define (factorial n) (if (zero? n) 1 (* n (factorial (- n 1))))) 17:00 Lajla: It has two tails 17:00 em: how could you possibly do (square 3) if it does not call (* 3 3) 17:00 Lajla: Find them both. 17:01 em: oh maybe (* n (factorial (- n 1))) and (- n 1) ? 17:02 Lajla: THe first is correct 17:02 Lajla: the other tail is 1 17:02 Lajla: Which is not a call 17:02 Lajla: So it's not a tail call, but it's still a tail. 17:02 Lajla: This is because, whatever happens, the function either evaluates to 1, or to (* n (factorial (- n 1))) , right? 17:02 em: oh i see that's a tail. 17:02 Lajla: For any input n, that is what happens. 17:03 Lajla: It either evaluates to these two expressions, 1 or (* n (factorial (- n 1))) 17:03 em: yeah 17:03 em: that's clear enough 17:05 Lajla: Cool, one more for the road: (define (describe person) (case person ((emma) "has boobs") ((lajla) (string-append "very" " annoying")) ((chandler) "gone from here") (else (+ 1 2 3))) 17:05 Lajla: You see there are four tails there, two of which calls, right? 17:06 em: yes 17:07 em: 4 tails and string-append and + are the calls 17:07 Lajla: Yeah. 17:07 Lajla: Well, technically they are the functions being called in the calls, but you get it. 17:07 Lajla: So this is why (define (factorial n) (if (zero? n) 1 (* n (factorial (- n 1))))) is not _tail recursive_ 17:07 em: did chandler say he was never coming back here? 17:08 Lajla: Even though there are definitely tail calls 17:08 Lajla: But the tail call is to * 17:08 bremner: em: you know how some people have imaginary friends? Lajla has imaginary enemies. 17:08 em: hehe 17:08 Lajla: So, to make it _tail recursive_ you have to find a way to make the call to factorial itself. 17:08 Lajla: bremner, nonononon, chandler is real man. 17:08 Lajla: He banned me from #scheme. 17:09 em: oh that takes some doing, i thought that was a pretty relaxed channel with hardly any moderation at all. 17:09 em: you could probably just get unbanned by now. 17:10 em: anyone who listens to you can tell you know a lot about scheme 17:10 Lajla: So... enter: (define (factorial n) (define (factorial-helper n acc) (if (zero? n) acc (factorial-helper (- n 1) (* acc n)))) (factorial-helper n 1)) 17:10 Lajla: em, chandler disagrees. 17:10 Lajla: And besides, no offense, but you're probably not yet the best person to judge that. 17:10 Lajla: Point was, I made a joke about child rape. -_- 17:11 em: Always a risky move. 17:11 Lajla: But, the factorial-helper function there is tail-recursive. 17:11 em: you gotta no your audience 17:11 Lajla: I like ot live dangerously. 17:11 Lajla: Well, I made it like 2 seconds after I entered. And I got back at me months and months later. 17:11 Lajla: I usually enter channels with a controversial statement to test if people aren't total stiffards. 17:12 em: well i know that feeling ostracised is one of the worst feelings and it is hard to let go of especially for people who already may have a tendency to focus on things with the laser like attention that is usually an asset in something like programming. 17:12 Lajla: But, going on, the factorial-helper is tail recursive there, factorial itself is not, but it calls factorialh-elper after like only one call, so it's really not that bad. 17:12 (quit) tony_: Quit: Ex-Chat 17:12 em: We will try to work this out. I have to go get my pizza now though. 17:13 Lajla: lol american pizza lol. 17:13 Lajla: Bon appetit. 17:18 em: I know you have an irrational disregard for America but the USA is where some of the best Pizza can be found. I would even say, by now, it's become an American food. 17:18 em: You have maybe never been to NYC or Chicago etc. 17:21 (join) Fare 17:22 Lajla: Nahh, I just jest 17:22 Lajla: I like New York Pizza. 17:22 Lajla: em, but you now realize what you have to do to make a function tail-recursive, right? 17:27 (join) lewis1711 17:27 (join) jao 17:27 (quit) jao: Changing host 17:27 (join) jao 17:48 (join) tony_ 18:47 tony_: Lajla and bremner: btw, I got an enlightening mailing list response to my 'print' query from the good folks at PLT. 18:48 Lajla: tony_, what did they say? 18:48 tony_: Several things, most important of which is that, astonishingly, the R6RS standard does not specify the behavior of print (!). 18:51 (join) jfalcon 18:54 Lajla: tony_, I'm pretty sure that 'print' is a nonstandard extension 18:54 Lajla: R5/R6 define write and display 18:55 tony_: Yes, that's the point. 18:55 tony_: I didn't know that until now. 19:01 lewis1711: http://paste.pocoo.org/show/337978/ bah, who needs classes 19:12 eli: tony_: Sorry, I got disconnected right after that. 19:13 tony_: eli: not a problem; I got a thorough answer on the mailing list. 19:13 eli: Americans are an extraordinarily habitual animals -- 12:00 comes, and they all flock to the dining areas. 19:13 tony_: How was skiing? 19:13 tony_: I hear the French are even more regimented... 19:13 eli: Tomer was doing nicely -- even knows how to turn. 19:13 lewis1711: http://docs.racket-lang.org/guide/contract-func.html#(part._contracts-flat-named-contracts) why is not default behaviour? :/ 19:14 eli: In any case, the whole debate refers to the usual argument on evaluation vs normalization. 19:14 tony_: Cool. I haven't skied in about 6 years. 19:14 eli didn't ski in much more... 19:14 tony_: Well I was working on the very wrong assumption that R6RS defines print; was surprised to discover it doesn't. 19:15 eli: There are some other scheme implementations that print an `x' symbol as "'x". 19:15 tony_: So it's up for grabs. 19:15 eli: Yeah, that's kind of the whole point of having a function that is not under any standard. 19:15 tony_: But this is truly surprising, because the concept of REPL is so fundamental. 19:15 eli: (Or expectations.) 19:15 tony_: Yes, but the repl itself sets up expectations (at least for me.) 19:16 tony_: As in: "repl" and not "rewl" and not "redl". 19:16 tony_: Anyway, I'm safe with #lang scheme. 19:16 eli: There's no contradiction here -- it's still a "print" step. 19:16 eli: The only question is how stuff gets printed. 19:17 tony_: yep. 19:17 eli: And it just happens that it took a long time to get to a printout that is more like scheme48's or mit-scheme's. 19:17 tony_: Is that what they do? 19:17 eli: Yeah. The latter goes to an even more extreme printout thing, where it can print closures out. 19:18 tony_: That makes more sense to me. 19:18 tony_: So I guess consistency requires that 'a be printed as 'a after evaluation. 19:19 eli: Well, it's kind of a higher commitment to the repl -- making it a little more than just a device for quick experiments. 19:19 eli: Oh here -- 19:19 eli: (lambda (x) x) gets printed as 19:19 eli: ;Value 11: #[compound-procedure 11] 19:19 tony_: That's PLT Scheme, right? 19:20 eli: And once you see that you can type just that -- #[compound-procedure 11] -- and it will evaluate to the same function. 19:20 eli: No, that's mit-scheme. 19:20 eli sighs 19:20 eli: Every time I exit mit-scheme I need to look for a barf bag. 19:20 tony_: So, the number 11 must be a unique oid for closures. 19:20 eli: "End of input stream reached.", "Happy Happy Joy Joy." 19:21 tony_ hands Eli a barf bag from Jet Blue. 19:21 eli goes to dinner stuff... 19:23 eli: tony_: Yeah, it basically assigns a number for every otherwise-unprintable value to make a printout that can still access it. 19:23 eli: It's kind of cute, but there's a question about GCing, of course. 19:24 lewis1711: http://paste.pocoo.org/show/337980/ what does the top error mean? :/ 19:25 tony_: eli: This is beginning to make more sense now. I knew there must be a good reason for it but just couldn't figure it out. 19:37 (join) jack 19:37 jack: hey guys 19:38 jack: anyone here? 19:38 (nick) jack -> Guest67232 19:38 Guest67232: hi 19:38 Guest67232: is anyone here 19:40 jonrafkind: sup bro 19:43 offby1: nobody here but us zombie processes. 19:44 jonrafkind: i like the switch from a real name to some random guest name 19:44 jonrafkind: classy 19:45 (quit) jao: Ping timeout: 240 seconds 19:46 Guest67232: the system did it 19:47 offby1: I blame society 19:47 Guest67232: could you guys help me with a design? 19:48 jonrafkind: you don't need to ask to ask. just ask 19:48 Guest67232: kk, thanks 19:49 Guest67232: i want to make a permutation of a list, it should return all the possibilities 19:49 Guest67232: eg, for input 123, i should get 123, 132 213 231 312 321 19:50 lewis1711: humm, permutation is always a set isn't it? 19:51 Guest67232: i want to do it like a list of lists 19:51 Guest67232: so it should return (list (list 1 2 3) (list 1 32) etc)) 19:51 Guest67232: yup 19:51 Guest67232: it should be 19:53 offby1: Guest67232: here's what I stole from SICP: http://ix.io/1tm 19:53 offby1: rudybot: eval (define (perms s) (if (null? s) (list '()) (append-map (lambda (x) (map (curry cons x) (perms (remove x s)))) s))) 19:53 rudybot: *offby1: your scheme sandbox is ready 19:53 rudybot: *offby1: Done. 19:53 offby1: rudybot: (perms (list 1 2 3)) 19:53 rudybot: *offby1: ; Value: ((1 2 3) (1 3 2) (2 1 3) (2 3 1) (3 1 2) (3 2 1)) 19:53 Guest67232: actually, im stuck on one thing. i have a list, and i want to insert an element to every position of the list 19:53 Guest67232: thx, buddy! 19:54 offby1: bonus points if you understand what it's doing :) 19:55 Guest67232: im trying 19:56 Guest67232: but it returns an error, the function contains ', 19:56 Guest67232: quote: expected a name after a ', found something else 19:56 lewis1711: could you do it with a list comprehension? in haskell: [(a, b, c) | a <- [1..3], b <- [1..3], c <- [1..3], a/=c, a/=b, b/=c] 19:56 lewis1711: racket has iota, and list comprehensions 19:58 Guest67232: append-map is not defined 19:59 offby1: rudybot: doc append-map 19:59 rudybot: *offby1: http://docs.plt-scheme.org/reference/pairs.html#(def._((lib._racket%2Flist..rkt)._append-map)) 20:00 (join) jao 20:00 (quit) jao: Changing host 20:00 (join) jao 20:01 Guest67232: thx, probably im in beginning student custom, so it doesnt contain append-map 20:01 offby1: that'd probably be the reason 20:03 Guest67232: what language r u using? 20:03 jonrafkind: r u 20:03 jonrafkind: are you 20:04 Guest67232: what language are you using? 20:04 bremner: what course are you doing homework for? 20:05 offby1: m uzng "racket" 20:05 offby1: rudybot: (perms (build-list 5 values)) 20:05 rudybot: *offby1: ; Value: ((0 1 2 3 4) (0 1 2 4 3) (0 1 3 2 4) (0 1 3 4 2) (0 1 4 2 3) (0 1 4 3 2) (0 2 1 3 4) (0 2 1 4 3) (0 2 3 1 4) (0 2 3 4 1) (0 2 4 1 3) (0 2 4 3 1) (0 3 1 2 4) (0 3 1 4 2) (0 3 2 1 4) (0 3 2 4 1) (0 3 4 1 2) (0 3 4 2 1) (0 4 1 2 3) (0 4 1 3 2) (0 4 2 1 3) (0 4 2 3 1) (0 4 3 1 2) (0 4 3 2 1) (1 0 2 3 4) (1 0 2 4 3) (1 0 3 2 4) (1 0 3 4 2) (1 0 4 2 3) (1 0 4 3 2) (1 2 0 3 4) (1 2 0 4 3) (1 2 3 0 4) (1 2 3 4 0) (1 2 4 0 20:05 offby1: rudybot: (perms (build-list 10 values)) 20:05 rudybot: *offby1: error: evaluator: terminated (out-of-memory) 20:05 offby1 drums fingers 20:05 offby1: rudybot: (perms (build-list 2 values)) 20:06 rudybot: *offby1: your scheme sandbox is ready 20:06 rudybot: *offby1: error: reference to an identifier before its definition: perms in module: 'program 20:06 offby1: *gasp* 20:07 Guest67232: for ubc cpsc 110 20:08 jonrafkind: xyz 123 20:10 Guest67232: i still dont get append-map...but thank you anyways 20:13 offby1: (define (append-map proc seq)) is just (apply append (map proc seq)) 20:19 (join) jfalcon_ 20:19 (quit) jfalcon: Read error: Connection reset by peer 20:19 (nick) jfalcon_ -> jfalcon 20:23 em: offby1: hey where did it get perms from that's not in racket is it? 20:24 offby1: em: I pasted in the definition half an hour ago 20:24 offby1: rudybot: eval (define (perms s) (if (null? s) (list '()) (append-map (lambda (x) (map (curry cons x) (perms (remove x s)))) s))) 20:24 rudybot: *offby1: Done. 20:25 em: offby1: rudybot remembers all your definitions from previoius conversations with it? 20:25 em: offby1: does it keep it seperate for each person? 20:25 offby1: unless the sandbox blows up, or two other people create sandboxes. 20:25 offby1: yes, they're separate 20:25 em: offby1: and can you ever reset it? 20:25 offby1: rudybot: (perms (build-list 2 values)) 20:25 rudybot: *offby1: ; Value: ((0 1) (1 0)) 20:25 offby1: yes 20:25 offby1: rudybot: init racket 20:25 rudybot: *offby1: your racket sandbox is ready 20:25 offby1: rudybot: (perms (build-list 2 values)) 20:25 rudybot: *offby1: error: reference to an identifier before its definition: perms in module: 'program 20:25 offby1: voilà 20:25 em: cool 20:25 offby1: eli wrote most of that 20:26 (quit) lucian: Remote host closed the connection 20:27 Guest67232: suppose i have a list, and i want to insert an element to every postion of the list. how can i do that? 20:27 jonrafkind: add-between or smoething 20:28 offby1: suppose I am a Congressman, and suppose I am an imbecile. But I repeat myself. 20:29 offby1: rudybot: (map (curry cons 3) (list 'a 'b 'c)) 20:29 rudybot: *offby1: ; Value: ((3 . a) (3 . b) (3 . c)) 20:29 em: offby1: then i suppose you would post a half naked picture of yourself through craigslist. 20:29 bremner: don't give him ideas 20:29 offby1: em: I was on vacation last week, but I am dimly aware of what you refer 20:30 offby1: rudybot: (append-map (curry list 3) '(a b c)) 20:30 rudybot: *offby1: ; Value: (3 a 3 b 3 c) 20:30 Guest67232: thx 20:31 Guest67232: but racket dont accept curry 20:31 offby1: charlie don't surf 20:31 offby1: rudybot: doc curry 20:31 rudybot: *offby1: http://docs.plt-scheme.org/reference/procedures.html#(def._((lib._racket%2Ffunction..rkt)._curry)) 20:31 offby1 begs to differ 20:32 offby1: Guest67232: you're probably still in a restricted language. 20:32 tony_: Guest: (foldr (lambda (x a) (cons x (cons something a))) '() the-list) 20:33 Guest67232: i guess so 20:33 offby1: (apply append (map (curry list 3) '(a b c))) 20:33 offby1: rudybot: (apply append (map (curry list 3) '(a b c))) 20:33 rudybot: *offby1: ; Value: (3 a 3 b 3 c) 20:33 offby1: rudybot: (apply append (map (lambda (frotz) (list 3 frotz)) '(a b c))) 20:33 rudybot: *offby1: ; Value: (3 a 3 b 3 c) 20:33 offby1: ta da 20:34 em: curry is really weird 20:34 Guest67232: thank you so much offby1 20:34 Guest67232: and budybot 20:34 Guest67232: and everyone here today 20:34 tony_: the fold solution is more efficient and easier to understand. 20:35 tony_: (oh well...my 2 cents) 20:35 Guest67232: i guess my racket is so restricted that it doesnt accept apply... 20:36 offby1: geez 20:37 tony_: So is there an 8 pm fold curfew? 20:38 offby1: doubt it; fold is over 15, as far as I know. 20:41 (quit) RyanRN: Read error: Connection reset by peer 20:41 (join) RyanRN 20:53 (quit) tony_: Ping timeout: 240 seconds 20:53 dnolen: is it possible to import fluid-let into a Racket program? how do you do this? 20:54 (part) lewis1711 20:55 offby1: rudybot: doc fluid-let 20:55 rudybot: *offby1: no docs for a current binding, but provided by: mzscheme 20:55 offby1: rudybot: (require 'mzscheme) 20:55 rudybot: *offby1: error: require: unknown module: 'mzscheme 20:55 offby1: rudybot: (require mzscheme) 20:55 rudybot: *offby1: Done. 20:55 offby1: rudybot: doc fluid-let 20:55 rudybot: *offby1: http://docs.plt-scheme.org/mzscheme/Old_Syntactic_Forms.html#(form._((lib._mzscheme%2Fmain..rkt)._fluid-let)) 20:56 offby1: rudybot: eval (fluid-let ([a 10]) (printf "a is ~a~%" a)) 20:56 rudybot: *offby1: error: reference to an identifier before its definition: a in module: 'program 20:56 offby1: rudybot: eval (let ([a 'frotz]) (fluid-let ([a 10]) (printf "a is ~a~%" a))) 20:56 rudybot: *offby1: ; stdout: "a is 10\n" 21:07 (quit) jfalcon: Quit: jfalcon 21:09 dnolen: thx 21:22 em: currying is so strange tome. 21:23 em: what is the real purpose of it, when do you use it mostly? why not just avoid it? 21:27 offby1: saves typing :) 21:27 offby1: (curry cons 3) => (lambda (x) (cons 3 x)) 21:28 em: so it's sort of something ot use when you want a built in value for a two or more argument procedure? 21:28 bremner: saves even more typing in Haskell, where (curry cons 3) is written "cons 3" ;) 21:29 offby1: em: the idea is that you take a function that takes N arguments, and you want some of them to be constant, so it makes you a new function where you only have to specify the other arguments. 21:30 em: okay that makes senes 21:46 (quit) Blkt: Quit: ERROR: do not makunbound t please! 21:51 (quit) Guest67232: Quit: Page closed 22:23 (quit) jonrafkind: Ping timeout: 240 seconds 22:42 (nick) coyotama|2 -> coyotama 22:43 (nick) coyotama -> bandu 22:43 (quit) bandu: Changing host 22:43 (join) bandu 22:44 (nick) bandu -> tama 22:44 (nick) tama -> bandu 23:04 (quit) corruptmemory: Ping timeout: 240 seconds 23:59 (quit) masm: Ping timeout: 245 seconds