00:07 (quit) mwolfe: Remote host closed the connection 00:46 (quit) masm: Quit: Leaving. 01:25 (join) jonrafkind 01:47 (quit) jeapostrophe: Quit: jeapostrophe 02:31 (quit) jonrafkind: Read error: Operation timed out 04:34 (quit) jsj: Read error: Connection reset by peer 04:35 (join) jsj 04:59 (quit) jsj: Read error: Connection reset by peer 05:55 (join) lucian 07:33 (quit) lucian: Remote host closed the connection 07:47 (join) MayDaniel 07:51 (quit) jao: Changing host 07:51 (join) jao 08:00 (join) dzhus 08:01 (quit) dzhus: Read error: Connection reset by peer 08:03 (join) dzhus 08:09 (join) jeapostrophe 08:21 (join) jsj 08:23 (join) dzhus89 08:24 (quit) dzhus: Ping timeout: 240 seconds 08:27 (quit) dzhus89: Remote host closed the connection 08:30 (join) mceier 08:36 (join) masm 08:38 (quit) jeapostrophe: Quit: jeapostrophe 08:39 (join) jeapostrophe 08:39 (join) jst 09:08 (quit) MayDaniel: 09:13 (join) hanDerPeder 09:16 (quit) hanDerPeder: Client Quit 09:36 (quit) jeapostrophe: Quit: jeapostrophe 09:39 (join) anRch 10:20 (join) b-man_ 10:24 (join) hanDerPeder 10:26 (quit) b-man_: Remote host closed the connection 10:28 Demosthenex: anyone recommend a good macro tutorial? at first glance, CL's defmacro makes more sense to me than this syntax scheme. 10:48 Lajla: Demosthenex, wouldn't you say that syntax-rules is a lot easier? 10:48 Lajla: If not arguably less expressive. 10:48 Lajla: Syntax-case however is so rediculously complicated that even jonrafkind has been bested by it. 10:49 Lajla: Demosthenex, it's remarkably intuitive. (syntax-rules () ((let ((name value) ...) . body) ((lambda (name ...) . body) value ...)) pretty much explains itself no? 10:50 (quit) anRch: Quit: anRch 10:51 Demosthenex: Lajla: really, coming from using defmacro, the syntax thing doesn't make much sense to me... or maybe i just haven't seen a good example yet 10:54 (join) mije 10:54 mije: hoy 10:54 mije: is there somewhere a documentation about the preferred way to use racket with emacs ? 10:55 Demosthenex: geiser! 10:55 mije: ! 10:55 Demosthenex: its not slime, but its good 10:56 mije: ok, thanks a lot 11:03 Demosthenex: Lajla: do you recommend a tutorial that can make them clear? 11:04 (join) dzhus 11:25 Lajla: Demosthenex, yeah, I know one, hold on 11:25 Lajla: http://blog.willdonnelly.net/2008/09/04/a-scheme-syntax-rules-primer/ 11:26 Lajla: By the way, I think racket and most other scheme implementations also support a defmacro 'low level macro' as we call it. 11:26 Lajla: But if you really want the motherload, I'd reccomend syntax-case 11:28 Demosthenex: ooo, defmacro would be nice ;] 11:28 Demosthenex: i didn't see it in the racket reference index 11:29 (quit) jst: Ping timeout: 240 seconds 11:30 Lajla: I think it's define-macro. 11:30 Lajla: But like, most scheme users don't like defmacro because it lacks hygiene 11:30 Lajla: Your macro no longeris a 'black box' and it's possible for users to break it by redefining other stuff and all that. 11:31 Lajla: Like, say your macro uses the * function, and it is located in a body (let ((* exp)) ) 11:31 Lajla: It would stop functioning properly. 11:46 Demosthenex: my use-case is pretty simple. i'm making a structure and some related functions, and need consistent naming across them and to iterate over a list of values to eliminate redundant coding 11:47 Lajla: Demosthenex, iterate over a list already has two functions for-each and map. 11:47 Lajla: Depending on if you want the side-effect or the return value. 11:48 Lajla: basically, map has no guarantee in what order it is done (Scheme is less strict with requiring a certain evaluation order for arguments than CL) 11:48 Lajla: And for-each does guarantee it be done from left to right. 11:48 Lajla: map is basically mapcar, but without that guarantee. 11:48 Lajla: Like (map square '(1 2 3 4 5)) 11:49 Lajla: If you want to print them, you would use (for-each display '(1 2 3 4 5)) because map doesn't guarantee the side effects are performed in order. 11:49 Demosthenex: oh no... wait ;] 11:50 Demosthenex: i mean i'd typically use a macro to generate this code from a list in CL 11:52 Lajla: Ahhh 11:53 Lajla: Well, you can use define-macro (I believe it's called) here. 12:01 Demosthenex: Lajla: http://pastebin.com/QJ42X6Gg 12:01 Demosthenex: that's what i'm trying to accomplish 12:02 Demosthenex: these snooze structs are tied positionally, so i'm trying to use a macro/syntax to ensure that my code is aligned in order 12:04 Lajla: Demosthenex, what do you mean with 'alighned in order'? 12:05 Demosthenex: the snooze structures constructor is positionally dependent, so if i get an argument out of order i break it 12:05 Demosthenex: (make-mytype a b c d e), instead of (make-mytype #:e e #:c c #:b b ........... 12:06 Demosthenex: that one's short, 5 parameters... but you see its defined in one place, and called in another 12:06 Demosthenex: i've got others with over 20 12:06 Lajla: Ahhh 12:06 Lajla: You want keyword arguments? 12:07 Demosthenex: well, it appears that snooze doesn't support keyword arguments int he constructor 12:08 Demosthenex: but given i'm defining a data type, and a parser... this is an ideal macro 12:08 Demosthenex: there's little unique code, it could be encapsulated into a list, and expanded into code 12:09 Demosthenex: the only unique parts are the name, regexp string, and datatype 12:10 (join) lucian 12:56 (join) jonrafkind 12:57 (join) MayDaniel 13:44 (quit) mije: Ping timeout: 265 seconds 13:48 (join) b-man_ 14:13 (quit) b-man_: Remote host closed the connection 14:13 (quit) Gwyth: Ping timeout: 240 seconds 14:14 (join) b-man_ 14:20 (quit) b-man_: Remote host closed the connection 14:21 (join) b-man_ 14:28 (quit) dzhus: Remote host closed the connection 14:29 (quit) em: Ping timeout: 245 seconds 14:30 (join) em 14:34 (quit) jonrafkind: Ping timeout: 240 seconds 14:48 (join) jonrafkind 14:57 (quit) Lajla: Ping timeout: 240 seconds 14:58 (join) Lajla 15:01 (quit) mceier: Quit: Lost terminal 15:02 (join) mceier 15:09 (quit) MayDaniel: Read error: Connection reset by peer 15:30 (quit) lucian: Ping timeout: 255 seconds 15:36 (join) lucian 15:48 (join) philo_ 15:48 philo_: hi 15:48 philo_: what is equivalement of the amb function in racket ? 15:53 jonrafkind: amb 15:53 philo_: in wich package ? 15:54 jonrafkind: oh i guess its only in planet: http://planet.racket-lang.org/display.ss?package=amb.plt&owner=wmfarr 15:54 philo_: thanks 15:54 Lajla: Amb function or special form? 15:54 philo_: what is the difference ? 15:54 philo_: i cant seems to find the doc about it 15:55 Lajla: philo_, the difference is that the one is syntax and the other a function. 15:55 Lajla: I once had to botch my own functional form of it together, I'm still not sure on how optimal it is. 15:55 Lajla: THe most important difference is apply though 15:55 Lajla: That you can have a runtime-based solution space. 15:57 (join) MayDaniel 16:01 (quit) lucian: Ping timeout: 260 seconds 16:02 philo_: i tought i was included in the standard 16:03 (join) lucian 16:04 Lajla: philo_ 'which standard?' =) 16:04 philo_: racket 16:04 philo_: like in racket\base 16:05 Lajla: Some would object to calling racket a 'standard' though. 16:05 philo_: ok 16:06 Lajla: But I don't think so no. 16:19 philo_: reading the update on 5.1 16:19 philo_: why did they use Gtk instead of Qt ? 16:19 philo_: someone knows ? 16:23 (join) helloworld 16:24 helloworld: hello everybody ! Does anybody know how to do to display the result of a function in a window ? 16:29 helloworld: Please ? 16:30 askhader: Wrap a (display ..) around the function call perhaps? 16:30 Lajla: helloworld, that quaestion could not be more vague. 16:30 Lajla: helloworld, you mean print it out? 16:34 (quit) b-man_: Remote host closed the connection 16:37 offby1: I'm kinda guessing he/she/it means "have a new GUI window appear that contains nothing but the characters that make up the printed representation of the value" 16:42 Lajla crawls submissively to offby1 like a dog. 16:48 (quit) MayDaniel: 16:48 (quit) philo_: Ping timeout: 265 seconds 16:49 helloworld: exactly... offby1 :D 16:49 helloworld: and I'm "he" :P 16:49 offby1: ... and I don't know how to do that :-( 16:49 offby1: I assume it's easy; and will be even easier once they release 5.0.3, which contains all kindsa spiffy GUI improvements 16:53 helloworld: askhader : I tried a few things but it still displays it in the original window, the soft's window... 17:00 (quit) tv|z: Ping timeout: 245 seconds 17:01 askhader: Oh you want a GUI window to display the text? 17:01 (join) tv|z 17:01 rapacity: (require racket/gui) (message-box "Message" "Hello World") ? 17:02 helloworld: yes that's it 17:04 (join) hanDerPeder_ 17:04 helloworld: rapacity : the thing is, I want to display the result of a function, and it does not accept functions... 17:04 helloworld: but thanks anyway 17:05 rapacity: does not accept functions ? 17:05 rapacity: (message-box "Message" (format "~a" return-value)) 17:06 (quit) hanDerPeder: Ping timeout: 260 seconds 17:06 (nick) hanDerPeder_ -> hanDerPeder 17:06 helloworld: wow if it works i LOVE you!!! lol 17:12 (join) FareWell 17:16 Lajla: helloworld, maybe number->string or something like that is simpler 17:16 Lajla: if your function returns a number 17:18 helloworld: Lajla : no, in fact my function returns a display... 17:18 Lajla: helloworld, returns a display? 17:18 Lajla: What do you mean with that? 17:18 Lajla: helloworld, you mean it produces a side-effect? 17:18 helloworld: rapacity : well, it worked with a function returning a number but with mine it writes # 17:19 Lajla: Ahhh 17:19 Lajla: helloworld, then the function doesn't return a value 17:19 Lajla: but causes a side-effect. 17:19 Lajla: Try with-output-to-string, if I'm not mistaken 17:19 Lajla: Not sure if that'sthe name, I don't really use it 17:19 helloworld: ok i try thanks fo helping me 17:20 Lajla: I think that (with-output-to-string (the-function x)) is the correct form 17:20 Lajla: It turn the output into a string I think 17:21 helloworld: with-output-to-string: expected argument of type ; given # 17:22 rapacity: (with-output-to-string (lambda () code )) 17:25 Lajla: Hmm 17:25 Lajla: It expects a procedure eh? 17:25 Lajla: I would just macro around that. 17:25 helloworld: ok !!! it WORKS !! BUT (hehe, still a but) i can only do "ok" then it closes the window, whereas I'd like to refresh the window with the new values... Some details or am I understandable? 17:26 rapacity: yeah with-output-to-string is a function 17:26 Lajla: rapacity, is there also a way to control from which port it reads? 17:26 offby1: helloworld: I think you need to read the documentation for GUI programming 17:27 rapacity: which port what reads :p? 17:27 Lajla: rapacity, the with-output-to-string 17:28 Lajla: Like, the output to which port it catches in the string. 17:28 Lajla: Like, say you give it a thunk which writes to two different ports 17:28 rapacity: with-output-to-string only parameterizes over the current-output-port 17:30 Lajla: Ahhh 17:30 Lajla: And you can't control which port? 17:30 offby1: try "call-with-output-string" if you want the output port passed to your procedure 17:30 Lajla: Or you have to set the current output porth before? 17:30 offby1: y'know folks, these functions are all documented. 17:30 offby1: rudybot: doc call-with-output-string 17:30 Lajla: Well, let me just cut to the chase. 17:30 rudybot: offby1: http://docs.plt-scheme.org/reference/port-lib.html#(def._((lib._racket%2Fport..rkt)._call-with-output-string)) 17:30 Lajla: I want this macro (catch-output expression port ?) 17:31 Lajla: port part being optional. 17:31 Lajla: It returns a string. 17:31 Lajla: And well, you get what it does. 17:31 Lajla: How would you write it? 17:31 Lajla: Without the port argument it would be easy of course 17:39 (quit) rapacity: Quit: Lost terminal 17:41 (join) rapacity 17:43 helloworld: well it works for me (I just asked the message box again after each action... i've got to click ok before doing anything but it's ok for me !), thank you guys !!! 17:44 rapacity: you can just make a frame% with a text-field% 17:57 (join) offby1` 17:59 (quit) offby1: Ping timeout: 245 seconds 18:03 (nick) offby1` -> offby1 18:04 (quit) helloworld: Quit: Page closed 18:16 (quit) jonrafkind: Ping timeout: 276 seconds 18:17 (quit) parcs: Ping timeout: 240 seconds 18:19 (quit) mceier: Quit: leaving 18:19 (join) parcs 18:20 Demosthenex: ok, i'm still struggling with this syntax idea. can someone tell me how i can do (create-stuff thing '(+ 1 2)) turning into (define (thing-maker) (+1 2)) 18:21 offby1: eli certainly could 18:21 offby1: Demosthenex: do you realize that this is quite similar to what "struct" does? 18:21 offby1: rudybot: doc struct 18:21 rudybot: offby1: http://docs.plt-scheme.org/mzlib/mzlib_unit.html#(form._((lib._mzlib%2Funit..rkt)._struct~7es)) 18:21 offby1: rudybot: doc define-struct 18:21 rudybot: offby1: http://docs.plt-scheme.org/reference/define-struct.html#(form._((lib._racket%2Fprivate%2Fbase..rkt)._define-struct)) 18:21 offby1: that second link is probably better 18:35 Demosthenex: yeah... i'm actually trying to combine snooze with a parser, and trying to minimize code and keep issues with positional parameters to a minimum 18:35 Demosthenex: defmacro in CL makes sense to me, this syntax thing is greek 18:36 Lajla: Demosthenex, why? 18:36 Lajla: I mean, it's far more high level and it works with template. 18:36 Lajla: Also, it lacks the expressiveness to do what you want there. 18:38 Demosthenex: nah, i could make a defmacro pretty quickly. its this template stuff i just am not getting 18:39 (quit) FareWell: Quit: Leaving 18:40 (quit) masm: Quit: Leaving. 18:41 eli: rudybot: (define-syntax (create-stuff stx) (syntax-case stx () [(_ name expr) (with-syntax ([maker (datum->syntax #'name (string->symbol (format "~a-maker" (syntax-e #'name))))]) #'(define (maker) expr))])) 18:41 rudybot: eli: your racket sandbox is ready 18:42 rudybot: eli: Done. 18:42 eli: rudybot: (create-stuff thing '(+ 1 2)) 18:42 rudybot: eli: Done. 18:42 eli: rudybot: (thing-maker) 18:42 rudybot: eli: ; Value: (+ 1 2) 18:42 eli: Demosthenex: ^ 18:42 eli will brb 18:43 Demosthenex: gah,. i was actually close 18:43 Demosthenex: i didn't have the #' in the last part 18:43 Demosthenex: and kept getting 18:43 Demosthenex: "literal is not an identifyer" 18:48 eli: Demosthenex: So the way to think about this, as someone who is used to CL is: 18:48 eli: First, a syntax transformer is something that gets the whole expression, not just the arguments one by one -- that's what the (define-syntax (create-stuff stx) ...) is 18:49 eli: This allows you to separate the transformer function from the actual name that is used. 18:49 (join) b-man_ 18:49 eli: Then, you have `syntax-case' to do the doconstruction work. 18:49 eli: What `syntax-case' binds are not normal bindings -- instead, it binds "template variables". 18:50 eli: These template variables have a value that can only be used inside a `syntax' form -- where `syntax' is kind of like a `quote'. 18:50 eli: Or actually kind of like a `quasiquote', where all the template variables are automatically unquoted. 18:51 eli: (Again, this is rough, since you can't use a template vairable outside of a `syntax'.) 18:51 eli: So my pattern is (_ name expr) -- which matches any parenthesized expression with three parts. (And the first is `_' so I don't care what it is.) 18:52 eli: Then, (syntax name) is just the name that was used -- it's basically just an identifier. #' is shorthand for `syntax', so #'name is the same. 18:53 eli: Now, the racket macro system uses values that are more than plain s-expressions -- it has a bunch of other things, like the location, and the important bit is the lexical context information -- some representation of the scope for various syntax bits. 18:54 eli: This is very much unlike CL, where "identifier" is exactly the same as "symbol". 18:54 eli: In my macro's case, #'name is the identifier -- which means that it's the symbol that was used plus all that extra information. 18:55 eli: (syntax-e #'name) pulls out the contents of that identifer, which in the case of an identifier is a symbol. 18:55 eli: Then, I use `format' to make up the new name, and `string->symbol' to turn the result to a symbol. 18:56 eli: Now I need to turn that back into an identifier -- and that's, of course, is the important bit where the extra information comes into the game. 18:56 eli: In CL, you'd just use the symbol, and let the context determines the lexical context -- broken or not. 18:57 eli: But in Racket, you do this by copying the lexical context from someplace else. 18:57 eli: In this case, I'm using #'name -- the original identifier -- to provide the lexical context for the newly constructed name. 18:57 eli: So I'm getting the new name with the same context as the given one. 18:58 eli: Finally, this whole thing is inside a (with-syntax ([maker ]) ...) 18:58 eli: and `with-syntax' will bind `maker' as a pattern variable, so it can also be used inside `syntax'. 18:59 eli: Finally, I return #'(define (maker) expr) -- where the `maker' part is that new identifier, and `expr' is coming from the input pattern. 18:59 eli: (If this was my class, I'd pause and ask for questions...) 19:00 eli: (And at this point I'd assume that everyone got bored and died.) 19:08 Lajla: eli, I'm reading 19:08 Lajla: I'm fascinated 19:08 Lajla: even though I already knew it 19:08 Lajla: but you managed to explain it in ways that I did not yet know it. 19:09 Lajla: The point is though I think that Demosthenex tried to get it with syntax-rules. 19:10 (join) lucian_ 19:11 (quit) lucian: Disconnected by services 19:11 (nick) lucian_ -> lucian 19:17 offby1: best explanation I've read so far 19:17 Lajla: I have no idea how syntax-case works though 19:17 Lajla: I write syntax case the way I write Dutch 19:17 Lajla: It just happens to work and the compiler understands it 19:18 Lajla: But I have no idea what I'm doing. 19:19 Lajla: offby1, if you were icecream 19:20 Lajla: how would you run the USA if elected praesident? 19:22 offby1: I guess I'd make sprinkles compulsory 19:23 Lajla: I was hoping for less power to copyright actually. 19:23 Lajla: And no more capital punishment 19:23 offby1: If I were icecream, I doubt I'd care about those things. 19:23 offby1: I'd be very concerned, however, about cones and toppings 19:25 Lajla: You are a very evil woman 19:26 offby1: I'm so evil, I've convinced everyone I'm a man 19:28 Lajla: Yes, but I didn't buy it. 19:29 Lajla: On IRC, everyone is female until proven otherwise, I always say 19:29 eli: re `syntax-rules' -- it's impossible to do that name munging with just `syntax-rules'. 19:30 Lajla: I had that idea. 19:30 eli: re `syntax-case' -- it's not too mysterious, think about it as just a pattern matcher. 19:30 Lajla: Syntax rules is kind of the least expressive lisp macro I ever saw, but one of the most hygienic. 19:31 eli: Yeah, it's pretty limited, even more for macros that you want to make public. 19:32 lucian: scheme still has defmacro, right? 19:33 (quit) b-man_: Remote host closed the connection 19:33 lucian thinks scheme got macros right 19:33 Lajla: lucian, I think defmacro or define-macro et cetera is implementation dependent, I'm not sure it was ever in any RNRS 19:33 lucian: Lajla: i see 19:34 lucian: Lajla: then my impression of scheme's macros is slightly less good :) 19:34 Lajla: Or maybe I am. 19:34 Lajla: Who knows 19:34 Lajla: syntax-case is obviouly the best lisp macro system ever 19:35 lucian: i still think walking lists is a good thing to have available for a macro system 19:35 lucian: but yes, i get how syntax-case is usually much superior 19:35 lucian is obviously a lisp beginner 19:35 Lajla: Nah, we're all pro. 19:35 (join) simon__ 19:36 eli: lucian: `defmacro' or `define-macro' was never standard in any way, though many schemes had it for a while. 19:37 eli: In racket, it's available as a library (`mzlib/defmacro'), but once you internalize how the hygienic macro system works, you'll probably get to the same place that many others did -- and consider defmacro to be a horrible hack. 19:37 eli: And re walking lists -- it's perfectly possible to do that with `syntax-case', and it's often used for that. 19:38 lucian: eli: oh, i see 19:38 lucian: then i have no love for defmacro left 19:38 eli: There's nothing that says that macros are all supposed to look like (define-syntax (foo stx) (syntax-case stx () ...rules...)) 19:38 Lajla: How old is syntax-case anyway 19:38 Lajla: And who had this excellent idea. 19:39 eli: It might actually be instructive to use defmacro after you know how the macro system works -- so you can really get how its broken. 19:39 Lajla: defmacro is just the common lisp system right? 19:39 lucian: eli: i understand how shadowing works (or doesn't) and how horrible expanded macros look with gensym 19:40 eli: Lajla: Yes. 19:40 eli: lucian: It's a bit more than that -- 19:40 lucian: eli: yes, i know. i don't fully understand all the details, though 19:40 lucian wishes he had more time 19:40 eli: basically, because `defmacro' works without a lexical context, and because racket does have it in its syntax representation, things get hairy. 19:41 eli: Basically what happens is: (a) it takes in the input syntax, 19:41 eli: (b) runs your sexpr-based transformation macro on it, 19:41 eli: (c) converts the result back into a syntax object. 19:41 eli: The thing is that you can't really do (c) in a reliable way. 19:41 eli: So what it does, instead, is construct a hash table at (a) from the input syntax, 19:42 eli: then, at (c), it uses the hash table to guess the contexts. 19:42 Lajla: eli, like, say I wanted a macro system which more or less looked like this (define-transform (name x y z) (hygienic : (if | +)) (if x (+ y z)))) for instance 19:42 Lajla: Are there any pitfalls to that. 19:42 Lajla: the (if | +) just marks which symbols should be considered hygienic 19:42 lucian: eli: that's really horrible 19:42 Lajla: For the rest it's just a lambda 19:43 lucian: i'm a bit torn towards lisps 19:43 lucian: especially scheme is beautiful and clean 19:43 lucian: and homoiconicity is awesome 19:44 lucian: but i don't like how uniform the syntax is 19:44 Lajla: lucian, well, hat's because it ś homo-iconic. 19:44 lucian: Lajla: i don't think it has to be a requirement 19:44 eli: Lajla: Not really, but that could be close to explicit renaming or one of those things. Perhaps a simple defmacro+automatic gensyms thing. 19:44 lucian: Lajla: look at clojure, it has something similar to that 19:44 Lajla: eli, well, it also works in reverse, like, shadowing doesn't break it. 19:45 Lajla: If you put it inside (let ((if ...)) ...) 19:45 eli: lucian: Yeah, it's horrible, but this is essentially what CL is doing, by design. 19:45 lucian: although you still have to use gensym sometimes in clojure 19:45 Lajla: lucian, ahh, like that. 19:45 Lajla: lucian, how do you like this (let (x : 3, y : 4) (+ x y)) 19:45 eli: Lajla: the clojure thing that lucian refers to is, IIRC, defmacro+auto-gensym. 19:45 Lajla: (x : 3, y : 4) is syntax for a hashtable like thing basically. 19:45 lucian: Lajla: i like extra syntax 19:45 lucian: eli: and yeah, that's what i was refering to 19:46 Lajla: Ah, I thought the (let [ ... ] ...) syntax. 19:46 Lajla: Where it uses a vector there to make it more clear. 19:46 lucian: the let syntax is nice too, yes 19:46 lucian: i also like (fn bla [a b] ...) 19:46 Lajla: Basically I though hashtables for a binding spec were cool because unless you dive into named-lets, the order is irrelevant if you have a purely functional language. 19:46 Lajla: And it also makes the syntax a bit more clear. 19:46 lucian: i think a lisp with very good and expressive data structure literals could have more readable syntax 19:47 eli has a very negative opinion of clojure 19:47 Lajla: lucian, that's sort of what I'm working on here. 19:48 Lajla sort of shares eli's opinion. 19:48 lucian: eli: could you expand on that? 19:48 eli: I get the whole better datastructures thing -- that's good. 19:48 eli: Also the emphasis on things being iterable, and easy laziness. 19:48 lucian: eli: and i'm assuming persistent data structures by default? 19:49 Lajla: lucian, some other things I like to implement are basically type requirements. Like if you do (func (n : Naturals) (k : Integers)) it reports an error if n and k are not of that type when applied, a macro all of course. 19:49 eli: But it was very disappointing to see a new lisp dialect that goes with some of CL's glaring problems. 19:49 lucian: Lajla: meh, i don't particularly care about types :) 19:49 lucian: eli: the macro system you mean? 19:49 eli: Like having symbolic macros -- IMO that's a serious design bug. 19:49 eli: Also, it has special variables, which is just puke-able. 19:50 lucian: eli: vars ? 19:50 eli: It's like a tribute to a 50-year-old bug. 19:50 eli: Ugh. 19:50 eli: Caroles attacking outside. 19:51 Lajla: eli, well, they do serve a purpose in clojure though. 19:51 Lajla: I do like how nil is not the empty list. 19:51 lucian: Lajla: yes, they make sense in the context of concurrency 19:51 Lajla: I'd like scheme to have a nil from time to time though. 19:51 lucian: but i'm sure you could do better 19:51 lucian: Lajla: +1 19:51 Lajla: A boolean false and a 'no meaningful value here' are two different things I guess. 19:52 lucian: Lajla: i guess you could define #n to mean that 19:52 Lajla: You'd have to redefine if though. 19:52 Lajla: You want it to test false 19:53 eli: What purpose is it exactly that special variables serve? 19:53 Lajla: eli, well, they're not 'special', they are 'variable' 19:53 Lajla: They are set!-able. 19:53 Lajla: The only way to rebind. 19:54 eli: I didn't use the language enough to know for sure, but what I've seen cetainly looks like special variables. 19:54 lucian: eli: they're used for solving contention in the context of concurrency 19:54 eli: And these things certainly do have a use in a modern language that deal with concurrency. 19:55 Lajla: eli, well, they are dynamic, yes. 19:55 lucian: you have a var accessed by multiple threads, protected by STM 19:55 Lajla: But there are no 'non special' variables. 19:55 eli: But it is a huge mistake to make them accessible like plain variables. 19:55 lucian: eli: they're immutable, so i think that's why 19:56 eli: In racket we have (let ([x 123]) ...) and (parameterize ([x 123]) ...) -- and they are *very* different. 19:56 eli: In CL you get just `let', and sometimes it does the special variable thing, sometimes it doesn't. 19:56 eli: And my understanding is that clojure does just that. 19:56 lucian: eli: clojure is like racket here 19:56 lucian: let is very different from let 19:57 lucian: * from var 19:57 eli: So you can't rebind them with `let'? 19:57 lucian: eli: not afaik 19:57 eli: So how do you change their value? 19:57 Lajla: with set! 20:00 eli: Oh yes, there's also the bad mistake of dumping tail calls. 20:00 Lajla: He did give it some serious thought. 20:00 Lajla: some would argue the primary mistake was the JVM. 20:00 Lajla: But that was his goal from the start 20:01 Lajla: a lisp on the jvm. 20:01 lucian: eli: implementing tail calls would cost clojure the easy java interop and performance 20:01 lucian: the jdk 7 does implement tail calls, so it's not a big deal 20:01 eli: Tails calls are possible on the jvm. Takes more work, but possible. 20:01 Lajla: lucian, what is the jdk 7? 20:02 Lajla: eli, yeah, but you lose performance apparently. 20:02 lucian: Lajla: openjdk 7 20:02 lucian: Lajla: that's not the main issue. you can no longer have clojure fns == java callables 20:02 Lajla: lucian, a java bytcode interpeter/compiler? 20:02 lucian: Lajla: the open source JVM from sun 20:02 Lajla: So they have two 20:02 Lajla: one closed source 20:02 Lajla: and one open? 20:02 lucian: Lajla: no 20:03 lucian: java se is open 20:03 lucian: it's called openjdk 20:03 lucian: java ee is java se + closed crap 20:03 lucian: eli: i personally like recur 20:04 Lajla: lucian, like as in, like more than TCO? 20:04 lucian: you don't get mutually recursive, but otherwise it's nice and explicit 20:04 Lajla: I do like that form though. 20:04 lucian: Lajla: in some ways, yes, more than TCO 20:04 eli: lucian: `recur' is just a named-let, no? 20:04 Lajla: Like, the named-let idea. 20:04 Lajla: (let recur ....) 20:04 Lajla: 99% of the time the name can be recur anyway. 20:04 lucian: eli: sort of, i think 20:04 Lajla: Well, recur is a special form 20:04 Lajla: not a general procedure. 20:05 Lajla: It can't just exit the let. 20:05 lucian: eli: basically replace the name of the recursive function with recur when you call it 20:05 lucian: i like that it's clear when a call is tail 20:05 (quit) simon__: Quit: Lost terminal 20:06 lucian: you don't have to think whether your function will use o(n) space. if recur is there, you know it's o(1) 20:06 eli will brb 20:07 Lajla praefers not to think bout that. 20:07 Lajla: I found that worrying whether a function is tail recursive or not can often wreck the readability of code. 20:08 lucian: Lajla: for me, that's another reason why i like recur 20:09 lucian: eli: as i understand it, recur is a controlled goto, with the option to rebind names 20:31 (join) mwolfe 20:39 Demosthenex: eli: i really appreciate the feedback! i've had a hard time finding a tutorial that made sense... and people say defmacro is hard. ;] 20:43 Lajla: syntax case is about as hard as a catholic priest's private parts in a kindergarten. 20:44 Lajla: It is the epitome of dare and baler 20:58 (quit) lucian: Read error: Connection reset by peer 21:01 (part) chandler: "*sigh*" 21:15 Lajla: eli, what advantages does syntax case have above that simple system. 21:15 Lajla: ? 21:20 (quit) mwolfe: Remote host closed the connection 22:49 (join) jonrafkind 23:10 Demosthenex: Lajla: wow.... great analogy 23:11 Demosthenex: thing is, it maybe simpler to understand than the documentation implies... but omg, i read the CL stuff and got defmacro pretty quick, it made sense. but the syntax stuff... 23:14 Lajla: Demosthenex, well, syntax-case is a lot more complicated because it's more expressive I guess. 23:21 Demosthenex: Lajla: defmacro uses basic lisp to basically generate code in s-exps 23:23 Lajla: Demosthenex, actually, you can also use whatever stuff you defined with define-syntax on lists dynamically. 23:23 jonrafkind: scheme isn't too different, you just need to know what hygiene is doing 23:23 Lajla: But the thing is, lists != syntax. 23:23 Demosthenex: the only thing unusual about defmacro was the quoting, you have to use quoting to say which parts to interpret, and which were static 23:24 Lajla: list <= syntax 23:24 Lajla: syntax contains more info. 23:24 Lajla: Demosthenex, well, the idea is that defmacro can easily break. 23:24 Demosthenex: sure, i don't dispute that. but that documentation chafes ;] 23:25 jonrafkind: you know ive never seen a real example of defmacro thats broken in a way that actually matters 23:25 Lajla clicks on the wheel 37823 time and gives jonrafkind a program 23:25 jonrafkind: ive just heard references to "without hygiene life will be painful" 23:25 Lajla: jonrafkind, all this practical stuff. 23:25 Lajla: Theory is what counts. 23:25 jonrafkind: yea right 23:25 Lajla: And dare you not ever forget again. 23:25 jonrafkind: how are the unicorns in your magical world? 23:25 jonrafkind: please name one after me 23:26 Demosthenex: wow ;] 23:28 jonrafkind: maybe i should write a bunch of defmacro macros and see what happens 23:29 eli: Demosthenex: In your opinion, is `defmacro' better than CPP? 23:36 Demosthenex: cpp? c++? 23:36 askhader: That's what I was thinking :p 23:36 Lajla: jonrafkind, it has come to my observation that you don't take me seriously. 23:37 Demosthenex: i'm sure i can get used to this syntax thing... 23:37 Demosthenex: i just said it seems ill-explained 23:38 Demosthenex: if its the only really hard thing to pickuo for scheme proficiency, great. 23:39 jonrafkind: eli, do you know a real example where lack of hygiene is death? 23:39 Lajla: England, ahahahahahhahahaa 23:40 Lajla: I'm so witty, I almost feel like jonrafkind when I spurt nonsense at him 23:40 Demosthenex: the example i saw was one of where you used names that accidentally collided with ones outside the macro, scheme protects against it, defmacro doesn't 23:40 Lajla: That is basically the idea. 23:40 Lajla: Like 23:40 jonrafkind: so forgetting to use (gensym) ? 23:40 Demosthenex: so in CL/defmacro you'd have to KNOW to use gensym 23:40 Lajla: what you want is that the macro doesn't break if you use define to rebind some stuff. 23:40 Demosthenex: where syntax does that automatically 23:40 Lajla: Well, it also works the other way around 23:41 eli: Demosthenex: the C preprocessor 23:41 Demosthenex: eli: gah, i haven't done C in ages. ;] 23:41 Lajla: Like, say the macro depends on some function 23:41 eli: OK, how about M4? 23:41 Lajla: which the user is not aware of. 23:41 Lajla: And that function is alled jonrafkind 23:41 Lajla: And you feel like, hey let's define a function called jonrafkind 23:41 Lajla: then you break the macro. 23:41 eli: jonrafkind: Do you mean the way that unhygienic macros break where you can't resolve it using a gensym? 23:41 Demosthenex: omg, m4. the quoting horror 23:42 Lajla: (define (jonrafkind) (display "I sold my soul to infix")) 23:42 jonrafkind: yes 23:42 jonrafkind: how many of those macros actually exist 23:42 eli: Demosthenex: OK, so how is `defmacro' better? 23:43 Demosthenex: eli: hey, i get that quoting is an issue 23:43 eli: jonrafkind: See my language tutorial thing -- I have a section about that. 23:43 Demosthenex: and really, syntax may be better 23:43 Demosthenex: all i said was it was hard to get started 23:43 jonrafkind: oh ok, i read your tutorial a while ago 23:43 eli: jonrafkind: Basically, it's a *huge* problem if you care about making up new languages. 23:43 eli: Demosthenex: No, it's more than just the syntax. 23:43 eli: Demosthenex: Let me answer this for you: 23:44 eli: The main benefit that `defmacro' gives you over something like M4 is that you're dealing with structured data -- not just flat strings. 23:44 eli: Does that sound right to you? 23:45 Lajla: Can I answer 'yes' for Demosthenex, I want to see you continue 23:45 Demosthenex: sure 23:45 Demosthenex: and unbalanced quotes give me nightmares ;] 23:46 eli: OK, so in that sense `defmacro' is a serious step up -- from a flat, unstructured representation for code you go to a tree representation. 23:46 eli: This makes it a much more powerful macro system in that playing with code is far easier. 23:47 eli: (Actually, CPP has moved from being completely unstructure to something more well behaved -- for example, it used to be valid to have "foo as a macro in CPP.) 23:47 eli: In any case, a hygienic `define-syntax' is another step up -- 23:48 eli: in `defmacro' you're dealing with sexprs -- which is very powerful, 23:48 eli: but you get *just* that -- you don't have any more information. 23:48 eli: In racket, you're dealing with syntax objects that have the sexprs in addition to a bunch of things (like source location) *and* the lexical information. 23:49 eli: So it's a more powerful system simply because it represents more of your code. 23:49 eli: (In the same way that sexprs represent more code than flat strings.) 23:49 eli: Obviously, it's easy to "downgrade", 23:49 eli: for example, you can have a defmacro that will call some string munging function, then use `read' on the result to parse it back to a resulting sexpr. 23:50 eli: In the same way, it's possible to take in some syntax object in a racket macro, strip away the extra information, run a plain sexpr function, then slap the extra information back -- which is what `mzlib/defmacro' is doing. 23:50 eli: But climbing *up* the tree is very difficult. 23:51 eli: If you want to climb up from an M4 macro system to defmacro you need to re-do parsing of sexprs. 23:51 eli: If you want to climb up from a defmacro system to a racket-like `define-syntax', you need to implement all that extra functionality. 23:51 Lajla is truly fascinated. 23:51 Lajla: I don't know why I like to read stuff I already know, it makes me all warm inside. 23:52 eli: Now, one of the main source of power in a macro system is the fact that it's a system of *local* transformations. 23:52 eli: And climbing up from a string-based macro system to a sexp based one is still possible to do locally. 23:53 eli: But you can't do that with a `defmacro' system -- you need to know about the surrounding context, which is why racket's macro system is strictly stronger than a defmacro system. 23:53 Demosthenex: cool 23:53 Demosthenex: again, i'm happy to concede its more powerful. and i'd compare it from my history to something like m4 or shell substitution vs soething like perl's Template::Toolkit 23:53 Lajla: But it's ill documented 23:54 Lajla: Demosthenex, to be honest, there is a 'syntax-case primer' around 23:54 Demosthenex: hey, wait. why'd everyone run screaming? where'd everybody go? 23:54 Lajla: but I found it to be more cryptic than R6RS 23:54 Lajla: Demosthenex, netsplit? 23:54 Demosthenex: yeah, cryptic. after i got used to reading the CL hyperref ;] 23:54 Demosthenex: no, i mentioned perl in a lisp channel. i'm waiting for lightning. 23:54 Demosthenex: ;] 23:55 Demosthenex: l 23:55 Lajla: Demosthenex, http://www.cs.indiana.edu/~dyb/pubs/tr356.pdf 23:55 eli: Demosthenex: There is a flip side too -- racket's syntax objects are not as easy to deal with as sexprs, 23:55 Lajla: This is apparently 'probably the best introduction' 23:55 eli: and that's for obvious reasons -- there's just more stuff there. 23:55 eli: For example, in CL you make up a new symbol and you're done. 23:56 eli: In racket, you make up the symbol, then you copy the lexical context from some other piece of syntax, which means that you have a choice that you never had in the defmacro system. 23:56 Demosthenex: sure 23:56 Demosthenex: Lajla: i saw that earlier, added it to my collection of referene material 23:56 eli: And then you have more stuff -- you can copy the source location from a different piece (or just make one up), and then there's syntax properties etc etc. 23:56 eli: And dealing with all of that means a macro system with more knobs and gadgets. 23:57 Lajla: Demosthenex, trying to read it may turn your brain into apple crumble pie in the process, it may not keep thinking as well, but it makes a great projectile to launch into the face of republicans. 23:57 eli: And as ryan's recent work on `syntax-parse' shows (as well as other recent work), there's still stuff to do. 23:57 Demosthenex: right now i just needed a way to reduce the amount of code, and protect against poisoning positional parameters because snooze doesn't take keyed based inputs on a constructor. 23:57 Demosthenex: Lajla: wow, you're full of it tonight. ;] 23:58 Demosthenex: seriously though, if i asked a question like this in #lisp, i'd get chewed on for an hour, and they might drop a useful tidbit somewhere. 23:58 Demosthenex: i like the scheme community alot more ;] 23:58 Lajla: Demosthenex, full of what? 23:58 Demosthenex: i appreciate the insight. 23:58 eli: Demosthenex: Ha! You should try comp.lang.lisp -- it's even more amusing. 23:58 Demosthenex: Lajla: i'll keep a printed copy so i can stay safe from republicans. 23:59 Demosthenex: eli: oh no, i know better. ;] 23:59 Demosthenex: i'll just lurk there 23:59 eli: :) 23:59 Lajla: THe problem I found with #lisp i that they got insanely angry with me once I called them all a bunch of archaic people who work in a language that has been the product of botching stuff over each other for 50 years alreay.