What is the Scheme equivalent of this alias code written in CL? - scheme

I'm trying to write the Scheme equivalent of this CL code:
(defmacro alias (new-name prev-name)
`(defmacro ,new-name (&rest args)
`(,',prev-name ,#args)))
;; Sample use:
(alias co concatenate)
My aim is to be able to use shorthand names for symbol and function names like:
(alias sa string-append)
(sa "ok" "not ok")
To do that I've tried this but it didn't work:
(define-syntax alias (new-name prev-name)
`(define-syntax ,new-name (#!rest args)
`(,',prev-name ,#args)))
Any help is appreciated. Thank you.

You can do this easily with a syntax-rules macro that defines another syntax-rules macro:
(define-syntax alias
(syntax-rules ()
((_ new-name prev-name)
(define-syntax new-name
(... (syntax-rules ()
((_ arg ...)
(prev-name arg ...))))))))
The trickiest thing is this macro is the use of ... to escape nested uses of ....
However, this is not necessarily the best way to do this. The best way probably depends on your precise Scheme implementation, as Scheme is less a language and more a family of languages. Writing portable Scheme is usually not very useful.

If your scheme supports R6RS syntax-case and cognates (say, guile or chez scheme), identifier-syntax is the most direct way of implementing what you want:
(define-syntax new-name (identifier-syntax old-name))
Thus:
(define-syntax new-display (identifier-syntax display))
(new-display "hello\n")
Edit: I see you are using chicken. In that case you can use er-macro-transformer to reproduce your defmacro solution (this works with chicken-4.10.0 at any rate):
(define-syntax alias
(er-macro-transformer
(lambda (exp r c)
(let ([new-name (cadr exp)]
[old-name (caddr exp)])
`(define-syntax ,new-name
(ir-macro-transformer
(lambda (exp i c)
`(,',old-name ,#(cdr exp)))))))))

By the way, in Common Lisp you can make an alias a real function, not a macro, by settings symbol-function of a symbol denoting an alias like this:
CL-USER> (defun foo (name)
(format nil "Hello ~A!~%" name))
FOO
CL-USER> (setf (symbol-function 'bar)
#'foo)
#<INTERPRETED-FUNCTION FOO>
CL-USER> (bar "Bob")
"Hello Bob!
"

Related

To use the same begin-for-syntax definition in different files

I'm in a bigger code and I need to do it like:
file_1.rkt :
#lang racket
(provide define-type types-ref)
(require syntax/parse/define)
(begin-for-syntax
(define types (make-hasheq)))
(define-syntax-parser define-type
[(_ id type)
(hash-set! types (syntax->datum #'id) (syntax->datum #'type))
#'(void)])
(define-syntax-parser types-ref
[(_ id)
(writeln (hash-ref types (syntax->datum #'id)))
#'(void)])
file_2.rkt :
#lang racket
(provide (all-defined-out))
(require "file_1.rkt")
(define-type Atom Symbol)
(types-ref Atom)
out:
Symbol
file_3.rkt :
#lang racket
(require "file_1.rkt" "file_2.rkt")
(types-ref Atom)
out:
; hash-ref: no value found for key
; key: 'Atom
; Context (plain; to see better errortrace context, re-run with C-u prefix):
; /Applications/Racket v8.0/collects/syntax/parse/define.rkt:20:4
; /Applications/Racket v8.0/collects/syntax/wrap-modbeg.rkt:46:4
; /...
It seems that for each syntax expansion types is instantiated again.
I need to share the same types for different files. What can I do?
Do you really need to store the information in a hash table like that? A simpler way is to actually define id in define-type, so that you can properly provide it, and the other modules can properly require it.
It looks like you want define-type to occur at compile-time, so you can use define-syntax to create the binding, and use syntax-local-value to reference it.
#lang racket
(provide define-type types-ref)
(require syntax/parse/define)
(define-syntax-parser define-type
[(_ id type)
#'(define-syntax id (quote type))])
(define-syntax-parser types-ref
[(_ id)
(writeln (syntax-local-value #'id))
#'(void)])

Common Lisp No Dispatch Character Defined

I am currently reading the chapter on read-time macros from Paul Graham's "On Lisp" book.
The problem I am encountering is the following. When I run one of his examples:
(set-dispatch-macro-character #\# #\?
#’(lambda (stream char1 char2)
‘#’(lambda (&rest ,(gensym))
,(read stream t nil t))))
I get the following error:
No dispatch function defined for #\’
Why is it happening? Could it be because I am running it at the REPL? What can one do to fix it?
The PDF from which you are copying the code uses punctuation marks outside the range of basic ASCII characters you are supposed to use here:
CL-USER> (char-name #\’)
"RIGHT_SINGLE_QUOTATION_MARK"
The usual quote symbol should instead use the apostrophe character:
CL-USER> (char-name #\')
"APOSTROPHE"
The same goes for backquote:
CL-USER> (char-name #\‘)
"LEFT_SINGLE_QUOTATION_MARK"
You should be writing instead:
(set-dispatch-macro-character #\# #\?
#'(lambda (stream char1 char2)
`#'(lambda (&rest ,(gensym))
,(read stream t nil t))))
The #' is not necessary before lambda, since Common Lisp also defines a macro named lambda which expands into (function (lambda ...)).
You can test your new read macro as follows:
CL-USER> #?10
#<FUNCTION (LAMBDA (&REST #:G617)) {1001C541FB}>
CL-USER> (funcall *)
10
When using SBCL, I obtain warnings about unused variables. This happens because the code declares variables in anonymous functions but never uses them. This is not a serious problem, but generally speaking, it is better to declare which variables are ignored:
(set-dispatch-macro-character
#\# #\?
(lambda (stream &rest chars)
(declare (ignore chars))
(let ((rest (gensym)))
`(lambda (&rest ,rest)
(declare (ignore ,rest))
,(read stream t nil t)))))

Macro for renaming sequence- functions

Can I create a macro so that I can call sequence- functions with a s-? Hence, I should be able to write s-length, s-filter and s-map instead of sequence-length, sequence-filter and sequence-map. Thanks.
You can use filtered-in from racket/require to perform this sort of transformation. Here’s a simple example:
#lang racket
(require racket/require
(filtered-in (λ (name) (regexp-replace #rx"^sequence-" name "s-"))
racket/sequence))
(s-ref '(1 2 3) 1)
If you find yourself using this sort of thing often, it wouldn’t be too hard to write a require transformer that would expand to filtered-in:
#lang racket
(require (for-syntax racket/require-transform
syntax/parse)
racket/require)
(define-syntax reprefix-in
(make-require-transformer
(syntax-parser
[(_ original-prefix:id new-prefix:id require-spec:expr ...)
#:with replacer (string-append "^" (regexp-quote (symbol->string (syntax-e #'original-prefix))))
#:with replacement (symbol->string (syntax-e #'new-prefix))
(expand-import #'(filtered-in (λ (name) (regexp-replace (regexp 'replacer) name 'replacement))
(combine-in require-spec ...)))])))
Then you can use it like this:
(require (reprefix-in sequence- s- racket/sequence))
(s-ref '(1 2 3) 1)
Yes there is. To versing levels of cludgyness.
The way I highly recommend you do, however, is to use rename-in To rename each of these functions on import. So for example, your code would look like:
#lang racket
(require (rename-in racket/sequence
[sequence-length s-length]
[sequence-map s-map]
[sequence-filter s-filter]
...))
There are other more advanced ways to do this that do not require you to explicitly list out each identifier, using module->exports, regexp-match, format-id, and make-require-transformer. But this seems to brittle to me and you're better off being explicit about which names you want to rename.

How to make a "define" that accepts string in the first parameter in SISC Scheme?

Let's call this function "dynamic-define".
Basically I want to write a macro or lambda that works like this:
$ (dynamic-define "variable" 123)
$ variable
$ => 123
I tried it:
(define-syntax dynamic-define
(syntax-rules ()
((_ string <body>)
(eval `(define ,(string->symbol string) <body>)))))
and it works as expected but doesn't seem to be a good solution.
I tried to use without eval like this:
(define-syntax dynamic-define
(syntax-rules ()
((_ string <body>)
(define (string->symbol string) <body>))))
But when I try to use I get this error:
Error: invalid syntax (define (string->symbol "variable") 123)
What should I do?
(PLEASE: edit this question to fit native English and erase this line please)
You're running against a fundamental problem: you cannot do a real dynamic define in a "clean" way, hence your attempt using eval. Note that the two solutions above are both not dynamic -- all they give you is the ability to write "foo" instead of foo. As I said elsewhere, using eval is usually bad, and in this case it's worse since it's eval that is used from a macro which makes it very weird. This is in addition to having an implicit quasi-quote in your macro that makes things even more confusing. You could just as well define the whole thing as a plain function:
(define (dynamic-define string <body>)
(eval `(define ,(string->symbol string) ,<body>)))
If you really need this to work, then it's best to take a step back and think about what it is that you need, exactly. On one hand, the above solutions are not dynamic since they require using the macro with a string syntax
(dynamic-define "foo" 123) ; instead of (define foo 123)
but how would it look to have a real dynamic definition that takes in a string? You'd probably expect this to define b:
(define a "b")
(dynamic-define a 123)
but this only becomes more confusing when you consider how it interacts with other bindings. For example:
(define y 123)
(define (foo s)
(define x 456)
(dynamic-define s 789)
(+ x y))
Now, assuming that dynamic-define does what you want it to do, think about what you'd get with (foo "x") and (foo "y"). Worse, consider (foo "s") and (foo "+"). And even worse, what about
(foo (random-element '("x" "y" "s" "+" "define")))
? Clearly, if this dynamic-define really does some dynamic definition, then there is no sense that you can make of this code without knowing ahead of time what name foo will be called with. Without being able to make such sense, compilation goes out the window -- but much more importantly, correctness (or generally, the meaning of your code) dies.
In my experience, this kind of pattern is much better handled with hash tables and similar devices.
using define-macro
#> (define-macro (dynamic-define varstr val)
`(define ,(string->symbol varstr) ,val))
#> (dynamic-define "variable" 123)
#> variable
123
using syntax-case
#> (define-syntax dynamic-define
(lambda (stx)
(syntax-case stx ()
((k varstr val)
(with-syntax ([var (datum->syntax-object
#'k
(string->symbol (syntax-object->datum #'varstr)))])
#'(define var val))))))
#> (dynamic-define "variable" 123)
#> variable
123

Why can't this macro execute?

I have the following dumb test:
(define-syntax a
(lambda (stx)
(syntax-case stx ()
[(k e s) #'(let ((show display)) (e s))])))
(a show "something")
Why can't this work? (The error shows in DrRacket is expand: unbound identifier in module in: show.
However, The following can work:
(define-syntax a
(lambda (stx)
(syntax-case stx ()
[(k e s)
(with-syntax ((show (datum->syntax #'k 'show)))
#'(let ((show display)) (e s)))])))
(a show "something")
Then WHY?
Um, I assume that you're trying this out after reading the blog post I mentioned in an earlier answer -- but that blog post is explaining exactly this issue. Specifically, your first example has two different show identifiers, one that is bound by the macro, and a different one that is coming from the toplevel use (and is unbound). OTOH, in the second case you're creating a show with the lexical context of the user code.

Resources