Simplifying complex setf expressions - reference

For rapid prototyping purposes in common-lisp it would be convenient to be able to easily function-modify an object in an arbitrary data structure. This would seem to involve calling an arbitrary function on a place in the data structure, replacing the object at that place with the result of the function call. Common-lisp has a number of specialized modification macros (eg, incf, push, getf, etc) for particular types of objects, and setf for generalized place modification (eg, setf-second, setf-aref, setf-gethash, etc). But rather than inventing new specialized macros for other object types, or having to mentally consider the characteristics of each macro (slowing down development), it might be nice to have a generalized setf-like modification capability that was simpler to use than setf. For example, instead of (setf (second (getf plist indicator)) (1+ (second (getf plist indicator)))) or (incf (second (getf plist indicator))), one might write (callf (second (getf plist indicator)) #'1+), using any of the normal one argument functions (or lambda-expression) provided by common-lisp or the user. Here is an attempt at code:
(defun call (object function) (funcall function object))
(define-modify-macro callf (&rest args) call)
Will something like this work for all general cases, and can it actually simplify code in practice?

callf
I think what you are looking for is _f from OnLisp 12.4:
(defmacro _f (op place &rest args)
"Modify place using `op`, e.g., (incf a) == (_f a 1+)"
(multiple-value-bind (vars forms var set access)
(get-setf-expansion place)
`(let* (,#(mapcar #'list vars forms)
(,(car var) (,op ,access ,#args)))
,set)))
This uses get-setf-expansion - the workhorse of generalized reference handling.
Note that _f only works with single-value places.
IOW, (_f (values a b c) 1+) will not increment all 3 variables.
It is not all that hard to fix that though...
can it actually simplify code in practice?
This really depends on your coding style and the specific problem you are solving.

Related

How do you find out the fields and properties of a struct?

The question
Suppose you have a struct, like this:
(struct soldier (name rank serial-number) #:transparent)
(define s (soldier 'Smith 'private 100134))
How can you find out what fields soldier or s contains? Or what generic interfaces it supports, or what structure type properties it has?
Research efforts so far
(Skip this section if you already know the answer.)
I've been reading through the documentation on structs for the last few days, and I haven't been able to figure out how you're supposed to put the pieces together. I'm probably just missing some elementary tidbit of information that goes without saying to people who know Racket.
The chapter on Reflection and Security has a section "Structure Inspectors", which says:
An inspector provides access to structure fields and structure type information without the normal field accessors and mutators.
but I haven't understood how to get an inspector to provide that.
struct-info and struct-type-info provide some information, but not field names, interfaces, properties, etc.:
> (struct-type-info struct:soldier)
'soldier
3
0
#<procedure:soldier-ref>
#<procedure:soldier-set!>
'(0 1 2)
#f
#f
struct->vector and struct->list provide access to an instance's contents and the above data, but that's all:
> (struct->vector s)
'#(struct:soldier Smith private 100134)
If you could show me an example of how to inspect a struct type to see what's in it, that would probably clarify whatever soon-to-be-obvious-in-hindsight thing I'm not seeing here.
The field names are not available at run time. However you can at expansion time use syntax-local-value on the struct name to get some information.
A quick example:
#lang racket
(require (for-syntax racket/struct-info))
(struct foo (a b))
(begin-for-syntax
(display (extract-struct-info (syntax-local-value #'foo))))
Update
In this example:
#lang racket
(require (for-syntax racket/struct-info))
(struct foo (a [b #:mutable] c))
(begin-for-syntax
(display (extract-struct-info (syntax-local-value #'foo))))
The list of identifiers for mutators is: (#f #<syntax:4:8 set-foo-b!> #f).
That is only the second field is mutable.
The information is available at expansion time, so you can transfer the information to runtime by calling a macro that expands into a definition like (define info '(#f set-foo-b! #f) or similar.

Prism over maybe-existent list element

today on "adventures in functional programming with lenses" our hero attempts to define a prism over a list element that may or may not exist.
It's a bit tricky to explain, so to avoid the X, Y problem I'll give the actual use-case in all its glory.
I'm writing a Text editor in Haskell called Rasa, the whole idea is that it's extremely extensible, and that means most functionality is written as extensions. Since it's a core principle, extensions ALSO depend on other extensions, so I needed a way to store their state centrally such that all extensions depending on an extension could access its current 'extension state'. Of course the types of these states is not known to the core of the editor, so at the moment I'm storing a list of Dynamic values. When the extension stores the state it converts to a Dynamic, then it can be extracted later via a prism like so:
data Store = Store
{ _event :: [Event]
, _editor :: E.Editor
, _extState :: [Dynamic]
}
ext :: Typeable a => Traversal' Store a
ext = extState.traverse._Dynamic
So now ext is a polymorphic Traversal that essentially operates over only the Dynamics that 'match' the type in question (if you set to it it'll replace values of the same type, if you 'get' from it, it acts as a traversal over the Dynamics that match the type of the outbound value). If that seems like magic, it basically is...
BTW, I'd love to have exactly 1 copy of a given Extension's state object in the list at any time.
So getting and setting is actually working fine IFF there's already a value of the proper type in the list, my question is how can I make a version of this Traversal such that if a value of the proper type is in the list that it will replace it (and getting works as expected), but that will ADD a value to the list if the traversal is SET to and there's NO matching element in the list. I understand that Traversal's aren't supposed to change the number of elements that they're traversing, so perhaps this needs to be a prism or lens over the list itself?
I understand this is really confusing, so please ask clarifying questions :)
As for things I've taken a look at already, I was looking at prefixed and _Cons as possible ways to do this, but I'm just not quite sure how to wire it up. Maybe I'm barking up the wrong tree entirely.
I could perhaps add a default value to the end of the traversal somehow, but I don't want to require Monoid or Default so I can't conjure up elements from nowhere (and I only want to do it when SETTING).
I'm also open to discussions about whether this is actually the proper way to store this state at all, but it's the most elegant of solutions I've found so far (though I know typecasting at run time is sub-optimal). I've looked into the Vault type, but passing keys around didn't really work well when I tried it (and I imagine it has similar type-casting performance issues).
Cheers! Thanks for reading.
I think the list of extensions is not proper solution for you. I would be added something like _extState :: Map TypeRep Ext where data Ext = forall a. Ext a. Then I would be added the lens:
ext :: forall a . Typeable a => Lens' Store (Maybe a)
ext = _extState . at (typeRep (Proxy :: Proxy a)) . mapping coerce
where
coerce = iso (\(Ext x) -> unsafeCoerce x) Ext
This lens does like at. So you can simply get/set your extensions.
But there is one limitation, all extensions must be of different types.

common lisp, how to mask keyboard input

This is a console program in Common Lisp for a Hangman type game. The first player enters a string to be guessed by the second player. My input function is below --- unfortunately the characters typed by the first player remain visible.
With JavaScript it's simple, just use a password text entry box. With VB it's simple using the same sort of facility. Is there any way to do this using a native Common Lisp function?
Thanks, CC.
(defun get-answer ()
(format t "Enter the word or phrase to be guessed: ~%")
(coerce (string-upcase (read-line)) 'list))
(defun start-hangman ()
(setf tries 6)
(greeting)
(setf answer (get-answer))
(setf obscure (get-obscure answer))
(game-loop answer obscure))
Each implementation supports this differently.
You might want to use an auxiliary library like iolib.termios or cl-charms (interface to libcurses) if you want a portability layer above different implementations.
SBCL
I found a discussion thread about it for SBCL, and here is the code for that implementation, from Richard M. Kreuter:
(require :sb-posix)
(defun echo-off ()
(let ((tm (sb-posix:tcgetattr sb-sys:*tty*)))
(setf (sb-posix:termios-lflag tm)
(logandc2 (sb-posix:termios-lflag tm) sb-posix:echo))
(sb-posix:tcsetattr sb-sys:*tty* sb-posix:tcsanow tm)))
(defun echo-on ()
(let ((tm (sb-posix:tcgetattr sb-sys:*tty*)))
(setf (sb-posix:termios-lflag tm)
(logior (sb-posix:termios-lflag tm) sb-posix:echo))
(sb-posix:tcsetattr sb-sys:*tty* sb-posix:tcsanow tm)))
And so, here is finally an opportunity to talk about PROG2:
(defun read-silently ()
(prog2
(echo-off)
(read-line sb-sys:*tty*)
(echo-on)))
However, you might want to ensure that the echo is always reset when unwinding the stack, and clear the input before inputting things:
(defun read-silently ()
(echo-off)
(unwind-protect
(progn
(clear-input sb-sys:*tty*)
(read-line sb-sys:*tty*))
(echo-on)))
CL-CHARMS
Here is an alternative using libcurse. The following is sufficient to make a simple test work.
(defun read-silently ()
(let (input)
(charms:with-curses ()
(charms:disable-echoing)
(charms:enable-raw-input)
(clear-input *terminal-io*)
(setf input (read-line *terminal-io*))
(charms:disable-raw-input)
(charms:enable-echoing))
input))
Besides, using libcurse might help you implement a nice-looking hangman console game.
Are you printing to a console? That's an inherent limitation of standard consoles.
You'll need to print a ton of newlines to push the text off the screen.
Many consoles aren't capable of fancy things like selectively erasing parts of the screen.

How do you securely parse untrusted input in Common Lisp?

How do you securely parse untrusted input in Common Lisp? Given that there is no parse-float etc, and that read-from-string will execute reader macros like #. (read time eval).
e.g.
(read-from-string "#.(+ 1 2)") => 3
I can't find the other question or comment that described some of the safe input handling procedures for Common Lisp (if someone else finds them, please post a comment!), but there are at least two important things that you might do:
Use with-standard-io-syntax to make sure that you're reading with the standard readtable, etc. Note that this will bind *read-eval* to true, so be sure to also:
Bind *read-eval* to false (within with-standard-io-syntax). This disables the sharpsign-dot (#.) macro mentioned in the question.
(let ((*readtable* (copy-readtable)))
(set-macro-character #\n (constantly 'injected))
(read-from-string "(#.(+ 2 5) n)"))
;;=> (7 INJECTED)
(let ((*readtable* (copy-readtable)))
(set-macro-character #\n (constantly 'injected))
(with-standard-io-syntax
(let ((*read-eval* nil))
(read-from-string "(#.(+ 2 5) n)"))))
;; Evaluation aborted on #<SB-INT:SIMPLE-READER-ERROR
;; "can't read #. while *READ-EVAL* is NIL" {1004DA3603}>.
(let ((*readtable* (copy-readtable)))
(set-macro-character #\n (constantly 'injected))
(list (read-from-string "(n)")
(with-standard-io-syntax
(let ((*read-eval* nil))
(read-from-string "(n)")))))
;; ((INJECTED) (N))
Generally, just that the standard code reader is so readily available and can read many kinds of input does not mean that you should use it to read anything but code.
There are many libraries for parsing a lot of things, e. g. parse-number for the Lisp number formats, fare-csv for CSV files (among many other CSV libraries), json-streams for JSON (again, many others). For most formats, you can just do a system-apropos lookup with Quicklisp.

Scope of functions and variables within a function and/or let statement for lisp

I'm having some trouble understanding the scope of variables and functions when defined inside a function call. I tried searching for this scope, but could not find a suitable answer (or maybe was searching for the wrong thing), so I decided to write a few functions to test things myself:
(defun test-scope1 ()
(setf myvar 1)
(defun set-var1 ()
(setf myvar 2))
(set-var1))
With this function I just wanted to see if anything gets set global. I would expect myvar and set-var to be defined globally because I have no scope here. As expected, before calling (test-scope1) the commands myvar and (set-var) give me errors. After calling (test-scope1), I can run myvar and (set-var) in the interpreter to yield 2.
Thinking to myself it would be nice to encapsulate my variables, I decided to add a let inside my function, therefore getting my next test:
(defun test-scope2 ()
(let ((myvar 10))
(defun set-var2 ()
(setf myvar 20))
(set-var2)))
I would expect myvar to be stuck in the scope of the let block, but wouldn't be able to guess for set-var2. It could be stuck in the let block or it could be defined globally. After running (test-scope2) I try to access myvar and get 2. That means this new function has its own myvar since it's still 2 from the previous function. I try running (set-var2)and get 20.
I'm not completely surprised that the function is defined globally after being run in the let block, but now I'm very confused what myvar variable its accessing. Since it didn't change my global copy of myvar, it would seem there's some variable floating around it still refers to.
Now I want to see if I can manipulate that floating variable, so I create this third function.
(defun test-scope3 ()
(let ((myvar (if (ignore-errors myvar)
myvar
100)))
(defun set-var3 ()
(setf myvar (+ myvar 100)))
(set-var3)))
Instead of just setting the variable to a fixed value, I want to increment it based on the previous value. I check two things here. The first is when test-scope3 is called. I wanted to see if I could pull up a "previous value" of myvar, since if it's floating around somewhere maybe I can access it again. It probably wouldn't be good practice, but that's not the point here. Ignore-errors is there in case there wasn't really a previous value floating around, in which case I choose a default of 100.
The second thing I test is to have set-var3 add 100 to the previous the value of myvar. I want to see if this will adjust that floating variable, or if somehow is something static. I have no idea what my function "should" return.
After running (test-scope3) I'm completely surprised to see 102. So apparently my test-scope3 found the value of myvar from running test-scope1. But, after checking the value of myvar in the interpreter, it is still 2. Next I run (set-var3) and get a return value of 202. Okay, so it added 100 again to my previous value. Calling it again returns 302 and so on. But, calling (test-scope3) again resets this value back down to 102.
I wrote one more function as a double nested let command. I just ran this in two ways: with no myvar definition for the let arguments. This function returns 10002. Then, I tried setting the local myvar to 50 and had 1050 return.
(defun test-scope4 ()
(let () ; or ((myvar 50))
(let ((myvar (if (ignore-errors myvar)
myvar
2000)))
(defun set-var4 ()
(setf myvar (+ myvar 1000)))
(set-var4))))
So, with all this together, here are some of my specific questions:
When I do a defun inside another defun, even in a let block, why does that function become accessible globally?
When I call set-var#, what variables (or within what scope) is this accessing? Or maybe more appropriately, when I define a function inside another statement, what am I actually binding?
When I use the variable myvarin a function, where does this pull from? From my 4th example conjecture is that it looks for the symbol myvar in the current scope, then checks up one level higher until it finds a value for it.
Sorry if everything was very wordy and my questions ill-formed. I tried to investigate things to the best of my ability. Really this all leads to my real question, which after writing everything up I realize might be beyond the scope (no pun intended) of this question as I've set it up so far.
The issue of hiding my inner functions as given above could be handled with a lambda expression; however, what I'd really love to do is to have a recursive function inside of a bigger block that uses the block to store values without feeding them directly into the function. To my knowledge, this is not possible with a lambda expression. For example, consider the following function which does this.
(defun outer-function (start)
(let ((x start))
(defun increment-to-ten ()
(setf x (+ x 1))
(if (< x 10)
(increment-to-ten)))
(increment-to-ten)
(print x)))
Which could be instead implemented recursively with arguments as
(defun increment-to-ten-recursive (x)
(if (< x 10)
(increment-to-ten-recursive (+ x 1))
10))
If there's a solution for this, that would be great, or if my thinking is completely wrong and there's a better way to do this that would be great to. It just seems convenient to have a block store data for you and then just call a recursive function with no arguments to work on that data.
Why it is difficult to discuss the effects you see:
You are doing things which are undefined in Common Lisp: setting undeclared variables in test-scope1: myvar. It's from then on unclear how the following code behaves.
Undeclared Variables
It is undefined what effect it has when an undeclared variable foo is set. Implementations allow it. Some will warn. SBCL:
* (setf foo 10)
; in: SETF FOO
; (SETF FOO 10)
; ==>
; (SETQ FOO 10)
;
; caught WARNING:
; undefined variable: FOO
;
; compilation unit finished
; Undefined variable:
; FOO
; caught 1 WARNING condition
Global variables are defined with DEFPARAMETER and DEFVAR. Local variables are defined by LET, LET* and by functions parameters. Since DEFPARAMETER and DEFVAR define global special (using dynamic binding) variables, it is common to write them as *some-variable* - note the * around it, which are part of the symbol name and not special syntax. It's a convention for special variables.
Nested DEFUNs
Nested DEFUNs are not used in Common Lisp. DEFUN is a top-level form, which sets a global function. To define local functions use FLET and LABELS. You can nest DEFUN forms, but it is bad style and you won't find it used in actual Lisp code. Don't nest DEFUN forms. Note: this is different from Scheme, where one can nest DEFINE forms. Since nested DEFUNs are not used, it makes little sense to discuss the effects. Convert the examples to use local functions defined by FLET or LABELS.
When I do a defun inside another defun, even in a let block, why does that function become accessible globally?
Because DEFUN defines global functions. That's its purpose.
You need to rewrite your examples to make it possible to discuss the effects:
declare all variables
don't use nested DEFUNs
We could try to understand the code you have in your current examples, but much depends on the implementation and the sequence of actions. We are either not in the realm of portable Common Lisp or doing stuff (nested DEFUNs), which has no practical use in Common Lisp.
As Rainer explained, the answer to your first question is that defun defines global functions. Use labels to define local functions.
Rainer is also right about much being dependent on the configuration of your lisp. Many Lisps know about two types of scope, lexical and dynamic. Lexical scope is the one you can see when you look at a page of code, and what you're used to from most other programming languages. Dynamic scope is what you get when you a lisp looks for the value of a variable in the environment where the function was called instead of the one where it was defined.
Finally, your code makes usse of closures. When you put a lambda (defun) inside a let, you create a closure, e.g. your variables "hang or float around" for the function to use in the future even when the function that contains them returns to it's caller.
So here's what might be going on (as Rainer said, it's hard to know since you're doing things that usually aren't done, such as nesting defuns):
So... probably, test-scope1 uses a global myvar and it's set-var references the global myvar since we are dealing with lexical scope. test-scope2 builds a closure, which creates a myvar with lexical scope only accessible to set-var2. Since this myvar has lexical scope, the call to set-var in test-scope2 will not use this myvar but still the global one.
I'm not sure why calling test-scope3 gets you 102, since test-scope3 just calls set-var, which should set the global myvar to 2, not 102. The only code that could explain 102 is in set-var3, and this isn't being called when you call test-scope3. Here's what might be going on if you got 2 instead of 102 when calling test-scope3:
(defun test-scope3 ()
(let ((myvar (if (ignore-errors myvar)
myvar
100)))
(defun set-var3 ()
(setf myvar (+ myvar 100)))
(set-var)))
With the let, you create a local binding for myvar with lexical scope, but you refer to the global myvar in it's binding form - the (if (ignore-errors myvar) myvar). Later on you call set-var, which should again reference the global myvar since test'scope3's let uses lexical scope for the binding of myvar. Then, wen you call set-var3 for the first time, it takes the myvar bound by the above let, which currently has a value of 2, and adds 100 to it. When you call it the second time, you again add 100 to the lexically bound myvar which still hangs around in the closure you built in test-scope3, and so on. But when you call test-scope3 again, you create a new closure (but replace the old one because you use defun to give the same name to it...) which again sets the initial value of the closed-over myvar to the value of the global myvar, which is 2.
I suggest you read Paul Graham's excellent ANSI Common Lisp and On Lisp, which explain special variables (dynamic scope), lexical scope and closures in depth.
Here's how you might have several closures share variables:
(let ((myvar 0))
(defun reset ()
(setf myvar 0)
(defun inc ()
(setf myvar (+ myvar 1))))
This builds two closures and makes them share myvar, and since myvar has lexical scope you can't access this copy of myvar from anywhere else. So you've basically given exclusive control of myvar to reset and inc.
This could be one way to build your recursive function that doesn't need a value passed into it with each iteration.

Resources