Non-existent hy macros runs assertions, but fails appropriately with everything else - hy

In the following code:
(eval-and-compile (import os hy))
(eval-and-compile (import pathlib [Path]))
; (defmacro with-cwd [dir #* body]
; (setv cwd (hy.gensym))
; `(let [ ~cwd (.cwd Path) ]
; (try (.chdir os ~dir)
; ~#body
; (finally (.chdir os ~cwd)))))
(setv cookies (/ (.cwd Path) "cookies"))
; This fails with an `AssertionError'
(with-cwd cookies (assert (= (.cwd Path) cookies)))
; This fails with a `NameError'
(with-cwd cookies (.cwd Path))
Similarly, any functions or macros depending on the missing macro errors out in the same way, and if, for example, I'm importing or requiring a function or macro that depends on the missing macro, the same thing happens; basically, I have to import or require a function or macro as well as its dependencies manually.
Is this a bug, or am I missing something about the order of Python / Hy assertions? I expected the first case to fail with a NameError as well.

This is a documented quirk:
Like many programming languages, but unlike Python, Hy doesn't guarantee in all cases the order in which function arguments are evaluated. More generally, the evaluation order of the child models of a hy.models.Sequence is unspecified. For example, (f (g) (h)) might evaluate (part of) (h) before (g), particularly if f is a function whereas h is a macro that produces Python-level statements. So if you need to be sure that g is called first, call it before f.
In this case, the assert statement has gotten pulled out of the function call ((with-cmd …) being a function call, since there is no macro named with-cmd) and evaluated before the symbol with-cmd itself.

Related

Suppressing Symbol Package Prefixes (Common Lisp)

When printing out object names which are interned in one package, but referenced from another package, the print name will include the full package name. For example, the following interaction interns the symbol X in PKG1, and prints its value from CL-USER:
* *package*
#<PACKAGE "COMMON-LISP-USER">
* (defpackage :pkg1 (:use :cl))
#<PACKAGE "PKG1">
* (in-package :pkg1)
#<PACKAGE "PKG1">
* (defvar x '(a b c))
X
* (in-package :cl-user)
#<PACKAGE "COMMON-LISP-USER">
* pkg1::x
(PKG1::A PKG1::B PKG1::C)
Sometimes for diagnostic/debugging reasons, I would like to printout external symbols without their package prefixes. In this case the printout would then look like (A B C). For complicated or nested objects where you know what the names mean, the package prefixes can make the printout hard to read, especially if there are multiple packages. Can the prefixes be temporarily suppressed for printout?
No, but you can elide the prefixes of one package by temporarily binding *package* to it for the printout.
Example:
(let ((*package* (find-package :pkg1)))
(print pkg1:*x*))
Since *package* is globally dynamic, this affects everything called inside (i. e. in the dynamic extent of its invocation) this let form but doesn't affect anything outside.

How to find variable in package using string and change it?

I have package with some variables:
(in-package #:pack)
(defparameter *a* "foo")
(defparameter *b* "bar")
Variables *a* and *b* are exported.
My goal is change this variables using strings ("*a*" and "*b*")
I can find these variables with intern function
(symbol-value (intern (string-upcase "*a*") :pack)) ;; return *a* symbol
(symbol-name (intern (string-upcase "*a*") :pack)) ;; return "foo"
But if I trying to change symbol with
(setf (symbol-name (intern (string-upcase "*a*") :pack)) "baz")
I've got an error:
The function (COMMON-LISP:SETF COMMON-LISP:SYMBOL-NAME) is undefined.
[Condition of type UNDEFINED-FUNCTION]
How can I change these variables?
As pointed in a comment #jkiiski, there is function in common lisp used to find symbols in a package:
find_symbol:
Function FIND-SYMBOL
Syntax:
find-symbol string &optional package => symbol, status
Then the other important thing is take a look at the answer here for understanding the difference between variables and symbols in common lisp.
And the function set, setq and setf from common lisp hypersec
set changes the contents of the value cell of symbol to the given
value.
setq(setq var1 form1 var2 form2 ...) is the simple variable assignment
statement of Lisp. First form1 is evaluated and the result is stored
in the variable var1, then form2 is evaluated and the result stored in
var2, and so forth. setq may be used for assignment of both lexical
and dynamic variables.
(setf place newvalue) expands into an update form that stores the
result of evaluating newvalue into the location referred to by place.
Some place forms involve uses of accessors that take optional
arguments. Whether those optional arguments are permitted by setf, or
what their use is, is up to the setf expander function and is not
under the control of setf. The documentation for any function that
accepts &optional, &rest, or ..... key arguments and that claims to be
usable with setf must specify how those arguments are treated.
So joining all this things we can have this code:
(defpackage :pack
(:use :cl) ;; You must import this line in order to use functions from cl package like setf
(:export :*a*
:*b*))
(in-package :pack)
(defparameter *a* "foo")
(defparameter *b* "bar")
Now lets explore the variables
CL-USER> pack:*a*
"foo"
CL-USER> pack:*b*
"bar"
Then we can find the symbol a (note that common lisp is case insensitive if you don't use || for naming symbols)
CL-USER> (find-symbol "*A*" :pack)
PACK:*A*
:EXTERNAL
So here, there is nothing unexpected exists symbol a and it is external to the package pack
then let's change the value wit set we can directly change the value but with setf we need a place, a pointer in the case of common lisp a symbol have different pointers in this case the important for us is symbol-value. so for changing that we can proceed as follow:
CL-USER> (set (find-symbol "*A*" :pack) "baz")
"baz"
CL-USER> pack:*a*
"baz"
CL-USER> (setf (symbol-value (find-symbol "*A*" :pack)) "buzz" )
"buzz"
CL-USER> pack:*a*
"buzz"
Hope this helps.

R5RS "provide" issues

I made a program in Racket and now I have to change my code to R5RS.
But I immediately get errors.
I had the following code in Racket :
#lang racket
(provide a-function)
(define (a-function)
; Do something
#t)
(define a-variable #t)
Then I changed it to R5RS :
#lang r5rs
(#%provide a-function)
(define (a-function)
; Do something
#t)
(define a-variable #t)
Now the problem is that when I run this simple code and try to call the procedure "a-function" it tells me a-function: undefined;
cannot reference an identifier before its definition
I noticed that this problem is only with procedures, the variable "a-variable" is known but no procedures are known...
EDIT : I tried to disguise a procedure as a variable to see if he knows that procedure, but then I get the same error.
#lang r5rs
(#%provide a-function)
(define a-function (lambda (x y) (+ x y)))
I searched a lot and I think the problem must be that I'm still merging my Racket code to R5RS so certain files are still in Racket, other files are in R5RS and that this is causing troubles for a reason I don't understand (it shouldn't be a problem...)
EDIT : I reconstructed the problem as easy as possible :
R5RS file "a.rkt" :
#lang r5rs
(#%provide makePosition)
(define (makePosition x y)
(cons x y))
Racket file :
#lang racket
(require "a.rkt")
(makePosition 20 10)
When running the Racket file this gives rise to the error "undefined identifier ...".
According to one of my teachers this is a Racket bug.
For the last program (makePosition), note that R5RS is case-insensitive, so makePosition is normalized to makeposition. Racket world, however, is case-sensitive, so makePosition doesn't exist; makeposition does.
For other programs, I really couldn't reproduce the problem. Did you change anything when you posted the question to StackOverflow?

Emacs - issues about hide-ifdef-mode

How to autoload hide-ifdef-mode?
Following implementations does not work for me:
;; auto hide-ifdef-mode from starting
(dolist (func '(hide-ifdef-mode hide-ifdef-mode-menu hide-ifdef-block
hide-ifdef-define hide-ifdef-undef
hide-ifdef-use-define-alist hide-ifdef-set-define-alist
hide-ifdef-toggle-read-only hide-ifdef-toggle-outside-read-only
hide-ifdef-shadowing))
(autoload func "hideif" "Hiding several ifdef blocks" t))
or just:
(autoload 'hide-ifdef-mode "hideif" "hideifdefmode" t)
A related issue - How to make that all actions with hide-ifdef-mode have been applied for all *.c and *.h files (buffers)?
Like, if I define some macro (C-c # d) or list of macro and apply it (C-c # h) this action would be performed for other files (and for new opened files too).
I think you're really looking for a way to enable hide-ifdef-mode automatically when you are in c-mode. In Emacs, this is done with hooks.
Try adding this to your configuration:
(add-hook 'c-mode-hook #'hide-ifdef-mode)
Note thate Emacs does have a feature called autoload, which does something different:
The autoload facility lets you register the existence of a function or macro, but put off loading the file that defines it. The first call to the function automatically loads the proper library, in order to install the real definition and other associated code, then runs the real definition as if it had been loaded all along. Autoloading can also be triggered by looking up the documentation of the function or macro (see Documentation Basics).

Changing hunchentoot's current package

I've set up a hunchentoot project with quickproject per Xach's instructions. In-package is run at the top of the file, and hunchentoot is started later in the file. The REPL is switched to my package also, but it is evident that hunchentoot is not running in my package. This causes some disparity between tests in the REPL and the browser. For example there is a function that looks up some stuff in an alist, but hunchentoot gets NILs from it because it is using symbols from another package.
I am aware from the answers to this related question that I can wrap every piece of code that interns symbols in something like
(let ((*package* (find-package :package-name)))
...)
which will set the *package* var to the correct package for the duration of the enclosed code.
Putting this in every function that needs it feels to me like a messy hack.
Intuition says that I should be able to start hunchentoot like this:
(let ((*package* (find-package :package-name)))
(hunchentoot:start (make-instance 'hunchentoot:easy-acceptor :port 4242)))
So that it makes its whole run with *package* set to the value that I prefer, thereby ensuring that any interning done by a call from the webserver is done in my package. It doesn't work. Hunchentoot ends up interning things under cl-user, possibly due to using a macro like WITH-STANDARD-IO-SYNTAX as in the link above.
Even if I can persuade hunchentoot to do what I want, is there a reason why my 'messy hack' is still the better thing to do?
This is not a Hunchentoot specific question, but relates to Common Lisp packages in general.
What you are seeing is that in your code, the *PACKAGE* special variable is not bound to your own package. IN-PACKAGE changes *PACKAGE* only at compile and read time. When a function in your package is called at run time, *PACKAGE* is not re-bound and needs to be bound explicitly.
When you are using INTERN or FIND-SYMBOL, it is often best to specify the package as argument. Alternatively, you can bind *PACKAGE* yourself.
Try LOADing this file to see:
(defpackage :foo
(:use :cl))
(in-package :foo)
(defun test ()
(print *package*))
(in-package :cl-user)
(foo::test)
Common Lisp code does not 'run' in a package.
There are a few operations which use a default package. Like reading a symbol from a text stream:
CL-USER 1 > *package*
#<The COMMON-LISP-USER package, 56/64 internal, 0/4 external>
CL-USER 2 > (read-from-string "FOO")
FOO
3
CL-USER 3 > (describe (read-from-string "FOO"))
FOO is a SYMBOL
NAME "FOO"
VALUE #<unbound value>
FUNCTION #<unbound function>
PLIST NIL
PACKAGE #<The COMMON-LISP-USER package, 57/64 internal, 0/4 external>
or like finding a symbol:
(find-symbol "FOO")
These operations depend on the value of the variable cl:*package*.
To make sure that these operations (reading symbols, finding symbols, interning symbols, ...) are doing what you expect, you may want to:
set or bind the *package* variable to the package you want to
explicitly pass the package to operations. You can call (find-symbol "FOO") and have *package* set to some package. But you can also call (find-symbol "FOO" my-package) by passing the respective package as an argument.
Summary: Common Lisp code does not 'run in a package', but it uses the variable *package* as a default package for package-related operations. You need to set or bind this variable when you use this mechanism.
When Hunchentoot runs in multi-threaded, its acceptors and handlers are processed in child threads made with bordeaux-threads on non-Lispwork CL implementation. The reason of the situation you asked is that the current packages of child threads become COMMON-LISP-USER.
To get the result you want, you can make child threads' current packages same as calling thread's with implementing START-THREAD generic function corresponding to ONE-THREAD-PER-CONNECTION-TASKMASTER taskmaster.
Note that you use latest Hunchentoot which has START-THREAD generic function, I use of version 1.2.19.
(in-package :hunchentoot)
(defmethod start-thread ((taskmaster one-thread-per-connection-taskmaster) thunk &key name)
(let* (;; calling thread's current package
(package-name (package-name *package*))
;; initial special bindings passed to bordeaux threads
(initial-bindings `((*package* . (find-package ,package-name)))))
;; making child thread passing initial special bindings
(bt:make-thread thunk :name name :initial-bindings initial-bindings)))

Resources