I would like to set the language that my racket REPL is using interactively, like this:
-> #lang typed/racket
; readline-input:15:0: read: #lang not enabled in the current context [,bt for
; context]
; typed/racket: undefined;
; cannot reference undefined identifier
; [,bt for context]`
But it gives me this error:
-> ,bt
; typed/racket: undefined;
; cannot reference undefined identifier
What is my error?
From the terminal you can choose what language to use when you start racket:
racket -I typed/racket
Related
I would like to try extending some Lisp (Scheme, Racket, Clojure, any) to run external commands as follows:
; having
(define foo ...)
(define bar ...)
; on command
(ls (foo bar) baz)
; this lisp should evaluate (foo bar) as usual, with result "foobar", then
(ls foobar baz)
; here "ls" is not defined
; instead of rising "undefined identifier" exception
; it must look for "ls" command in the directories
; in the "PATH" environment variable
; and launch the first found "ls" command
; with strings "foobar" and "baz" on input
I just want to run it anyhow, without carrying about correct conversion from lisp's data structures to strings or handling the exit code and the output of the command in stdout/stderr.
I think there is no way to extend it within normal environment (like catching the "undefined" exception all the time). The eval procedure of the interpreter itself must be changed.
Which Lisp is the best to extend it like this and how is it done? Maybe there already exists a project performing something similar?
Common Lisp has a standard error system which may be used to implement that.
In Common Lisp implementations which provide a use-value or store-value restart for errors of type undefined-function.
Example
CL-USER 69 > (flet ((call-use-value-restart (c)
(use-value (lambda (arg)
(format t "~%dummy function with arg ~a~%" arg))
c)))
(handler-bind ((undefined-function #'call-use-value-restart))
(this-function-does-not-exist "foo")))
dummy function with arg foo
NIL
In the above example the function this-function-does-not-exist does not exist. As you can see, the error is handled and another function is called instead, which then does some output.
If we call the undefined function on its own, we get an error:
CL-USER 70 > (this-function-does-not-exist "foo")
Error: Undefined operator THIS-FUNCTION-DOES-NOT-EXIST in form (THIS-FUNCTION-DOES-NOT-EXIST "foo").
1 (continue) Try invoking THIS-FUNCTION-DOES-NOT-EXIST again.
2 Return some values from the form (THIS-FUNCTION-DOES-NOT-EXIST "foo").
3 Try invoking something other than THIS-FUNCTION-DOES-NOT-EXIST with the same arguments.
4 Set the symbol-function of THIS-FUNCTION-DOES-NOT-EXIST to another function.
5 Set the macro-function of THIS-FUNCTION-DOES-NOT-EXIST to another function.
6 (abort) Return to top loop level 0.
Type :b for backtrace or :c <option number> to proceed.
Type :bug-form "<subject>" for a bug report template or :? for other options.
CL-USER 71 : 1 >
Our example basically calls the restart number 3 programmatically:
It binds a handler which calls the function call-use-value-restart when an error of type undefined-function happens.
The function call-use-value-restart then calls the use-value restart with a function it provides. Here you could provide a function which calls an external program of the name given by (cell-error-name c). The use-value restart then just calls the provided function and keeps on executing the program as usual.
Hint for a solution
Typically one would write a small top-level loop where such a handler is provided.
Another way to call the restart
In this example we use a hook to add a handler in case an error happens. Here we use the global variable *debugger-hook*. This should be a function and in our case it calls a new function when the condition c is of type undefined-function.
* (defun provide-a-function-hook (c hook)
(declare (ignore hook))
(typecase c
(undefined-function (use-value (lambda (arg)
(format t "~%dummy function with arg ~a~%" arg))
c))))
PROVIDE-A-FUNCTION-HOOK
* (setf *debugger-hook* #'provide-a-function-hook)
#<FUNCTION PROVIDE-A-FUNCTION-HOOK>
* (this-function-does-not-exist "foo")
; in: THIS-FUNCTION-DOES-NOT-EXIST "foo"
; (THIS-FUNCTION-DOES-NOT-EXIST "foo")
;
; caught STYLE-WARNING:
; undefined function: THIS-FUNCTION-DOES-NOT-EXIST
;
; compilation unit finished
; Undefined function:
; THIS-FUNCTION-DOES-NOT-EXIST
; caught 1 STYLE-WARNING condition
dummy function with arg foo
NIL
In racket you may override #%top:
#lang racket
(provide
(combine-out
(except-out (all-from-out racket) #%top)
(rename-out [shell-curry #%top])))
(require racket/system)
(define (stringify a)
(~a (if (cmd? a) (cmd-name a) a)))
(struct cmd (name proc)
#:property prop:procedure
(struct-field-index proc)
#:transparent
#:methods gen:custom-write
[(define (write-proc x port mode)
(display (string-append "#<cmd:" (stringify x) ">") port))])
(define (shell name)
(define (cmd-proxy . args)
(define cmd
(string-join (map stringify (cons name args))
" "))
(system cmd))
cmd-proxy)
(define-syntax shell-curry
(syntax-rules ()
((_ . id)
(cmd 'id (shell 'id)))))
Save this as shell.rkt and make this runner.rkt in the same directory:
#lang s-exp "shell.rkt"
(define test (list /bin/ls /usr/bin/file))
(second test) ; ==> #<cmd:/usr/bin/file>
(first test) ; ==> #<cmd:/bin/ls>
((second test) (first test))
; ==> t (prints that /bin/ls is an executable on my system)
Now from here to make it a #lang myshell or something like that is pretty easy.
Suppose the following trivial function:
(define/contract (foo func)
(-> (-> any/c ... any/c) #t)
#t)
This is trying (and failing) to express the idea "foo takes a processor function. I don't care what arguments the processor requires (that's the caller's job) but the processor must return a singular result."
What would be the correct contract for foo? I've been through the section on function contracts; the above was my first guess but this fails:
(foo identity)
; foo: contract violation
; expected: a procedure that accepts 0 non-keyword arguments and arbitrarily
; many more
; given: #<procedure:identity>
; identity accepts: 1 argument
; in: the 1st argument of
; (-> (-> any/c ... any/c) #t)
; contract from: (function foo)
; blaming: top-level
; (assuming the contract is correct)
; at: readline-input:8.18
; [,bt for context]
I also tried this, which apparently isn't even legal syntax:
(define/contract (foo func)
(-> (-> any any/c) #t)
#t)
; readline-input:10:33: any: use of 'any' outside the range of an arrow
; contract
; in: any
; [,bt for context]
I think you want unconstrained-domain->
I have defined the following simple macro:
(defmacro define-class (class-name)
`(defclass ,class-name ()()))
And now I want to use it in the following function:
(defun create-data (mode)
(define-class mode))
After compiling the last function I get the following message, the variable MODE is defined but never used.
And when I execute the function to create a class "myclass", I get instead the creation of a class of type "mode":
(create-data 'myclass)
#<STANDARD-CLASS MODE>
Seems that my argument is not used? How can I get the function create-data to use the argument?
defclass isn't a function but a macro. It uses the name provided in the source (mode in your case) and it's not the same as your variable mode. In fact some CL implementations would warn you that argument mode is never used.
You can macroexpand it (macroexpand '(defclass mode ()())) to check what it becomes in your implementation. I get this in CLISP (I've cleaned it up a little):
(progn
(eval-when (compile load eval)
(apply #'ensure-class
'mode ; notice mode is quoted
:direct-superclasses (list)
:direct-slots (list)
:metaclass clos::<standard-class>
(append '(:fixed-slot-locations nil)
(list :direct-default-initargs nil
:documentation nil
:generic-accessors 't))))
(find-class 'mode)) ; notice mode is quoted
The expansion is imlementation dependent but the result is the same in all. mode is the name of the class being defined and not what you pass as argument.
You should use (define-class myclass) instead of (create-data 'myclass).
I would use something like this:
CL-USER 86 > (defmacro define-class (class-name)
`(defclass ,class-name ()()))
DEFINE-CLASS
CL-USER 87 > (defun create-data (mode)
(funcall (compile nil `(lambda ()
(define-class ,mode)))))
CREATE-DATA
CL-USER 88 > (create-data 'bar)
#<STANDARD-CLASS BAR 402016CC73>
Above uses code generation and the built-in compiler.
I'm writing some code in SBCL, and the ordering of my functions keeps causing warnings of the following type to appear when I load files into the REPL:
;caught STYLE-WARNING:
undefined function: FOO
Where FOO is the symbol for the function. This is purely due to how they are ordered in my file, as the function FOO is defined, just not before the part of the code that throws that warning.
Now, in Clojure, which is the Lisp I'm familiar with, I have the declare form, which lets me make forward declarations to avoid this kind of issue. Is there something similar for SBCL/Common Lisp in general?
We can use the '(declaim (ftype ...))' for that:
(declaim (ftype (function (integer list) t) ith))
(defun foo (xs)
(ith 0 xs))
(defun ith (n xs)
(nth n xs))
Both the function 'foo' and 'ith' works fine and there is not any style warning about that.
http://www.lispworks.com/documentation/HyperSpec/Body/d_ftype.htm
Here's what I found in the manual, section 4.1.1:
CL-USER> (defun foo (x) (bar x))
; in: DEFUN FOO
; (BAR X)
;
; caught STYLE-WARNING:
; undefined function: BAR
;
; compilation unit finished
; Undefined function:
; BAR
; caught 1 STYLE-WARNING condition
FOO
CL-USER> (declaim (sb-ext:muffle-conditions style-warning))
; No value
CL-USER> (defun baz (y) (quux y))
BAZ
So you can at least silence the style warnings.
I also thought about how SBCL is handling the evaluation step in the REPL: it compiles the code. So I restarted the inferior lisp process and ran "compile region" on the following two lines:
(defun foo (x) (bar x))
(defun bar (y) (baz y))
and SBCL only complained about baz, but not about bar. Are you giving single functions to SBCL or larger chunks?
sorry for my poor english:)
I have a problem with lisp. i type code here http://mitpress.mit.edu/sicp/full-text/book/book-Z-H-10.html to sbcl
* (define a 3)
; in: DEFINE A
; (DEFINE A 3)
;
; caught WARNING:
; undefined variable: A
;
; caught STYLE-WARNING:
; undefined function: DEFINE
;
; compilation unit finished
; Undefined function:
; DEFINE
; Undefined variable:
; A
; caught 1 WARNING condition
; caught 1 STYLE-WARNING condition
debugger invoked on a UNBOUND-VARIABLE in thread #<THREAD
"initial thread" RUNNING
{10029211E1}>:
The variable A is unbound.
Type HELP for debugger help, or (SB-EXT:QUIT) to exit from SBCL.
restarts (invokable by number or by possibly-abbreviated name):
0: [ABORT] Exit debugger, returning to top level.
some one give me a help?
You define a function with DEFUN:
(defun a () 3)
In your case you're trying to call the function DEFINE with an argument A... which is of course undefined.
More generally, you supply the parameters to a function like this:
(defun param-taking-fun (a b)
(+ a b))
Note that Scheme is a 1-lisp (same namespace for functions and variables) while SBCL, like all Common Lisp implementations, is a 2-lisp (different namespaces for functions and variables).
Thus in Scheme (define foo 3) defines a constant while (define foo (lambda () 3)) defines a constant function. In Common Lisp one way to define a constant is
(defconstant foo 3)