Re: [racket-users] Is there a way to check whether syntax is an expression or a define statement?

2017-06-29 Thread Matthew Flatt
At Thu, 29 Jun 2017 09:32:24 -0700 (PDT), Sam Waxman wrote:
> "The only way to check whether a form is an expression or definition is
> to partially expand it and match on the form." 
> - This seems sort of rough to believe. If you shadow the syntax-rule for 
> define so that (define id binding) always just returns the number 1, then (+ 
> (define a 1) 1) will work perfectly, so somehow racket knows that the first 
> define is not an expression, whereas the second is. If you partially expand 
> it 
> and look at it's form, doesn't that just tell you that it expands into 
> something called define? Can't you not figure out if that's racket's define 
> or 
> a user-defined, expression define?

By "partial expansion", I meant expansion of the immediate form to a
core form as in

http://docs.racket-lang.org/reference/syntax-model.html?q=partial%20expansion#%28tech._partial._expansion%29

and as implemented by `local-expand` with a non-empty stop list.

So, in your example, the expansion of `(define a 1)` won't stop there,
since `define` doesn't have a core binding --- and if you make the
example `define-values` instead of `define` as a macro that expands to
`1`, that `define-values` still won't be bound to the core form.


> "In this case, maybe you want to report the error from the
> implementation `func` by using `syntax-local-context` to detect when
> it's being used in an expression position."
> 
> I just tried this and it worked pretty nicely! Thanks! Do you know if there's 
> any way to adapt this to let statements? I.e.
> 
> (my-let () (func a(x) x))
> 
> Syntax-local-context just tells me that the func is in an internal-definition 
> position, but I'd like a way of saying "If the LAST body of the let is an 
> internal-definition, do something, and if not, do something else."

No, there's not currently a way for a macro to know that expansion is
in the last position with an internal-definition sequence.

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [racket-users] Is there a way to check whether syntax is an expression or a define statement?

2017-06-29 Thread Sam Waxman
On Thursday, June 29, 2017 at 11:47:00 AM UTC-4, Matthew Flatt wrote:
> At Thu, 29 Jun 2017 08:10:25 -0700 (PDT), Sam Waxman wrote:
> > One of my constructs, (func name(args) body), defines a function that's 
> > able 
> > to be called afterwards, and it desugars into a pretty regular define 
> > statement. [...]
> > 
> > While I don't want this to be allowed, I'd like to catch this and
> > throw my own errors if this happens. The only way I can really
> > imagine doing this is to modify all the functions I have that take in
> > expressions (+ - * / let ...) and give them contracts that say "Hey,
> > check to make sure your arguments are expressions, and if not, throw
> > this syntax error!"
> 
> The only way to check whether a form is an expression or definition is
> to partially expand it and match on the form.
> 
> In this case, maybe you want to report the error from the
> implementation `func` by using `syntax-local-context` to detect when
> it's being used in an expression position.

"The only way to check whether a form is an expression or definition is
to partially expand it and match on the form." 
- This seems sort of rough to believe. If you shadow the syntax-rule for define 
so that (define id binding) always just returns the number 1, then (+ (define a 
1) 1) will work perfectly, so somehow racket knows that the first define is not 
an expression, whereas the second is. If you partially expand it and look at 
it's form, doesn't that just tell you that it expands into something called 
define? Can't you not figure out if that's racket's define or a user-defined, 
expression define?

"In this case, maybe you want to report the error from the
implementation `func` by using `syntax-local-context` to detect when
it's being used in an expression position."

I just tried this and it worked pretty nicely! Thanks! Do you know if there's 
any way to adapt this to let statements? I.e.

(my-let () (func a(x) x))

Syntax-local-context just tells me that the func is in an internal-definition 
position, but I'd like a way of saying "If the LAST body of the let is an 
internal-definition, do something, and if not, do something else."

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [racket-users] Is there a way to check whether syntax is an expression or a define statement?

2017-06-29 Thread Matthew Flatt
At Thu, 29 Jun 2017 08:10:25 -0700 (PDT), Sam Waxman wrote:
> One of my constructs, (func name(args) body), defines a function that's able 
> to be called afterwards, and it desugars into a pretty regular define 
> statement. [...]
> 
> While I don't want this to be allowed, I'd like to catch this and
> throw my own errors if this happens. The only way I can really
> imagine doing this is to modify all the functions I have that take in
> expressions (+ - * / let ...) and give them contracts that say "Hey,
> check to make sure your arguments are expressions, and if not, throw
> this syntax error!"

The only way to check whether a form is an expression or definition is
to partially expand it and match on the form.

In this case, maybe you want to report the error from the
implementation `func` by using `syntax-local-context` to detect when
it's being used in an expression position.

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [racket-users] Is there a way to check whether syntax is an expression or a define statement?

2017-06-29 Thread Sam Waxman
On Thursday, June 29, 2017 at 11:22:38 AM UTC-4, David K. Storrs wrote:
> On Thu, Jun 29, 2017 at 11:10 AM, Sam Waxman  wrote:
> Hey all,
> 
> 
> 
> I'm writing a #lang and am trying to raise my own errors instead of having 
> racket throw any errors of its own.
> 
> 
> 
> One of my constructs, (func name(args) body), defines a function that's able 
> to be called afterwards, and it desugars into a pretty regular define 
> statement. As a result, I can't do things like
> 
> 
> 
> (let () (func a(x) x))
> 
> (+ (func a(x) x) 1)
> 
> etc ...
> 
> 
> 
> because it ends up expanding into a define statement in an expression 
> position, which is bad.
> 
> 
> 
> While I don't want this to be allowed, I'd like to catch this and throw my 
> own errors if this happens. The only way I can really imagine doing this is 
> to modify all the functions I have that take in expressions (+ - * / let ...)
> 
> and give them contracts that say "Hey, check to make sure your arguments are 
> expressions, and if not, throw this syntax error!"
> 
> 
> 
> The only problem there is that I can't seem to find any function that will 
> tell me if I have an expression or a define. Is there an easy way to check 
> this? I.e. a function expression? such that
> 
> 
> 
> (expression? #'(+ 1 1)); #t
> 
> (expression? #'(define a 1)); #f
> 
> (expression? #'(define-syntax-rule (id x) x)); #f
> 
> 
> 
> 
> 
> It'd be nice if there was a function like this, but also, if there's an 
> easier way to do this, by all means, lemme know!
> 
> 
> 
> Thanks in advance.
> 
> 
> 
> 
> 
> I think you want 'splicing-let':
> 
> #lang racket
> 
> (require racket/splicing)
> 
> (splicing-let ()
>   (define (foo a) a)
>   (foo 'x))
> (foo 'y)
> 
> 
> Ouput:
> 
> 
> 'x
> 
> 'y
> 
>  I'm not actually trying to get the define statements to define things here, 
> or to splice them into the surrounding environment, I'm just trying to throw 
> my own custom error messages/define my own custom behavior when you put 
> defines in expression positions. So

(my+ 1 (func a(x) x))

shouldn't work, but instead of racket's error messages, I'd like to throw one 
like "The arguments to + must be expressions. Recieved a function definition 
for argument 2."

I'd also be interested in changing (my-let () (func a(x) x)) to expand into 
(my-let () (func a(x) x) (values)) so racket doesn't throw an error when func's 
are the final bodies in a let statement.

But the issue isn't that I want to splice these defines, it's that I need a way 
of checking in my+, my-let, my-, my/ ... (which are all macros I've written for 
my languages' +, let, -, / ...) to see if the arguments they have are 
expressions or define statements.
> --
> 
> You received this message because you are subscribed to the Google Groups 
> "Racket Users" group.
> 
> To unsubscribe from this group and stop receiving emails from it, send an 
> email to racket-users...@googlegroups.com.
> 
> For more options, visit https://groups.google.com/d/optout.

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [racket-users] Is there a way to check whether syntax is an expression or a define statement?

2017-06-29 Thread David Storrs
On Thu, Jun 29, 2017 at 11:10 AM, Sam Waxman  wrote:

> Hey all,
>
> I'm writing a #lang and am trying to raise my own errors instead of having
> racket throw any errors of its own.
>
> One of my constructs, (func name(args) body), defines a function that's
> able to be called afterwards, and it desugars into a pretty regular define
> statement. As a result, I can't do things like
>
> (let () (func a(x) x))
> (+ (func a(x) x) 1)
> etc ...
>
> because it ends up expanding into a define statement in an expression
> position, which is bad.
>
> While I don't want this to be allowed, I'd like to catch this and throw my
> own errors if this happens. The only way I can really imagine doing this is
> to modify all the functions I have that take in expressions (+ - * / let
> ...)
> and give them contracts that say "Hey, check to make sure your arguments
> are expressions, and if not, throw this syntax error!"
>
> The only problem there is that I can't seem to find any function that will
> tell me if I have an expression or a define. Is there an easy way to check
> this? I.e. a function expression? such that
>
> (expression? #'(+ 1 1)); #t
> (expression? #'(define a 1)); #f
> (expression? #'(define-syntax-rule (id x) x)); #f
>
>
> It'd be nice if there was a function like this, but also, if there's an
> easier way to do this, by all means, lemme know!
>
> Thanks in advance.
>
>
I think you want 'splicing-let':

#lang racket

(require racket/splicing)

(splicing-let ()
  (define (foo a) a)
  (foo 'x))
(foo 'y)

Ouput:

'x
'y


> --
> You received this message because you are subscribed to the Google Groups
> "Racket Users" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to racket-users+unsubscr...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.
>

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[racket-users] Is there a way to check whether syntax is an expression or a define statement?

2017-06-29 Thread Sam Waxman
Hey all,

I'm writing a #lang and am trying to raise my own errors instead of having 
racket throw any errors of its own.

One of my constructs, (func name(args) body), defines a function that's able to 
be called afterwards, and it desugars into a pretty regular define statement. 
As a result, I can't do things like

(let () (func a(x) x))
(+ (func a(x) x) 1)
etc ...

because it ends up expanding into a define statement in an expression position, 
which is bad.

While I don't want this to be allowed, I'd like to catch this and throw my own 
errors if this happens. The only way I can really imagine doing this is to 
modify all the functions I have that take in expressions (+ - * / let ...)
and give them contracts that say "Hey, check to make sure your arguments are 
expressions, and if not, throw this syntax error!"

The only problem there is that I can't seem to find any function that will tell 
me if I have an expression or a define. Is there an easy way to check this? 
I.e. a function expression? such that

(expression? #'(+ 1 1)); #t
(expression? #'(define a 1)); #f
(expression? #'(define-syntax-rule (id x) x)); #f


It'd be nice if there was a function like this, but also, if there's an easier 
way to do this, by all means, lemme know!

Thanks in advance.

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.