Re: Shorter lambda expressions
One related thing I sometimes lack is: =20 (define-syntax-rule (thunk exp ...) (lambda () exp ...)) =20 (Found in Racket, notably.) IMO, it's much more useful to have `λ', together with an Emacs hack that makes it easy to type. In the last few years I even switched to omitting the space in some simple cases, so I use (λ() (blah) (blah) (blah)) which is even shorter than `thunk'. Also, there's no confusion between `thunk' and `thunk*' (accepts any number of arguments) which some people prefer. (Not on the list; feel free to forward...) -- ((lambda (x) (x x)) (lambda (x) (x x))) Eli Barzilay: http://barzilay.org/ Maze is Life!
Re: [racket-dev] Enhancement to the syntax system?
20 minutes ago, Marijn wrote: It seems to me that both these results cannot be correct simultaneously, but I'll await the experts' opinion on that. This does look weird: #lang racket (define-for-syntax (f stx) #`(let ([x 1]) #,stx)) (define-syntax (m stx) (with-syntax ([zz (f #'x)]) #`(let ([x 2]) zz))) (m) evaluates to 1, but if I change the first two stx names into x *or* if I change the argument name for the macro to x, then it returns 2. -- ((lambda (x) (x x)) (lambda (x) (x x))) Eli Barzilay: http://barzilay.org/ Maze is Life!
Re: [racket-dev] Enhancement to the syntax system?
An hour and a half ago, Matthew Flatt wrote: It's natural --- but not correct --- to think that #` is responsible for hygiene, in which case `(f #'x)' should keep the given `x' separate from the `let'-bound `x' in the result. Instead, hygiene is the responsibility of macro invocation, and #`(let ([x 1]) #,#'x) is simply the same as #`(let ([x 1]) x) and so (f #'x) above is equivalent to #`(let ([x 1]) x) If you change the example to #lang racket (begin-for-syntax (define-syntax-rule (f body) #`(let ([x 1]) body))) (define-syntax (m stx) (with-syntax ([zz (f x)]) #`(let ([x 2]) zz))) (m) so that `f' is used as a macro instead of a function, then you get 2, since the macro-expansion of `(f x)' keeps the `x's separate. Yeah, I think that this kind of confusion is there, but it's easy (at least relatively easy) to build a mental model of how things work and avoid such problems -- but the tricky bit here is that things break when the `stx' is renamed to `x'. 50 minutes ago, Ryan Culpepper wrote: The difference between (define-for-syntax (f1 stx) #`(let ([x 1]) #,stx) and (define-for-syntax (f2 x) #`(let ([x 1]) #,x) is that the 'x' in the template in the 'f2' is not bound-identifier=? to the 'x' that appears in the template of 'm', because it has a rename wrap due to the 'x' formal parameter of 'f2'. That is, 'f2' behaves essentially the same as (define-for-syntax (f2* x*) #`(let ([x* 1]) #,x*) Yeah, I think that this is the more confusing bit. (I suspected something along this line, but didn't have time to figure out a good explanation...) So I think that the real confusion is actually a combination of what Matthew pointed at in the above and this one, making the result trickier than both. In other words, I *think* that the effect of the transformer's argument name makes it looks like the #` *was* responsible for hygiene when it's actually just this point that makes it happen... (This is all IIUC.) A likely mistake is to think that the wrap generated by the 'x' in 'f2' doesn't count because it happens before we get around to the real macro expansion that you care about. But that's not the case (at least in Racket). A good rule of thumb is to never use local variable names in your macro implementation (including compile-time auxiliary functions) that also appear in the macro's template (including etc). Yeah, and a subtle lesson here is that `stx' is a useful convention. (I think that `x' is common in some guile code, so this would be a point for them.) A related error is the identifier used out of context error that you get from, eg, (define-syntax (m stx) (let ([+ *]) #'(+ 1 2))) (m) ;; = identifier used out of context in: + The binding of '+' in the macro changes the meaning of the '+' in the template, even though the bindings exist at different phases. You could perhaps avoid this issue by changing the hygiene algorithm by adding a phase level to rename wraps and skipping different-phase rename wraps during resolution. I'm not sure if this is a good idea or if anyone has tried it. (And this is what Matthew's last example gets by changing `f' to a macro, right? Also, Stefan posted a related message to the scheme-reports list where he imlpemented some new #. thing which is (roughly speaking) something that expands to a `let-syntax' and therefore tries to do the same.) In any case, it would be nice if the original example I posted (which is a variant of what was discussed originally) would throw an error instead of looking right in a way that is wrong... -- ((lambda (x) (x x)) (lambda (x) (x x))) Eli Barzilay: http://barzilay.org/ Maze is Life!
Re: *current-language*
An hour and a half ago, e...@barzilay.org wrote: On Tue 06 Dec 2011 01:36, Noah Lavine noah.b.lav...@gmail.com writes: And about the directives, what should they be? ',language' is what we used to use at the REPL, and I was about to write an email arguing for that, until I realized that there is one big advantage to using the same thing as Racket - we might actually share some languages. ,language would be pretty cute, but I don't think it would work, as it reads as (unquote language), and who knows what the binding of `unquote' would be. FWIW, that's true -- and a reason that I plan to change what xrepl (our command-line thing which I added to Racket recently) so that it intercepts any line that starts with a , which means that it would work no matter what the actual language reader does with that. -- ((lambda (x) (x x)) (lambda (x) (x x))) Eli Barzilay: http://barzilay.org/ Maze is Life!
News gmane.lisp.guile.devel: Re: syntax-local-value [racket]
6 hours ago, Andy Wingo wrote: syntax-local-value e.g. http://docs.racket-lang.org/reference/stxtrans.html#%28def._%28%28quote._~23~25kernel%29._syntax-local-value%29%29 We don't have this. It wouldn't be too hard to implement though; want to give it a try? What is it used for, though? It is used to get the value of a macro-level binding. Usually that's not very useful since you'd prefer to just use the macro (by producing code that has it). You could probably implement your own macro expander which would use this to get the transformer functions and call them directly but that's not a good use case either. But there are cases where you want to keep around syntax-level information to be used *by* macros rather than being a user macro directly. Probably the most obvious example of that is struct definition: when you define a struct, racket puts information about the struct on its name, so it can be used by declarations of structs that inherit from it: - (struct foo (x y z)) - foo #procedure:foo - (begin-for-syntax (printf ~s\n (syntax-local-value #'foo))) #procedure:self-ctor-checked-struct-info - (require (for-syntax racket/struct-info)) - (begin-for-syntax (printf ~s\n (extract-struct-info (syntax-local-value #'foo (#syntax:1:8 struct:foo #syntax:1:8 foo #syntax:1:8 foo? (#syntax:1:8 foo-z #syntax:1:8 foo-y #syntax:1:8 foo-x) (#f #f #f) #t) (IIRC, the reason for the checked is to avoid faking these things, which is needed for enforcing typed racket's assumptions.) There are lots of such examples where you want to keep syntax information around. Related to this, we have `syntax-parameter-value' which is even more exotic. It is actually something that I didn't know about until I worked on the syntax parameters paper, and all of the (very few) uses of it that we have are using syntax paremeters as values (as above) that obeys lexical scope. But there was one reviewer that noted that a possible problem with syntax parameters is that a macro that uses one essentially gets the parameter macro to be part of its public interface, which can leak out to other macros that use it. An example from the paper is when you have a `ten-times' macro: (define-syntax ten-times (syntax-rules () [(_ body ...) (let loop ([n 10]) (when ( n 0) body ... (loop (- n 1])) and user code that uses it: (forever (ten-times (display hey\n) (abort))) Now the macro author decides that it's better to implement `ten-times' via `forever', perhaps because that's the preferred primitive way to loop: ;; (forever expr ...) is defined as a macro that loops forever, uses ;; an `abort' syntax parameter to make it possible to exit the loop (define-syntax ten-times (syntax-rules () [(_ body ...) (let ([n 10]) (forever body ... (set! n (- n 1)) (when (= n 0) (abort])) and now the above user code fails -- because the `abort' is shadowed by `ten-times' which means that it aborts the wrong loop. Obviously, this is a problem -- and perhaps a little less obvious is that it's actually the *desired* behavior since the intention was that `abort' is usable in `forever' forms including macros that use it. This is all -- still -- in complete analogy with parameters, where you can run into the same situation with a function that shadows something like `current-output-port' and now functions that are called see the shadowed value rather than the original one. (define (foo some-function) (parameterize ([current-output-port ...something...]) (printf something) (some-function))) In some cases like the above you can just move the call to outside the `parameterize', but in other cases that's not possible (with nested functions etc). In these cases, the solution in the parameter case is to save the original value and restore it around calls to other functions: (define (foo some-function) (define orig-stdout (current-output-port)) (parameterize ([current-output-port ...something...]) (printf something) (parameterize ([current-output-port orig-stdout]) (some-function When I thought about this, I was pleasantly surprised that `syntax-parameter-value' could be used in exactly the same way. -- ((lambda (x) (x x)) (lambda (x) (x x))) Eli Barzilay: http://barzilay.org/ Maze is Life!
Re: *current-language*
20 minutes ago, Andy Wingo wrote: Guile's REPL does do that, yes. I think that Noah's proposal was to pun the ,language command so that in a file, instead of #!lang r5rs (eval '(+ 1 2) (scheme-report-environment 5)) you could have ,language r5rs (eval '(+ 1 2) (scheme-report-environment 5)) Cute. I guess it would work if we changed the reader, for the same reason that it works at the REPL. Ah, in that case, the obvious thing to note is that the part of our reader that deals with reading the language is not using the sexpr reader. For example: #lang |racket| doesn't work. The only small hack is that the default reader is the one that's used to read the file, and it changes when it runs into a `#lang'. Because of this things like ;; some comment #lang racket ... still work. -- ((lambda (x) (x x)) (lambda (x) (x x))) Eli Barzilay: http://barzilay.org/ Maze is Life!
Re: Syntax Parameters documentation for guile
8 hours ago, Andy Wingo wrote: On Wed 04 Jan 2012 01:33, Eli Barzilay e...@barzilay.org writes: (Ugh, medieval programming...) Goes along with the guild stuff, I guess :) (That was a scribble hint...) -- ((lambda (x) (x x)) (lambda (x) (x x))) Eli Barzilay: http://barzilay.org/ Maze is Life!
Re: Syntax Parameters documentation for guile
An hour and a half ago, Ian Price wrote: Eli Barzilay e...@barzilay.org writes: the macro is used. Examples include an 'if' form that binds the result of the test to an 'it' binding, or class macros that introduce a special 'self' binding. The `abort' example is also popular, probably even more than `it'. I think that there are practical uses of that (eg, a function with a `return' keyword), whereas anaphoric conditionals are more of an academic exercise that I don't think gets used in practice (at least in Schemes). I mentioned it mostly because it is a traditional example, but I've swapped it for the lambda with return. I'm not sure how popular aif is in general (I prefer a clojure style if-let), but I do know it is in the popular miscmacros egg for chicken. (I suspect that its popularity comes from these examples...) ** define-syntax-parameter keyword transformer [syntax] Binds keyword to the value obtained by evaluating transformer as a syntax-parameter. The keyword is bound to the value of the `transformer' expression. (Evaluated at the syntax level, in Racket's case, I don't know if Guile has separate phases yet...) It's not evaluated as a syntax parameter, just like parameters. This is a case of syntactic ambiguity in English, I meant it as Binds keyword to (the value obtained by evaluating transformer) as a syntax-parameter. Yeah, I figured that. It's generally pretty hard to describe such things accurately because of natural language conventions. I run into such problems in my course very frequently. I've just dropped the as a syntax-parameter part. That works fine. In case anyone else has any comments, the modified version is included below. Now I'm off to learn about texinfo :) (Ugh, medieval programming...) -- ((lambda (x) (x x)) (lambda (x) (x x))) Eli Barzilay: http://barzilay.org/ Maze is Life!
Re: add regexp-split: a summary and new proposal
An hour ago, Daniel Hartwig wrote: Anyway, what do people think of this proposal which tries to address that whole discussion: * [Vanilla `string-split' expanded to support the CHAR_PRED semantics of `string-index' et al.] * New function `string-explode' similar to `string-split' but returns the deliminators in it's result. * Regex module replaces both of these with regexp-enhanced versions. Aha -- I was looking for a new name, and `-explode' sounds good and not misleading like `-split' (misleading in that I wouldn't have expected a split function to return stuff from the gaps). But there's one more point that bugs me about the python thing: the resulting list has both the matches and the non-matching gaps, and knowing which is which is tricky. For example, if you do this (I'll use our syntax here, so note the minor differences): (define (foo rx) (regexp-split rx some string)) then you can't tell which is which in its output without knowing how many grouping parens are in the input regexp. It therefore makes sense to me to have this instead: (regexp-explode #rx([^0-9]) 123+456*/) '(123 (+) 456 (*) (/) ) and now it's easy to know which is which. This is of course a simple example with a single group so it doesn't look like much help, but when with more than one group things can get confusing otherwise: for example, in python you can get `None's in the result: re.split('([^0-9](4)?)', '123+456*/') ['123', '+4', '4', '56', '*', None, '', '/', None, ''] but with the above, this becomes: (regexp-explode #rx([^0-9](4)?) 123+456*/) '(123 (+4 4) 456 (* #f) (/ #f) ) so you can rely on the odd-numbered elements to be strings. This is probably going to be different for you, since you allow string predicates instead of regexps. Finally, the Racket implementation will probably be a little different still -- our `regexp-match' returns a list with the matched substring first, and then the matches for the capturing groups. Following this, a more uniform behavior for a `regexp-explode' would be to return these lists, so we'd actually get: (regexp-explode #rx[^0-9] 123+456*/) '(123 (+) 456 (*) (/) ) (regexp-explode #rx([^0-9]) 123+456*/) '(123 (+ +) 456 (* *) (/ /) ) And again, this looks silly in this simple example, but would be more useful in more complex ones. We would also have a similar `regexp-explode-positions' function that returns position pairs for cases where you don't want to allocate all substrings. One last not-too-related note: this is IMO all a by-product of a bad choice of common regexp practices where capturing groups always refer to the last match only. In a world that would have made a better choice, I'd expect: (regexp-match #rx(foo+)+ bar blah foof bar) '(foof bar (foo f)) and, of course: (regexp-match #rx(fo(o)+)+ bar blah foof bar) '(foof bar ((foo (o)) (f (o o o But my guess is that many people wouldn't like that much... (Probably similar to disliking sexprs which are needed for the results of these things.) With such a thing, many of these additional constructs wouldn't be necessary -- for exampe, we have `regexp-match*' that returns all matches, and that wouldn't have been necessary. `regexp-split' would probably not have been necessary too. -- ((lambda (x) (x x)) (lambda (x) (x x))) Eli Barzilay: http://barzilay.org/ Maze is Life!
Re: Syntax Parameters documentation for guile
More than a week ago, Ian Price wrote: Eli, I'd especially appreciate it if you could clear up any misconceptions I may have, or may be unintentionally imparting on others. (And that I'm kind of on the list I can reply...) * Syntax Parameters Syntax parameters[fn:1] are a mechanism for rebinding a macro definition within the dynamic extent of a macro expansion. It provides a convenient solution to one of the most common types of unhygienic macro: those that introduce a special binding each time I'd explicitly say unhygienic here rather than special. the macro is used. Examples include an 'if' form that binds the result of the test to an 'it' binding, or class macros that introduce a special 'self' binding. The `abort' example is also popular, probably even more than `it'. I think that there are practical uses of that (eg, a function with a `return' keyword), whereas anaphoric conditionals are more of an academic exercise that I don't think gets used in practice (at least in Schemes). [As a sidenote, when I worked on that paper I've asked our local Perl guru about the problem of shadowing the implicit `it' in Perl -- he said that in practice it's considered bad style to use it in perl code, and referred me to some book that talks about the pitfalls of using it... I found it amusing that this perl-ism has become such a popular example for unhygienic macros where perl hackers actually try to avoid it.] With syntax parameters, instead of introducing the binding unhygienically each time, we instead create one binding for the keyword, which we can then adjust later when we want the keyword to have a different meaning. As no new bindings are introduced hygiene is preserved. This is similar to the dynamic binding mechanisms we have at run-time like parameters[fn:2] or fluids[fn:3]. An important note to add here is that there is no dynamic scope in the usual sense here -- it's rather a dynamic scope during macro expansion, and for macro-bound identifiers. The resulting expanded code is of course as lexical as always. (We've had some discussions at #scheme where this was a confusing point.) ** define-syntax-parameter keyword transformer [syntax] Binds keyword to the value obtained by evaluating transformer as a syntax-parameter. The keyword is bound to the value of the `transformer' expression. (Evaluated at the syntax level, in Racket's case, I don't know if Guile has separate phases yet...) It's not evaluated as a syntax parameter, just like parameters. The transformer provides the default expansion for the syntax parameter, and in the absence of syntax-parameterize, is functionally equivalent to define-syntax. A good note to add here is that it is usually bound to a transformer that throws a syntax error like `foo' must be used inside a `bar'. It immediately clarifies the use of syntax parameters in the common case. ** syntax-parameterize ((keyword transformer) ...) exp ... [syntax] (note, each keyword must be bound to a syntax-parameter Adjusts each of the keywords to use the value obtained by evaluating their respective transformer, in the expansion of the exp forms. It differs from let-syntax, in that the binding is not shadowed, but adjusted, and so uses of the keyword in the expansion of exp forms use the new transformers. A possibly useful analogy is with `fluid-let' which doesn't create new bindings, but rather `set!'s them. But IMO `fluid-let' should die, so using parameters is a better example... -- ((lambda (x) (x x)) (lambda (x) (x x))) Eli Barzilay: http://barzilay.org/ Maze is Life!
Re: [PATCH 2/5] [mingw]: Have compiled-file-name produce valid names.
[Second attempt, my Emacs has unfortunate issues with Ludovic's name...] An hour ago, Andy Wingo wrote: On Mon 02 May 2011 22:58, l...@gnu.org (Ludovic Courtès) writes: Andy Wingo wi...@pobox.com writes: Basically I think the plan should be to add scm_from_locale_path, scm_from_raw_path, etc to filesys.[ch], and change any pathname-accepting procedure in Guile to accept path objects, producing them from strings when given strings, and pass the bytevector representation to the raw o/s procedures like `open' et al. Seems to like a disjoint type “just for Windows” would be overkill, no? Maybe you're right; hummm! I have added a kind racketeer on Cc; perhaps if he has time, he might have some thoughts in this regard. :-) I don't think that I can contribute much -- I'm mostly looking at these things from a user's point of view... Roughly speaking (mostly because I don't know what the issues that you're up against), our path values have just paths for whatever the OS wants -- so on Windows they might have either backslashes or slashes (since Racket accepts both). To write portable code we don't have a `file-separator' thing, instead, we have `build-path' that combines two paths with the right separator. Similarly, we have `split-path' to split up a path to the directory part and the last part. I think that it's generally better this way, since it represents the higher level operation rather than fiddling with the semantics of where and how to put separators directly (but this is not some religious issue, just seems to me like it would be more convenient). Also, we have cases where we want something that looks like a portable path (for example, naming relative file names in `require') -- for those we use /-separated strings that are limited to safe characters. And related, in cases where we want to encode path in code (for example, some macro that wants to generate a path), we'll use strings or byte strings, with the latter more common for lower level things. (But I'm just rambling now, I haven't slept in N days -- so feel free to ignore me...) -- ((lambda (x) (x x)) (lambda (x) (x x))) Eli Barzilay: http://barzilay.org/ Maze is Life!