(define defun define)
It raises error define: not allowed in an expression context in: define in Racket. How to create aliases for fundamental constructs like define, let, lambda?
define is a syntax, not a first-class object. You cannot refer to it as an object.
As Justin said, you can create a macro. But note that Lisp-style defun has different syntax to Scheme-style define, and your macro should take that into account:
(define-syntax-rule (defun name params body ...)
(define (name . params)
body ...))
Not sure about Racket specifically, but the more general problem is that in Scheme define, let and lambda are syntax and/or special forms rather than functions. So you cannot reference them in an expression context like you could if they were defined as functions.
But instead, you can define a macro defun that expands into a define expression.
With normal procedures you can alias with define:
(define first car) ; first isn't defined in R[67]RS
However define and defun isn't form compatible. This macro will make a global defun that works as in Common Lisp:
#!r6rs
(import (rnrs base))
(define-syntax defun
(syntax-rules ()
((defun name args . body)
(define (name . args) . body))))
define in Scheme has more hats than defun, mostly because of the one-namespace nature of Scheme. define works as labels, flet, defconstant and setq (but for previously bound, one need to use set! to update).
Related
It's very common for Scheme macros to make "derived" identifiers, like how defining a record type foo (using the R6RS syntactic record API) will by default define a constructor called make-foo. I wanted to do something similar in my own macro, but I couldn't find any clean way within the standard libraries. I ended up writing this:
(define (identifier-add-prefix identifier prefix)
(datum->syntax identifier
(string->symbol (string-append prefix
(symbol->string (syntax->datum identifier)))))
I convert a syntax object (assumed to be an identifier) into a datum, convert that symbol into a string, make a new string with the prefix prepended, convert that string into a symbol, and then finally turn that symbol into an identifier in the same syntactic environment as identifier.
This works, but it seems roundabout and messy. Is there a cleaner or more idiomatic way to do this?
Although it might not be a hygienic macro, i suppose you could use define-syntax like this (in chicken scheme).
For chicken scheme the documentation for macros is here. Also this SO question sheds some light on chicken scheme macros. Finally i don't know if this would be an idiomatic way to approach the problem.
(use format)
(use srfi-13)
(define-syntax recgen
(lambda (expr inject compare)
`(define (,(string->symbol (string-append "make-" (cadr expr))) ) (format #t "called"))))
#> (recgen "bar")
#> (make-bar)
called
The single define above could be changed to a (begin ... ) that defines getters/setters or other ways to interact with the record.
The problem is quite difficult to explain because I need to collect my thoughts, so bear with me. I've been able to reduce the problem to a minimal example for illustrative purposes. The example will not make any sense as to what this would be useful for, but I digress. Say I want to extend the racket language to write things that look like this:
(define-something
(['a] 'whatever)
(['b 'c] 'whatever2))
Between the square brackets is a sequence of one or more symbols, followed by a sequence of racket expressions (the whatever's, which are not important for the problem statement)
The example would match a macro that looks something like this:
(define-syntax (define-something stx)
(syntax-case stx ()
[(_ ([symb ...] body ...) ...)
#'()]))
Actually here we match 0 or more symbols, but we can assume there is always going to be at least one.
In the macro's body I want to generate function definitions using the concatenated symbols as the identifier. So for our silly example the macro would expand to something like:
(define (a) 'whatever)
(define (bc) 'whatever2)
I have found a similar question where the poster generates functions using a pre-defined list of strings, but I am not that fluent with macro's so I have not been able to translate the concepts to solve my problem. I thought perhaps I could try generating a similar list (by concatenating the symbols) and applying their tactic, but I've been getting way too confused with all the ellipses in my macro definition. I'm also a bit confused about their use of an ellipsis in with-syntax.
It’s possible to solve this with with-syntax and syntax-case, but the easiest way to do this is by using syntax-parse’s syntax classes. By defining a syntax class that parses a list of symbols and produces a single concatenated identifier, you can lift the symbol parsing out of the macro body:
(require (for-syntax syntax/parse
racket/string))
(begin-for-syntax
(define-syntax-class sym-list
#:attributes [concatenated-id]
(pattern (~and stx (sym:id ...))
#:attr concatenated-id
(let* ([syms (syntax->datum #'(sym ...))]
[strs (map symbol->string syms)]
[str (string-append* strs)]
[sym (string->symbol str)])
(datum->syntax #'stx sym #'stx #'stx)))))
Now you can define your macro pretty easily:
(define-syntax (define-something stx)
(syntax-parse stx
[(_ (syms:sym-list body ...) ...)
#'(begin
(define (syms.concatenated-id) body ...)
...)]))
Note that this uses unquoted symbols in the name clause, so it would work like this:
(define-something
([a] 'whatever)
([b c] 'whatever2))
The names can’t be expressions that evaluate to symbols because the information needs to be known at compile-time to be available to macro expansion. Since you mentioned in a comment that this is for an FRP-like system, your signal graph will need to be static, like Elm’s is for example. If you want the ability to construct a dynamic signal graph, you’ll need a more complex strategy than macros since that information will need to be resolved at runtime.
Why is it that:
Function definitions can use definitions defined after it
while variable definitions can't.
For example,
a) the following code snippet is wrong:
; Must define function `f` before variable `a`.
#lang racket
(define a (f))
(define (f) 10)
b) While the following snippet is right:
; Function `g` could be defined after function `f`.
#lang racket
(define (f) (g)) ; `g` is not defined yet
(define (g) 10)
c) Right too :
; Variable `a` could be defined after function `f`
#lang racket
(define (f) a) ; `a` is not defined yet
(define a 10)
You need to know several things about Racket:
In Racket, each file (that starts with #lang) is a module, unlike many (traditional, r5rs) schemes that have no modules.
The scoping rules for modules are similar to the rules for a function, so in a sense, these definitions are similar to definitions in a function.
Racket evaluates definitions from left to right. In scheme lingo you say that Racket's definitions have letrec* semantics; this is unlike some schemes that use letrec semantics where mutually recursive definitions never work.
So the bottom line is that the definitions are all created in the module's environment (similarly in a function, for function-local definitions), and then they are initialized from left to right. Back-references therefore always work, so you can always do something like
(define a 1)
(define b (add1 a))
They are created in a single scope -- so in theory forward definitions are valid in the sense that they're in scope. But actually using a value of a forward-reference is not going to work since you get a special #<undefined> value until the actual value is evaluated. To see this, try to run this code:
#lang racket
(define (foo)
(define a a)
a)
(foo)
A module's toplevel is further restricted so that such references are actually errors, which you can see with:
#lang racket
(define a a)
Having all that in mind, things are a bit more lenient with references inside functions. The thing is that the body of a function is not executed until the function is called -- so if a forward reference happens inside a function, it is valid (= won't get an error or #<undefined>) if the function is called after all of the bindings have been initialized. This applies to plain function definitions
(define foo (lambda () a))
definitions that use the usual syntactic sugar
(define (foo) a)
and even other forms that ultimately expand into functions
(define foo (delay a))
With all of these, you won't get any errors by the same rule -- when all uses of the function bodies happen after the definitions were initialized.
One important note, however, is that you shouldn't confuse this kind of initialization with assignment. This means that things like
(define x (+ x 1))
are not equivalent to x = x+1 in mainstream languages. They're more like some var x = x+1 in a language that will fail with some "reference to uninitialized variable" error. This is because define creates a new binding in the current scope, it does not "modify" an existing one.
The following is an approximate general Scheme description, an analogy.
Defining a function
(define (f) (g))
is more or less like
f := (lambda () (g))
so the lambda expression is evaluated, and the resulting functional object (usually a closure) is stored in the new variable f being defined. The function g will have to be defined when the function f will be called.
Similarly, (define (h) a) is like h := (lambda () a) so only when the function h will be called, the reference to the variable a will be checked, to find its value.
But
(define a (f))
is like
a := (f)
i.e. the function f has to be called with no arguments, and the result of that call stored in the new variable a being defined. So the function has to be defined already, at that point.
Each definition in a file is executed in sequence, one after another. Each definition is allowed to refer to any of the variables being defined in a file, both above and below it (they are all said to belong to the same scope), but it is allowed to use values of only those variables that are defined above it.
(there is an ambiguity here: imagine you were using a built-in function, say with (define a (+ 1 2)), but were also defining it later on in the file, say (define + -). Is it a definition, or a redefinition? In the first case, which is Racket's choice, use before definition is forbidden. In the second, the "global" value is used in calculating the value of a, and then the function is redefined. Some Schemes may go that route. Thanks go to Eli Barzilay for showing this to me, and to Chris Jester-Young for helping out).
What 'kind of thing' will I get if I do this?
(car (list lambda lambda))
I thought I'd get lambda back, which means I could do
(define my_lambda (car (list lambda lambda)))
(define foo (my_lambda (n) (+ n n)))
But that didn't work!
Thanks,
lambda is a special form (meaning: standard evaluation rules don't apply to it), part of the core primitives of the language and is not a symbol or other kind of value that can be assigned to a variable.
Answering your question, the "kind of thing" that you'll get after evaluating the expression (list lambda) will depend on the Scheme interpreter that you're using, but more often than not you'll get an error. For instance, DrRacket complains like this:
lambda: bad syntax in: lambda
In some sense, lambda doesn't exist at runtime (sure, the functions created by lambda statements exist, but that's a different matter; they aren't lambda itself).
The reason for this is that the lambda statement manipulates other things that don't exist at runtime; in particular, it changes the meaning of variable names (in your example, n).
To answer your question about what kind of thing lambda is, the usual answer is "syntax". Fortunately, Scheme provides a mechanism to abstract over syntax: macros. Macros can abstract over compile-time-only entities, like variable names and lambdas and other macros. So, you could write (in the Racket REPL, in this case):
> (define-syntax-rule (mylambda (x ...) body)
(lambda (x ...) body))
> (define foo (mylambda (n) (+ n n)))
> (foo 71)
142
There are multiple systems for defining Scheme macros; the syntax-rules system uses ...s in an unusual, but ultimately pretty intuitive fashion. It is also possible to define macros by writing Scheme code that emits Scheme, which involves a little more complication.
Forgive my ignorance, but what is the difference between these two:
(define blah)
(define* blah)
? Unfortunately Google ignores the asterisks character.
SRFI 89 was written by Gambit's author, so it's only fair to assume that Gambit's define* does what that document says. :-)
In other words, it's syntactic sugar over lambda* (as described in SRFI 89) rather than lambda.
In the (rather extensive) documentation of Gambit Scheme there is no mention of a define* special form; it might be some procedure, definition, macro or special form found only in the piece of code where you saw it. You should post a link referencing the source of the code where define* is being used.
A little more context for the question would be nice.
Sometimes the * just means that the form does something extra.
My guess is therefore that define* works as ordinary define,
but at the same time does something extra. This extra could
be automatically exporting the name from a module.
This definition was found in the Racket ffi-lib illustrates
this principle:
(define-syntax define*
(syntax-rules ()
[(_ (name . args) body ...)
(begin (provide name) (define (name . args) body ...))]
[(_ name expr)
(begin (provide name) (define name expr))]))